98
stored in bookmark_hash, this structure is never removed from the
99
hash and is used to mark a single offset for a session local variable
100
even if plugins have been uninstalled and reinstalled, repeatedly.
101
This structure is allocated from plugin_mem_root.
103
The key format is as follows:
104
1 byte - variable type code
105
name_len bytes - variable name
122
112
uint32_t version;
126
typedef boost::unordered_map<string, Bookmark> bookmark_unordered_map;
127
static bookmark_unordered_map bookmark_hash;
118
sys_var class for access to all plugin variables visible to the user
120
class sys_var_pluginvar: public sys_var
123
plugin::Module *plugin;
124
drizzle_sys_var *plugin_var;
126
sys_var_pluginvar(const std::string name_arg,
127
drizzle_sys_var *plugin_var_arg)
128
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
129
sys_var_pluginvar *cast_pluginvar() { return this; }
130
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
131
bool check_type(enum_var_type type)
132
{ return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
133
bool check_update_type(Item_result type);
134
SHOW_TYPE show_type();
135
unsigned char* real_value_ptr(Session *session, enum_var_type type);
136
TYPELIB* plugin_var_typelib(void);
137
unsigned char* value_ptr(Session *session, enum_var_type type,
138
const LEX_STRING *base);
139
bool check(Session *session, set_var *var);
140
bool check_default(enum_var_type)
141
{ return is_readonly(); }
142
void set_default(Session *session, enum_var_type);
143
bool update(Session *session, set_var *var);
132
static void plugin_prune_list(vector<string> &plugin_list,
133
const vector<string> &plugins_to_remove);
134
static bool plugin_load_list(module::Registry ®istry,
135
memory::Root *tmp_root,
136
const set<string> &plugin_list,
137
po::options_description &long_options,
138
bool builtin= false);
139
static int test_plugin_options(memory::Root *, module::Module *,
140
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);
148
static bool plugin_load_list(plugin::Registry ®istry,
149
memory::Root *tmp_root, int *argc, char **argv,
151
static int test_plugin_options(memory::Root *, plugin::Module *,
153
static void unlock_variables(Session *session, struct system_variables *vars);
154
static void cleanup_variables(Session *session, struct system_variables *vars);
155
static void plugin_vars_free_values(sys_var *vars);
157
/* declared in set_var.cc */
158
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
159
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
160
const std::string &name, int64_t val);
162
static bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
163
const char *name, int64_t val)
165
const std::string name_str(name);
166
return throw_bounds_warning(session, fixed, unsignd, name_str, val);
169
/****************************************************************************
170
Value type thunks, allows the C world to play in the C++ world
171
****************************************************************************/
173
static int item_value_type(drizzle_value *value)
175
switch (((st_item_value_holder*)value)->item->result_type()) {
177
return DRIZZLE_VALUE_TYPE_INT;
179
return DRIZZLE_VALUE_TYPE_REAL;
181
return DRIZZLE_VALUE_TYPE_STRING;
185
static const char *item_val_str(drizzle_value *value,
186
char *buffer, int *length)
188
String str(buffer, *length, system_charset_info), *res;
189
if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
191
*length= res->length();
192
if (res->c_ptr_quick() == buffer)
196
Lets be nice and create a temporary string since the
199
return current_session->strmake(res->c_ptr_quick(), res->length());
203
static int item_val_int(drizzle_value *value, int64_t *buf)
205
Item *item= ((st_item_value_holder*)value)->item;
206
*buf= item->val_int();
213
static int item_val_real(drizzle_value *value, double *buf)
215
Item *item= ((st_item_value_holder*)value)->item;
216
*buf= item->val_real();
145
223
/****************************************************************************
154
232
Requires that a write-lock is held on LOCK_system_variables_hash
156
static bool plugin_add(module::Registry ®istry, memory::Root *tmp_root,
157
module::Library *library,
158
po::options_description &long_options)
234
static bool plugin_add(plugin::Registry ®istry, memory::Root *tmp_root,
235
plugin::Library *library,
236
int *argc, char **argv)
160
238
if (! initialized)
163
241
if (registry.find(library->getName()))
165
errmsg_printf(error::WARN, ER(ER_PLUGIN_EXISTS),
243
errmsg_printf(ERRMSG_LVL_WARN, ER(ER_PLUGIN_EXISTS),
166
244
library->getName().c_str());
170
module::Module *tmp= NULL;
248
plugin::Module *tmp= NULL;
171
249
/* Find plugin by name */
172
const module::Manifest *manifest= library->getManifest();
174
if (registry.find(manifest->name))
176
errmsg_printf(error::ERROR,
177
_("Plugin '%s' contains the name '%s' in its manifest, which "
178
"has already been registered.\n"),
179
library->getName().c_str(),
184
tmp= new (std::nothrow) module::Module(manifest, library);
250
const plugin::Manifest *manifest= library->getManifest();
252
tmp= new (std::nothrow) plugin::Module(manifest, library);
188
if (!test_plugin_options(tmp_root, tmp, long_options))
256
if (!test_plugin_options(tmp_root, tmp, argc, argv))
190
258
registry.add(tmp);
193
errmsg_printf(error::ERROR, ER(ER_CANT_FIND_DL_ENTRY),
261
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY),
194
262
library->getName().c_str());
199
static void reap_plugins(module::Registry ®istry)
201
std::map<std::string, module::Module *>::const_iterator modules=
267
static void delete_module(plugin::Registry ®istry, plugin::Module *module)
269
plugin::Manifest manifest= module->getManifest();
271
if (module->isInited)
273
if (manifest.status_vars)
275
remove_status_vars(manifest.status_vars);
279
manifest.deinit(registry);
282
/* Free allocated strings before deleting the plugin. */
283
plugin_vars_free_values(module->system_vars);
284
module->isInited= false;
285
pthread_rwlock_wrlock(&LOCK_system_variables_hash);
286
mysql_del_sys_var_chain(module->system_vars);
287
pthread_rwlock_unlock(&LOCK_system_variables_hash);
292
static void reap_plugins(plugin::Registry ®istry)
294
plugin::Module *module;
296
std::map<std::string, plugin::Module *>::const_iterator modules=
202
297
registry.getModulesMap().begin();
204
299
while (modules != registry.getModulesMap().end())
206
module::Module *module= (*modules).second;
301
module= (*modules).second;
302
delete_module(registry, module);
213
static bool plugin_initialize(module::Registry ®istry,
214
module::Module *module)
305
drizzle_del_plugin_sysvar();
309
static void plugin_initialize_vars(plugin::Module *module)
311
if (module->getManifest().status_vars)
313
add_status_vars(module->getManifest().status_vars); // add_status_vars makes a copy
317
set the plugin attribute of plugin's sys vars so they are pointing
320
if (module->system_vars)
322
sys_var_pluginvar *var= module->system_vars->cast_pluginvar();
326
if (! var->getNext())
328
var= var->getNext()->cast_pluginvar();
334
static bool plugin_initialize(plugin::Registry ®istry,
335
plugin::Module *module)
216
337
assert(module->isInited == false);
218
module::Context loading_context(registry, module);
339
registry.setCurrentModule(module);
219
340
if (module->getManifest().init)
221
if (module->getManifest().init(loading_context))
342
if (module->getManifest().init(registry))
223
errmsg_printf(error::ERROR,
344
errmsg_printf(ERRMSG_LVL_ERROR,
224
345
_("Plugin '%s' init function returned error.\n"),
225
346
module->getName().c_str());
350
registry.clearCurrentModule();
229
351
module->isInited= true;
292
374
Finally we initialize everything, aka the dynamic that have yet to initialize.
294
bool plugin_init(module::Registry ®istry,
295
po::options_description &long_options)
376
bool plugin_init(plugin::Registry ®istry,
377
int *argc, char **argv,
297
memory::Root tmp_root(4096);
380
plugin::Manifest **builtins;
381
plugin::Manifest *manifest;
382
plugin::Module *module;
383
memory::Root tmp_root;
388
init_alloc_root(&plugin_mem_root, 4096);
389
init_alloc_root(&tmp_root, 4096);
391
if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
392
get_bookmark_hash_key, NULL, HASH_UNIQUE))
394
free_root(&tmp_root, MYF(0));
304
PluginOptions builtin_load_list;
305
tokenize(builtin_load_plugins, builtin_load_list, ",", true);
307
PluginOptions builtin_list;
308
tokenize(builtin_plugins, builtin_list, ",", true);
402
First we register builtin plugins
404
for (builtins= drizzled_builtins; *builtins; builtins++)
407
if (manifest->name != NULL)
409
module= new (std::nothrow) plugin::Module(manifest);
413
free_root(&tmp_root, MYF(memory::MARK_BLOCKS_FREE));
414
if (test_plugin_options(&tmp_root, module, argc, argv))
417
registry.add(module);
419
plugin_initialize_vars(module);
423
if (plugin_initialize(registry, module))
425
free_root(&tmp_root, MYF(0));
310
433
bool load_failed= false;
312
if (opt_plugin_add.size() > 0)
314
for (PluginOptions::iterator iter= opt_plugin_add.begin();
315
iter != opt_plugin_add.end();
318
if (find(builtin_list.begin(),
319
builtin_list.end(), *iter) != builtin_list.end())
321
builtin_load_list.push_back(*iter);
325
opt_plugin_load.push_back(*iter);
330
if (opt_plugin_remove.size() > 0)
332
plugin_prune_list(opt_plugin_load, opt_plugin_remove);
333
plugin_prune_list(builtin_load_list, opt_plugin_remove);
338
First we register builtin plugins
340
const set<string> builtin_list_set(builtin_load_list.begin(),
341
builtin_load_list.end());
342
load_failed= plugin_load_list(registry, &tmp_root,
343
builtin_list_set, long_options, true);
346
tmp_root.free_root(MYF(0));
350
/* Uniquify the list */
351
const set<string> plugin_list_set(opt_plugin_load.begin(),
352
opt_plugin_load.end());
354
434
/* Register all dynamic plugins */
355
load_failed= plugin_load_list(registry, &tmp_root,
356
plugin_list_set, long_options);
437
load_failed= plugin_load_list(registry, &tmp_root, argc, argv,
442
string tmp_plugin_list(opt_plugin_load_default);
445
tmp_plugin_list.push_back(',');
446
tmp_plugin_list.append(opt_plugin_add);
448
load_failed= plugin_load_list(registry, &tmp_root, argc, argv,
359
tmp_root.free_root(MYF(0));
453
free_root(&tmp_root, MYF(0));
363
tmp_root.free_root(MYF(0));
368
bool plugin_finalize(module::Registry ®istry)
459
free_root(&tmp_root, MYF(0));
371
464
Now we initialize all remaining plugins
373
module::Registry::ModuleList module_list= registry.getList();
374
module::Registry::ModuleList::iterator modules= module_list.begin();
466
std::map<std::string, plugin::Module *>::const_iterator modules=
467
registry.getModulesMap().begin();
376
while (modules != module_list.end())
469
while (modules != registry.getModulesMap().end())
378
module::Module *module= *modules;
471
module= (*modules).second;
380
473
if (module->isInited == false)
475
plugin_initialize_vars(module);
382
477
if (plugin_initialize(registry, module))
384
registry.remove(module);
478
delete_module(registry, module);
392
BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
394
value.second->prime();
483
free_root(&tmp_root, MYF(0));
401
Window of opportunity for plugins to issue any queries with the database up and running but with no user's connected.
403
void plugin_startup_window(module::Registry ®istry, drizzled::Session &session)
405
BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
407
value.second->startup(session);
412
public unary_function<string, bool>
414
const string to_match;
416
PrunePlugin& operator=(const PrunePlugin&);
418
explicit PrunePlugin(const string &match_in) :
422
result_type operator()(const string &match_against)
424
return match_against == to_match;
428
static void plugin_prune_list(vector<string> &plugin_list,
429
const vector<string> &plugins_to_remove)
431
for (vector<string>::const_iterator iter= plugins_to_remove.begin();
432
iter != plugins_to_remove.end();
435
plugin_list.erase(remove_if(plugin_list.begin(),
443
491
called only by plugin_init()
445
static bool plugin_load_list(module::Registry ®istry,
446
memory::Root *tmp_root,
447
const set<string> &plugin_list,
448
po::options_description &long_options,
493
static bool plugin_load_list(plugin::Registry ®istry,
494
memory::Root *tmp_root, int *argc, char **argv,
451
module::Library *library= NULL;
497
plugin::Library *library= NULL;
453
for (set<string>::const_iterator iter= plugin_list.begin();
454
iter != plugin_list.end();
499
const string DELIMITER(",");
500
string::size_type last_pos= plugin_list.find_first_not_of(DELIMITER);
501
string::size_type pos= plugin_list.find_first_of(DELIMITER, last_pos);
502
while (string::npos != pos || string::npos != last_pos)
457
const string plugin_name(*iter);
504
const string plugin_name(plugin_list.substr(last_pos, pos - last_pos));
459
library= registry.addLibrary(plugin_name, builtin);
506
library= registry.addLibrary(plugin_name);
460
507
if (library == NULL)
462
errmsg_printf(error::ERROR,
463
_("Couldn't load plugin library named '%s'.\n"),
509
errmsg_printf(ERRMSG_LVL_ERROR,
510
_("Couldn't load plugin library named '%s'."),
464
511
plugin_name.c_str());
468
tmp_root->free_root(MYF(memory::MARK_BLOCKS_FREE));
469
if (plugin_add(registry, tmp_root, library, long_options))
515
free_root(tmp_root, MYF(memory::MARK_BLOCKS_FREE));
516
if (plugin_add(registry, tmp_root, library, argc, argv))
471
518
registry.removeLibrary(plugin_name);
472
errmsg_printf(error::ERROR,
473
_("Couldn't load plugin named '%s'.\n"),
519
errmsg_printf(ERRMSG_LVL_ERROR,
520
_("Couldn't load plugin named '%s'."),
474
521
plugin_name.c_str());
525
last_pos= plugin_list.find_first_not_of(DELIMITER, pos);
526
pos= plugin_list.find_first_of(DELIMITER, last_pos);
483
void module_shutdown(module::Registry ®istry)
532
void plugin_shutdown(plugin::Registry ®istry)
491
540
unlock_variables(NULL, &global_system_variables);
492
541
unlock_variables(NULL, &max_system_variables);
494
cleanup_variables(&global_system_variables);
495
cleanup_variables(&max_system_variables);
543
cleanup_variables(NULL, &global_system_variables);
544
cleanup_variables(NULL, &max_system_variables);
500
549
/* Dispose of the memory */
501
plugin_mem_root.free_root(MYF(0));
551
hash_free(&bookmark_hash);
552
free_root(&plugin_mem_root, MYF(0));
503
554
global_variables_dynamic_size= 0;
557
/****************************************************************************
558
Internal type declarations for variables support
559
****************************************************************************/
561
#undef DRIZZLE_SYSVAR_NAME
562
#define DRIZZLE_SYSVAR_NAME(name) name
563
#define PLUGIN_VAR_TYPEMASK 0x007f
565
#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
567
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
568
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
569
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
570
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
572
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_enum_t, unsigned long);
573
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
574
typedef DECLARE_DRIZZLE_SYSVAR_TYPELIB(sysvar_set_t, uint64_t);
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)
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 my_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 my_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 my_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 int check_func_enum(Session *, drizzle_sys_var *var,
712
void *save, drizzle_value *value)
714
char buff[STRING_BUFFER_USUAL_SIZE];
715
const char *strvalue= "NULL", *str;
721
if (var->flags & PLUGIN_VAR_SessionLOCAL)
722
typelib= ((sessionvar_enum_t*) var)->typelib;
724
typelib= ((sysvar_enum_t*) var)->typelib;
726
if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
728
length= sizeof(buff);
729
if (!(str= value->val_str(value, buff, &length)))
731
if ((result= (long)find_type(typelib, str, length, 1)-1) < 0)
739
if (value->val_int(value, &tmp))
741
if (tmp >= typelib->count)
749
*(long*)save= result;
752
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
757
static int check_func_set(Session *, drizzle_sys_var *var,
758
void *save, drizzle_value *value)
760
char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
761
const char *strvalue= "NULL", *str;
768
if (var->flags & PLUGIN_VAR_SessionLOCAL)
769
typelib= ((sessionvar_set_t*) var)->typelib;
771
typelib= ((sysvar_set_t*)var)->typelib;
773
if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
775
length= sizeof(buff);
776
if (!(str= value->val_str(value, buff, &length)))
778
result= find_set(typelib, str, length, NULL,
779
&error, &error_len, ¬_used);
782
length= min((uint32_t)sizeof(buff), error_len);
783
strncpy(buff, error, length);
791
if (value->val_int(value, (int64_t *)&result))
793
if (unlikely((result >= (1UL << typelib->count)) &&
794
(typelib->count < sizeof(long)*8)))
801
*(uint64_t*)save= result;
804
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
809
static void update_func_bool(Session *, drizzle_sys_var *,
810
void *tgt, const void *save)
812
*(bool *) tgt= *(int *) save ? 1 : 0;
816
static void update_func_int(Session *, drizzle_sys_var *,
817
void *tgt, const void *save)
819
*(int *)tgt= *(int *) save;
823
static void update_func_long(Session *, drizzle_sys_var *,
824
void *tgt, const void *save)
826
*(long *)tgt= *(long *) save;
830
static void update_func_int64_t(Session *, drizzle_sys_var *,
831
void *tgt, const void *save)
833
*(int64_t *)tgt= *(uint64_t *) save;
837
static void update_func_str(Session *, drizzle_sys_var *var,
838
void *tgt, const void *save)
840
char *old= *(char **) tgt;
841
*(char **)tgt= *(char **) save;
842
if (var->flags & PLUGIN_VAR_MEMALLOC)
844
*(char **)tgt= strdup(*(char **) save);
847
* There isn't a _really_ good thing to do here until this whole set_var
848
* mess gets redesigned
851
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
507
857
/****************************************************************************
508
858
System Variables support
509
859
****************************************************************************/
862
sys_var *find_sys_var(Session *, const char *str, uint32_t length)
865
sys_var_pluginvar *pi= NULL;
866
plugin::Module *module;
868
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
869
if ((var= intern_find_sys_var(str, length, false)) &&
870
(pi= var->cast_pluginvar()))
872
pthread_rwlock_unlock(&LOCK_system_variables_hash);
873
if (!(module= pi->plugin))
874
var= NULL; /* failed to lock it, it must be uninstalling */
875
else if (module->isInited == false)
881
pthread_rwlock_unlock(&LOCK_system_variables_hash);
884
If the variable exists but the plugin it is associated with is not ready
885
then the intern_plugin_lock did not raise an error, so we do it here.
888
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
894
called by register_var, construct_options and test_plugin_options.
895
Returns the 'bookmark' for the named variable.
896
LOCK_system_variables_hash should be at least read locked
898
static st_bookmark *find_bookmark(const char *plugin, const char *name, int flags)
900
st_bookmark *result= NULL;
901
uint32_t namelen, length, pluginlen= 0;
904
if (!(flags & PLUGIN_VAR_SessionLOCAL))
907
namelen= strlen(name);
909
pluginlen= strlen(plugin) + 1;
910
length= namelen + pluginlen + 2;
911
varname= (char*) malloc(length);
915
sprintf(varname+1,"%s_%s",plugin,name);
916
for (p= varname + 1; *p; p++)
921
memcpy(varname + 1, name, namelen + 1);
923
varname[0]= flags & PLUGIN_VAR_TYPEMASK;
925
result= (st_bookmark*) hash_search(&bookmark_hash,
926
(const unsigned char*) varname, length - 1);
934
returns a bookmark for session-local variables, creating if neccessary.
935
returns null for non session-local variables.
936
Requires that a write lock is obtained on LOCK_system_variables_hash
938
static st_bookmark *register_var(const char *plugin, const char *name,
941
uint32_t length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
945
if (!(flags & PLUGIN_VAR_SessionLOCAL))
948
switch (flags & PLUGIN_VAR_TYPEMASK) {
949
case PLUGIN_VAR_BOOL:
950
size= ALIGN_SIZE(sizeof(bool));
953
size= ALIGN_SIZE(sizeof(int));
955
case PLUGIN_VAR_LONG:
956
case PLUGIN_VAR_ENUM:
957
size= ALIGN_SIZE(sizeof(long));
959
case PLUGIN_VAR_LONGLONG:
961
size= ALIGN_SIZE(sizeof(uint64_t));
964
size= ALIGN_SIZE(sizeof(char*));
971
varname= ((char*) malloc(length));
972
sprintf(varname+1, "%s_%s", plugin, name);
973
for (p= varname + 1; *p; p++)
977
if (!(result= find_bookmark(NULL, varname + 1, flags)))
979
result= (st_bookmark*) alloc_root(&plugin_mem_root,
980
sizeof(struct st_bookmark) + length-1);
981
varname[0]= flags & PLUGIN_VAR_TYPEMASK;
982
memcpy(result->key, varname, length);
983
result->name_len= length - 2;
986
assert(size && !(size & (size-1))); /* must be power of 2 */
988
offset= global_system_variables.dynamic_variables_size;
989
offset= (offset + size - 1) & ~(size - 1);
990
result->offset= (int) offset;
992
new_size= (offset + size + 63) & ~63;
994
if (new_size > global_variables_dynamic_size)
998
(char *)realloc(global_system_variables.dynamic_variables_ptr,
1001
global_system_variables.dynamic_variables_ptr= tmpptr;
1004
(char *)realloc(max_system_variables.dynamic_variables_ptr,
1007
max_system_variables.dynamic_variables_ptr= tmpptr;
1010
Clear the new variable value space. This is required for string
1011
variables. If their value is non-NULL, it must point to a valid
1014
memset(global_system_variables.dynamic_variables_ptr +
1015
global_variables_dynamic_size, 0,
1016
new_size - global_variables_dynamic_size);
1017
memset(max_system_variables.dynamic_variables_ptr +
1018
global_variables_dynamic_size, 0,
1019
new_size - global_variables_dynamic_size);
1020
global_variables_dynamic_size= new_size;
1023
global_system_variables.dynamic_variables_head= offset;
1024
max_system_variables.dynamic_variables_head= offset;
1025
global_system_variables.dynamic_variables_size= offset + size;
1026
max_system_variables.dynamic_variables_size= offset + size;
1027
global_system_variables.dynamic_variables_version++;
1028
max_system_variables.dynamic_variables_version++;
1030
result->version= global_system_variables.dynamic_variables_version;
1032
/* this should succeed because we have already checked if a dup exists */
1033
if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
1035
fprintf(stderr, "failed to add placeholder to hash");
1045
returns a pointer to the memory which holds the session-local variable or
1046
a pointer to the global variable if session==null.
1047
If required, will sync with global variables if the requested variable
1048
has not yet been allocated in the current thread.
1050
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
1052
assert(offset >= 0);
1053
assert((uint32_t)offset <= global_system_variables.dynamic_variables_head);
1056
return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
1059
dynamic_variables_head points to the largest valid offset
1061
if (!session->variables.dynamic_variables_ptr ||
1062
(uint32_t)offset > session->variables.dynamic_variables_head)
1066
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1069
if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
1070
global_variables_dynamic_size)))
1072
session->variables.dynamic_variables_ptr= tmpptr;
1075
pthread_mutex_lock(&LOCK_global_system_variables);
1077
//safe_mutex_assert_owner(&LOCK_global_system_variables);
1079
memcpy(session->variables.dynamic_variables_ptr +
1080
session->variables.dynamic_variables_size,
1081
global_system_variables.dynamic_variables_ptr +
1082
session->variables.dynamic_variables_size,
1083
global_system_variables.dynamic_variables_size -
1084
session->variables.dynamic_variables_size);
1087
now we need to iterate through any newly copied 'defaults'
1088
and if it is a string type with MEMALLOC flag, we need to strdup
1090
for (idx= 0; idx < bookmark_hash.records; idx++)
1092
sys_var_pluginvar *pi;
1094
st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
1096
if (v->version <= session->variables.dynamic_variables_version ||
1097
!(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1098
!(pi= var->cast_pluginvar()) ||
1099
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1102
/* Here we do anything special that may be required of the data types */
1104
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
1105
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
1107
char **pp= (char**) (session->variables.dynamic_variables_ptr +
1108
*(int*)(pi->plugin_var + 1));
1109
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
1110
*(int*)(pi->plugin_var + 1))))
1118
pthread_mutex_unlock(&LOCK_global_system_variables);
1120
session->variables.dynamic_variables_version=
1121
global_system_variables.dynamic_variables_version;
1122
session->variables.dynamic_variables_head=
1123
global_system_variables.dynamic_variables_head;
1124
session->variables.dynamic_variables_size=
1125
global_system_variables.dynamic_variables_size;
1127
pthread_rwlock_unlock(&LOCK_system_variables_hash);
1129
return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1132
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1134
return (bool *)intern_sys_var_ptr(a_session, offset, true);
1137
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1139
return (int *)intern_sys_var_ptr(a_session, offset, true);
1142
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1144
return (long *)intern_sys_var_ptr(a_session, offset, true);
1147
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1149
return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1152
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1154
return (char **)intern_sys_var_ptr(a_session, offset, true);
1157
static uint64_t *mysql_sys_var_ptr_set(Session* a_session, int offset)
1159
return (uint64_t *)intern_sys_var_ptr(a_session, offset, true);
1162
static unsigned long *mysql_sys_var_ptr_enum(Session* a_session, int offset)
1164
return (unsigned long *)intern_sys_var_ptr(a_session, offset, true);
513
1168
void plugin_sessionvar_init(Session *session)
515
1170
session->variables.storage_engine= NULL;
516
cleanup_variables(&session->variables);
1171
cleanup_variables(session, &session->variables);
518
1173
session->variables= global_system_variables;
519
1174
session->variables.storage_engine= NULL;
556
1239
void plugin_sessionvar_cleanup(Session *session)
558
1241
unlock_variables(session, &session->variables);
559
cleanup_variables(&session->variables);
1242
cleanup_variables(session, &session->variables);
1247
@brief Free values of thread variables of a plugin.
1249
This must be called before a plugin is deleted. Otherwise its
1250
variables are no longer accessible and the value space is lost. Note
1251
that only string values with PLUGIN_VAR_MEMALLOC are allocated and
1254
@param[in] vars Chain of system variables of a plugin
1257
static void plugin_vars_free_values(sys_var *vars)
1260
for (sys_var *var= vars; var; var= var->getNext())
1262
sys_var_pluginvar *piv= var->cast_pluginvar();
1264
((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
1265
(piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
1267
/* Free the string from global_system_variables. */
1268
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
1277
bool sys_var_pluginvar::check_update_type(Item_result type)
1281
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1282
case PLUGIN_VAR_INT:
1283
case PLUGIN_VAR_LONG:
1284
case PLUGIN_VAR_LONGLONG:
1285
return type != INT_RESULT;
1286
case PLUGIN_VAR_STR:
1287
return type != STRING_RESULT;
1294
SHOW_TYPE sys_var_pluginvar::show_type()
1296
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1297
case PLUGIN_VAR_BOOL:
1298
return SHOW_MY_BOOL;
1299
case PLUGIN_VAR_INT:
1301
case PLUGIN_VAR_LONG:
1303
case PLUGIN_VAR_LONGLONG:
1304
return SHOW_LONGLONG;
1305
case PLUGIN_VAR_STR:
1306
return SHOW_CHAR_PTR;
1307
case PLUGIN_VAR_ENUM:
1308
case PLUGIN_VAR_SET:
1317
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, enum_var_type type)
1319
assert(session || (type == OPT_GLOBAL));
1320
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1322
if (type == OPT_GLOBAL)
1325
return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1327
return *(unsigned char**) (plugin_var+1);
1331
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
1333
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1334
case PLUGIN_VAR_ENUM:
1335
return ((sysvar_enum_t *)plugin_var)->typelib;
1336
case PLUGIN_VAR_SET:
1337
return ((sysvar_set_t *)plugin_var)->typelib;
1338
case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
1339
return ((sessionvar_enum_t *)plugin_var)->typelib;
1340
case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
1341
return ((sessionvar_set_t *)plugin_var)->typelib;
1349
unsigned char* sys_var_pluginvar::value_ptr(Session *session, enum_var_type type, const LEX_STRING *)
1351
unsigned char* result;
1353
result= real_value_ptr(session, type);
1355
if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
1356
result= (unsigned char*) get_type(plugin_var_typelib(), *(ulong*)result);
1357
else if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
1359
char buffer[STRING_BUFFER_USUAL_SIZE];
1360
String str(buffer, sizeof(buffer), system_charset_info);
1361
TYPELIB *typelib= plugin_var_typelib();
1362
uint64_t mask= 1, value= *(uint64_t*) result;
1366
for (i= 0; i < typelib->count; i++, mask<<=1)
1368
if (!(value & mask))
1370
str.append(typelib->type_names[i], typelib->type_lengths[i]);
1374
result= (unsigned char*) "";
1376
result= (unsigned char*) session->strmake(str.ptr(), str.length()-1);
1382
bool sys_var_pluginvar::check(Session *session, set_var *var)
1384
st_item_value_holder value;
1385
assert(is_readonly() || plugin_var->check);
1387
value.value_type= item_value_type;
1388
value.val_str= item_val_str;
1389
value.val_int= item_val_int;
1390
value.val_real= item_val_real;
1391
value.item= var->value;
1393
return is_readonly() ||
1394
plugin_var->check(session, plugin_var, &var->save_result, &value);
1398
void sys_var_pluginvar::set_default(Session *session, enum_var_type type)
1403
assert(is_readonly() || plugin_var->update);
1408
pthread_mutex_lock(&LOCK_global_system_variables);
1409
tgt= real_value_ptr(session, type);
1410
src= ((void **) (plugin_var + 1) + 1);
1412
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1414
if (type != OPT_GLOBAL)
1415
src= real_value_ptr(session, OPT_GLOBAL);
1417
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1418
case PLUGIN_VAR_INT:
1419
src= &((sessionvar_uint_t*) plugin_var)->def_val;
1421
case PLUGIN_VAR_LONG:
1422
src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1424
case PLUGIN_VAR_LONGLONG:
1425
src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1427
case PLUGIN_VAR_ENUM:
1428
src= &((sessionvar_enum_t*) plugin_var)->def_val;
1430
case PLUGIN_VAR_SET:
1431
src= &((sessionvar_set_t*) plugin_var)->def_val;
1433
case PLUGIN_VAR_BOOL:
1434
src= &((sessionvar_bool_t*) plugin_var)->def_val;
1436
case PLUGIN_VAR_STR:
1437
src= &((sessionvar_str_t*) plugin_var)->def_val;
1444
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1445
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1446
session == current_session);
1448
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1450
plugin_var->update(session, plugin_var, tgt, src);
1451
pthread_mutex_unlock(&LOCK_global_system_variables);
1455
pthread_mutex_unlock(&LOCK_global_system_variables);
1456
plugin_var->update(session, plugin_var, tgt, src);
1461
bool sys_var_pluginvar::update(Session *session, set_var *var)
1465
assert(is_readonly() || plugin_var->update);
1467
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1468
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1469
session == current_session);
1474
pthread_mutex_lock(&LOCK_global_system_variables);
1475
tgt= real_value_ptr(session, var->type);
1477
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1479
/* variable we are updating has global scope, so we unlock after updating */
1480
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1481
pthread_mutex_unlock(&LOCK_global_system_variables);
1485
pthread_mutex_unlock(&LOCK_global_system_variables);
1486
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1492
#define OPTION_SET_LIMITS(type, options, opt) \
1493
options->var_type= type; \
1494
options->def_value= (opt)->def_val; \
1495
options->min_value= (opt)->min_val; \
1496
options->max_value= (opt)->max_val; \
1497
options->block_size= (long) (opt)->blk_sz
1500
void plugin_opt_set_limits(struct my_option *options,
1501
const drizzle_sys_var *opt)
1503
options->sub_size= 0;
1505
switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
1506
PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1507
/* global system variables */
1508
case PLUGIN_VAR_INT:
1509
OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
1511
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
1512
OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
1514
case PLUGIN_VAR_LONG:
1515
OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
1517
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
1518
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sysvar_ulong_t*) opt);
1520
case PLUGIN_VAR_LONGLONG:
1521
OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1523
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
1524
OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1526
case PLUGIN_VAR_ENUM:
1527
options->var_type= GET_ENUM;
1528
options->typelib= ((sysvar_enum_t*) opt)->typelib;
1529
options->def_value= ((sysvar_enum_t*) opt)->def_val;
1530
options->min_value= options->block_size= 0;
1531
options->max_value= options->typelib->count - 1;
1533
case PLUGIN_VAR_SET:
1534
options->var_type= GET_SET;
1535
options->typelib= ((sysvar_set_t*) opt)->typelib;
1536
options->def_value= ((sysvar_set_t*) opt)->def_val;
1537
options->min_value= options->block_size= 0;
1538
options->max_value= (1UL << options->typelib->count) - 1;
1540
case PLUGIN_VAR_BOOL:
1541
options->var_type= GET_BOOL;
1542
options->def_value= ((sysvar_bool_t*) opt)->def_val;
1544
case PLUGIN_VAR_STR:
1545
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1546
GET_STR_ALLOC : GET_STR);
1547
options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1549
/* threadlocal variables */
1550
case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
1551
OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1553
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1554
OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1556
case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
1557
OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1559
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1560
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sessionvar_ulong_t*) opt);
1562
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
1563
OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1565
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1566
OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1568
case PLUGIN_VAR_ENUM | PLUGIN_VAR_SessionLOCAL:
1569
options->var_type= GET_ENUM;
1570
options->typelib= ((sessionvar_enum_t*) opt)->typelib;
1571
options->def_value= ((sessionvar_enum_t*) opt)->def_val;
1572
options->min_value= options->block_size= 0;
1573
options->max_value= options->typelib->count - 1;
1575
case PLUGIN_VAR_SET | PLUGIN_VAR_SessionLOCAL:
1576
options->var_type= GET_SET;
1577
options->typelib= ((sessionvar_set_t*) opt)->typelib;
1578
options->def_value= ((sessionvar_set_t*) opt)->def_val;
1579
options->min_value= options->block_size= 0;
1580
options->max_value= (1UL << options->typelib->count) - 1;
1582
case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1583
options->var_type= GET_BOOL;
1584
options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1586
case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1587
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1588
GET_STR_ALLOC : GET_STR);
1589
options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1594
options->arg_type= REQUIRED_ARG;
1595
if (opt->flags & PLUGIN_VAR_NOCMDARG)
1596
options->arg_type= NO_ARG;
1597
if (opt->flags & PLUGIN_VAR_OPCMDARG)
1598
options->arg_type= OPT_ARG;
1601
extern "C" bool get_one_plugin_option(int optid, const struct my_option *,
1604
bool get_one_plugin_option(int, const struct my_option *, char *)
1610
static int construct_options(memory::Root *mem_root, plugin::Module *tmp,
1613
const char *plugin_name= tmp->getManifest().name;
1614
uint32_t namelen= strlen(plugin_name), optnamelen;
1615
uint32_t buffer_length= namelen * 4 + 75;
1616
char *name= (char*) alloc_root(mem_root, buffer_length);
1617
bool *enabled_value= (bool*) alloc_root(mem_root, sizeof(bool));
1619
int index= 0, offset= 0;
1620
drizzle_sys_var *opt, **plugin_option;
1623
/* support --skip-plugin-foo syntax */
1624
memcpy(name, plugin_name, namelen + 1);
1625
my_casedn_str(&my_charset_utf8_general_ci, name);
1626
sprintf(name+namelen+1, "plugin-%s", name);
1627
/* Now we have namelen + 1 + 7 + namelen + 1 == namelen * 2 + 9. */
1629
for (p= name + namelen*2 + 8; p > name; p--)
1633
sprintf(name+namelen*2+10,
1634
"Enable %s plugin. Disable with --skip-%s (will save memory).",
1637
Now we have namelen * 2 + 10 (one char unused) + 7 + namelen + 9 +
1638
20 + namelen + 20 + 1 == namelen * 4 + 67.
1641
options[0].comment= name + namelen*2 + 10;
1644
This whole code around variables and command line parameters is turd
1647
e.g. the below assignemnt of having the plugin alaways enabled is never
1648
changed so that './drizzled --skip-innodb --help' shows innodb as enabled.
1650
But this is just as broken as it was in MySQL and properly fixing everything
1651
is a decent amount of "future work"
1653
*enabled_value= true; /* by default, plugin enabled */
1655
options[1].name= (options[0].name= name) + namelen + 1;
1656
options[0].id= options[1].id= 256; /* must be >255. dup id ok */
1657
options[0].var_type= options[1].var_type= GET_BOOL;
1658
options[0].arg_type= options[1].arg_type= NO_ARG;
1659
options[0].def_value= options[1].def_value= true;
1660
options[0].value= options[0].u_max_value=
1661
options[1].value= options[1].u_max_value= (char**) enabled_value;
1665
Two passes as the 2nd pass will take pointer addresses for use
1666
by my_getopt and register_var() in the first pass uses realloc
1669
for (plugin_option= tmp->getManifest().system_vars;
1670
plugin_option && *plugin_option; plugin_option++, index++)
1672
opt= *plugin_option;
1673
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1675
if (!(register_var(name, opt->name, opt->flags)))
1677
switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
1678
case PLUGIN_VAR_BOOL:
1679
(((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1681
case PLUGIN_VAR_INT:
1682
(((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1684
case PLUGIN_VAR_LONG:
1685
(((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1687
case PLUGIN_VAR_LONGLONG:
1688
(((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1690
case PLUGIN_VAR_STR:
1691
(((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1693
case PLUGIN_VAR_ENUM:
1694
(((sessionvar_enum_t *)opt)->resolve)= mysql_sys_var_ptr_enum;
1696
case PLUGIN_VAR_SET:
1697
(((sessionvar_set_t *)opt)->resolve)= mysql_sys_var_ptr_set;
1700
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1701
opt->flags, plugin_name);
1706
for (plugin_option= tmp->getManifest().system_vars;
1707
plugin_option && *plugin_option; plugin_option++, index++)
1709
switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
1710
case PLUGIN_VAR_BOOL:
1712
opt->check= check_func_bool;
1714
opt->update= update_func_bool;
1716
case PLUGIN_VAR_INT:
1718
opt->check= check_func_int;
1720
opt->update= update_func_int;
1722
case PLUGIN_VAR_LONG:
1724
opt->check= check_func_long;
1726
opt->update= update_func_long;
1728
case PLUGIN_VAR_LONGLONG:
1730
opt->check= check_func_int64_t;
1732
opt->update= update_func_int64_t;
1734
case PLUGIN_VAR_STR:
1736
opt->check= check_func_str;
1739
opt->update= update_func_str;
1740
if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1742
opt->flags|= PLUGIN_VAR_READONLY;
1743
errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1744
"to be read-only: string variable without "
1745
"update_func and PLUGIN_VAR_MEMALLOC flag"),
1746
opt->name, plugin_name);
1750
case PLUGIN_VAR_ENUM:
1752
opt->check= check_func_enum;
1754
opt->update= update_func_long;
1756
case PLUGIN_VAR_SET:
1758
opt->check= check_func_set;
1760
opt->update= update_func_int64_t;
1763
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1764
opt->flags, plugin_name);
1768
if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1769
== PLUGIN_VAR_NOCMDOPT)
1774
errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1779
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1781
optnamelen= strlen(opt->name);
1782
optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
1783
sprintf(optname, "%s-%s", name, opt->name);
1784
optnamelen= namelen + optnamelen + 1;
1788
/* this should not fail because register_var should create entry */
1789
if (!(v= find_bookmark(name, opt->name, opt->flags)))
1791
errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
1792
"in plugin '%s'."), opt->name, plugin_name);
1796
*(int*)(opt + 1)= offset= v->offset;
1798
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
1801
optname= (char*) memdup_root(mem_root, v->key + 1,
1802
(optnamelen= v->name_len) + 1);
1805
/* convert '_' to '-' */
1806
for (p= optname; *p; p++)
1810
options->name= optname;
1811
options->comment= opt->comment;
1812
options->app_type= opt;
1813
options->id= (options-1)->id + 1;
1815
plugin_opt_set_limits(options, opt);
1817
if (opt->flags & PLUGIN_VAR_SessionLOCAL)
1818
options->value= options->u_max_value= (char**)
1819
(global_system_variables.dynamic_variables_ptr + offset);
1821
options->value= options->u_max_value= *(char***) (opt + 1);
1823
options[1]= options[0];
1824
options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
1825
options[1].comment= 0; // hidden
1826
sprintf(p,"plugin-%s",optname);
1835
static my_option *construct_help_options(memory::Root *mem_root, plugin::Module *p)
1837
drizzle_sys_var **opt;
1839
uint32_t count= EXTRA_OPTIONS;
1841
for (opt= p->getManifest().system_vars; opt && *opt; opt++, count+= 2) {};
1843
opts= (my_option*)alloc_root(mem_root, (sizeof(my_option) * count));
1847
memset(opts, 0, sizeof(my_option) * count);
1849
if (construct_options(mem_root, p, opts))
1855
void drizzle_add_plugin_sysvar(sys_var_pluginvar *var)
1857
plugin_sysvar_vec.push_back(var);
1860
void drizzle_del_plugin_sysvar()
1862
vector<sys_var_pluginvar *>::iterator iter= plugin_sysvar_vec.begin();
1863
while(iter != plugin_sysvar_vec.end())
1868
plugin_sysvar_vec.clear();
566
1873
test_plugin_options()
567
1874
tmp_root temporary scratch space
568
1875
plugin internal plugin structure
1876
argc user supplied arguments
1877
argv user supplied arguments
569
1878
default_enabled default plugin enable status
571
1880
0 SUCCESS - plugin should be enabled/loaded
573
1882
Requires that a write-lock is held on LOCK_system_variables_hash
575
static int test_plugin_options(memory::Root *,
576
module::Module *test_module,
577
po::options_description &long_options)
1884
static int test_plugin_options(memory::Root *tmp_root, plugin::Module *tmp,
1885
int *argc, char **argv)
580
if (test_module->getManifest().init_options != NULL)
582
string plugin_section_title("Options used by ");
583
plugin_section_title.append(test_module->getName());
584
po::options_description module_options(plugin_section_title);
585
module::option_context opt_ctx(test_module->getName(),
586
module_options.add_options());
587
test_module->getManifest().init_options(opt_ctx);
588
long_options.add(module_options);
1887
struct sys_var_chain chain= { NULL, NULL };
1888
drizzle_sys_var **opt;
1889
my_option *opts= NULL;
1892
struct st_bookmark *var;
1893
uint32_t len, count= EXTRA_OPTIONS;
1895
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
1896
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
1899
if (count > EXTRA_OPTIONS || (*argc > 1))
1901
if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
1903
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory for plugin '%s'."), tmp->getName().c_str());
1906
memset(opts, 0, sizeof(my_option) * count);
1908
if (construct_options(tmp_root, tmp, opts))
1910
errmsg_printf(ERRMSG_LVL_ERROR, _("Bad options for plugin '%s'."), tmp->getName().c_str());
1914
error= handle_options(argc, &argv, opts, get_one_plugin_option);
1915
(*argc)++; /* add back one for the program name */
1919
errmsg_printf(ERRMSG_LVL_ERROR, _("Parsing options for plugin '%s' failed."),
1920
tmp->getName().c_str());
1928
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
1931
if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
1934
if ((var= find_bookmark(tmp->getName().c_str(), o->name, o->flags)))
1935
v= new sys_var_pluginvar(var->key + 1, o);
1938
len= tmp->getName().length() + strlen(o->name) + 2;
1939
string vname(tmp->getName());
1940
vname.push_back('-');
1941
vname.append(o->name);
1942
transform(vname.begin(), vname.end(), vname.begin(), ::tolower);
1943
string::iterator p= vname.begin();
1944
while (p != vname.end())
1951
v= new sys_var_pluginvar(vname, o);
1953
assert(v); /* check that an object was actually constructed */
1955
drizzle_add_plugin_sysvar(static_cast<sys_var_pluginvar *>(v));
1957
Add to the chain of variables.
1958
Done like this for easier debugging so that the
1959
pointer to v is not lost on optimized builds.
1961
v->chain_sys_var(&chain);
1965
chain.last->setNext(NULL);
1966
if (mysql_add_sys_var_chain(chain.first, NULL))
1968
errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has conflicting system variables"),
1969
tmp->getName().c_str());
1972
tmp->system_vars= chain.first;
1979
my_cleanup_options(opts);