12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24
23
#include <algorithm>
27
#include <boost/program_options.hpp>
29
#include <drizzled/option.h>
30
#include <drizzled/internal/m_string.h>
32
#include <drizzled/plugin.h>
33
#include <drizzled/module/load_list.h>
34
#include <drizzled/module/library.h>
35
#include <drizzled/module/registry.h>
36
#include <drizzled/module/option_context.h>
37
#include <drizzled/sql_parse.h>
38
#include <drizzled/show.h>
39
#include <drizzled/cursor.h>
40
#include <drizzled/set_var.h>
41
#include <drizzled/session.h>
42
#include <drizzled/item/null.h>
43
#include <drizzled/error.h>
44
#include <drizzled/gettext.h>
45
#include <drizzled/errmsg_print.h>
46
#include <drizzled/pthread_globals.h>
47
#include <drizzled/util/tokenize.h>
48
#include <drizzled/system_variables.h>
50
#include <boost/foreach.hpp>
25
#include "drizzled/my_getopt.h"
26
#include "drizzled/my_hash.h"
27
#include "drizzled/internal/m_string.h"
29
#include "drizzled/plugin.h"
30
#include "drizzled/plugin/load_list.h"
31
#include "drizzled/sql_parse.h"
32
#include "drizzled/show.h"
33
#include "drizzled/cursor.h"
34
#include "drizzled/set_var.h"
35
#include "drizzled/session.h"
36
#include "drizzled/item/null.h"
37
#include "drizzled/plugin/registry.h"
38
#include "drizzled/error.h"
39
#include "drizzled/gettext.h"
40
#include "drizzled/errmsg_print.h"
41
#include "drizzled/plugin/library.h"
42
#include "drizzled/strfunc.h"
43
#include "drizzled/pthread_globals.h"
44
#include "drizzled/util/tokenize.h"
52
46
/* FreeBSD 2.2.2 does not define RTLD_NOW) */
57
namespace po=boost::program_options;
59
51
using namespace std;
61
/** These exist just to prevent symbols from being optimized out */
62
typedef drizzled::module::Manifest drizzled_builtin_list[];
63
extern drizzled_builtin_list PANDORA_BUILTIN_SYMBOLS_LIST;
64
extern drizzled_builtin_list PANDORA_BUILTIN_LOAD_SYMBOLS_LIST;
65
drizzled::module::Manifest *drizzled_builtins[]=
67
PANDORA_BUILTIN_SYMBOLS_LIST, NULL
69
drizzled::module::Manifest *drizzled_load_builtins[]=
71
PANDORA_BUILTIN_LOAD_SYMBOLS_LIST, NULL
53
typedef drizzled::plugin::Manifest drizzled_builtin_plugin[];
54
extern drizzled_builtin_plugin PANDORA_BUILTIN_LIST;
55
static drizzled::plugin::Manifest *drizzled_builtins[]=
57
PANDORA_BUILTIN_LIST, NULL
77
typedef vector<string> PluginOptions;
78
static PluginOptions opt_plugin_load;
79
static PluginOptions opt_plugin_add;
80
static PluginOptions opt_plugin_remove;
81
const char *builtin_plugins= PANDORA_BUILTIN_LIST;
82
const char *builtin_load_plugins= PANDORA_BUILTIN_LOAD_LIST;
64
class sys_var_pluginvar;
65
static vector<sys_var_pluginvar *> plugin_sysvar_vec;
67
char *opt_plugin_add= NULL;
68
char *opt_plugin_remove= NULL;
69
char *opt_plugin_load= NULL;
70
char *opt_plugin_dir_ptr;
71
char opt_plugin_dir[FN_REFLEN];
72
const char *opt_plugin_load_default= PANDORA_PLUGIN_LIST;
84
74
/* Note that 'int version' must be the first field of every plugin
85
75
sub-structure (plugin->info).
103
stored in bookmark_hash, this structure is never removed from the
104
hash and is used to mark a single offset for a session local variable
105
even if plugins have been uninstalled and reinstalled, repeatedly.
106
This structure is allocated from plugin_mem_root.
108
The key format is as follows:
109
1 byte - variable type code
110
name_len bytes - variable name
123
sys_var class for access to all plugin variables visible to the user
125
class sys_var_pluginvar: public sys_var
128
plugin::Module *plugin;
129
drizzle_sys_var *plugin_var;
131
sys_var_pluginvar(const std::string name_arg,
132
drizzle_sys_var *plugin_var_arg)
133
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
134
sys_var_pluginvar *cast_pluginvar() { return this; }
135
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
136
bool check_type(sql_var_t type)
137
{ return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
138
bool check_update_type(Item_result type);
139
SHOW_TYPE show_type();
140
unsigned char* real_value_ptr(Session *session, sql_var_t type);
141
TYPELIB* plugin_var_typelib(void);
142
unsigned char* value_ptr(Session *session, sql_var_t type,
143
const LEX_STRING *base);
144
bool check(Session *session, set_var *var);
145
bool check_default(sql_var_t)
146
{ return is_readonly(); }
147
void set_default(Session *session, sql_var_t);
148
bool update(Session *session, set_var *var);
111
static void plugin_prune_list(vector<string> &plugin_list, const vector<string> &plugins_to_remove);
112
static bool plugin_load_list(module::Registry ®istry,
113
memory::Root *tmp_root,
114
const set<string> &plugin_list,
115
po::options_description &long_options,
116
bool builtin= false);
117
static int test_plugin_options(memory::Root*, module::Module*, po::options_description&long_options);
118
static void unlock_variables(Session *session, drizzle_system_variables *vars);
119
static void cleanup_variables(drizzle_system_variables *vars);
153
static void plugin_prune_list(vector<string> &plugin_list,
154
const vector<string> &plugins_to_remove);
155
static bool plugin_load_list(plugin::Registry ®istry,
156
memory::Root *tmp_root, int *argc, char **argv,
157
const vector<string> &plugin_list);
158
static int test_plugin_options(memory::Root *, plugin::Module *,
160
static void unlock_variables(Session *session, struct system_variables *vars);
161
static void cleanup_variables(Session *session, struct system_variables *vars);
162
static void plugin_vars_free_values(sys_var *vars);
164
/* declared in set_var.cc */
165
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
166
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
167
const std::string &name, int64_t val);
169
static bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
170
const char *name, int64_t val)
172
const std::string name_str(name);
173
return throw_bounds_warning(session, fixed, unsignd, name_str, val);
176
/****************************************************************************
177
Value type thunks, allows the C world to play in the C++ world
178
****************************************************************************/
180
static int item_value_type(drizzle_value *value)
182
switch (((st_item_value_holder*)value)->item->result_type()) {
184
return DRIZZLE_VALUE_TYPE_INT;
186
return DRIZZLE_VALUE_TYPE_REAL;
188
return DRIZZLE_VALUE_TYPE_STRING;
192
static const char *item_val_str(drizzle_value *value,
193
char *buffer, int *length)
195
String str(buffer, *length, system_charset_info), *res;
196
if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
198
*length= res->length();
199
if (res->c_ptr_quick() == buffer)
203
Lets be nice and create a temporary string since the
206
return current_session->strmake(res->c_ptr_quick(), res->length());
210
static int item_val_int(drizzle_value *value, int64_t *buf)
212
Item *item= ((st_item_value_holder*)value)->item;
213
*buf= item->val_int();
220
static int item_val_real(drizzle_value *value, double *buf)
222
Item *item= ((st_item_value_holder*)value)->item;
223
*buf= item->val_real();
122
230
/****************************************************************************
160
module::Module* tmp= new module::Module(manifest, library);
269
tmp= new (std::nothrow) plugin::Module(manifest, library);
162
if (!test_plugin_options(tmp_root, tmp, long_options))
273
if (!test_plugin_options(tmp_root, tmp, argc, argv))
164
275
registry.add(tmp);
167
errmsg_printf(error::ERROR, ER(ER_CANT_FIND_DL_ENTRY),
278
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY),
168
279
library->getName().c_str());
173
static void reap_plugins(module::Registry ®istry)
175
BOOST_FOREACH(module::Registry::ModuleMap::const_reference module, registry.getModulesMap())
176
delete module.second;
180
static bool plugin_initialize(module::Registry ®istry,
181
module::Module *module)
284
static void delete_module(plugin::Registry ®istry, plugin::Module *module)
286
plugin::Manifest manifest= module->getManifest();
288
if (module->isInited)
291
manifest.deinit(registry);
294
/* Free allocated strings before deleting the plugin. */
295
plugin_vars_free_values(module->system_vars);
296
module->isInited= false;
297
pthread_rwlock_wrlock(&LOCK_system_variables_hash);
298
mysql_del_sys_var_chain(module->system_vars);
299
pthread_rwlock_unlock(&LOCK_system_variables_hash);
304
static void reap_plugins(plugin::Registry ®istry)
306
plugin::Module *module;
308
std::map<std::string, plugin::Module *>::const_iterator modules=
309
registry.getModulesMap().begin();
311
while (modules != registry.getModulesMap().end())
313
module= (*modules).second;
314
delete_module(registry, module);
317
drizzle_del_plugin_sysvar();
321
static void plugin_initialize_vars(plugin::Module *module)
324
set the plugin attribute of plugin's sys vars so they are pointing
327
if (module->system_vars)
329
sys_var_pluginvar *var= module->system_vars->cast_pluginvar();
333
if (! var->getNext())
335
var= var->getNext()->cast_pluginvar();
341
static bool plugin_initialize(plugin::Registry ®istry,
342
plugin::Module *module)
183
344
assert(module->isInited == false);
185
module::Context loading_context(registry, module);
346
registry.setCurrentModule(module);
186
347
if (module->getManifest().init)
188
if (module->getManifest().init(loading_context))
349
if (module->getManifest().init(registry))
190
errmsg_printf(error::ERROR,
351
errmsg_printf(ERRMSG_LVL_ERROR,
191
352
_("Plugin '%s' init function returned error.\n"),
192
353
module->getName().c_str());
357
registry.clearCurrentModule();
196
358
module->isInited= true;
200
static void compose_plugin_options(vector<string> &target,
201
vector<string> options)
203
BOOST_FOREACH(vector<string>::reference it, options)
204
tokenize(it, target, ",", true);
205
BOOST_FOREACH(vector<string>::reference it, target)
206
std::replace(it.begin(), it.end(), '-', '_');
209
void compose_plugin_add(vector<string> options)
211
compose_plugin_options(opt_plugin_add, options);
214
void compose_plugin_remove(vector<string> options)
216
compose_plugin_options(opt_plugin_remove, options);
219
void notify_plugin_load(string in_plugin_load)
221
tokenize(in_plugin_load, opt_plugin_load, ",", true);
365
static unsigned char *get_bookmark_hash_key(const unsigned char *buff,
366
size_t *length, bool)
368
struct st_bookmark *var= (st_bookmark *)buff;
369
*length= var->name_len + 1;
370
return (unsigned char*) var->key;
225
375
The logic is that we first load and initialize all compiled in plugins.
229
379
Finally we initialize everything, aka the dynamic that have yet to initialize.
231
bool plugin_init(module::Registry ®istry,
232
po::options_description &long_options)
381
bool plugin_init(plugin::Registry ®istry,
382
int *argc, char **argv,
385
plugin::Manifest **builtins;
386
plugin::Manifest *manifest;
387
plugin::Module *module;
388
memory::Root tmp_root;
239
PluginOptions builtin_load_list;
240
tokenize(builtin_load_plugins, builtin_load_list, ",", true);
242
PluginOptions builtin_list;
243
tokenize(builtin_plugins, builtin_list, ",", true);
393
init_alloc_root(&plugin_mem_root, 4096);
394
init_alloc_root(&tmp_root, 4096);
396
if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
397
get_bookmark_hash_key, NULL, HASH_UNIQUE))
399
free_root(&tmp_root, MYF(0));
407
First we register builtin plugins
409
for (builtins= drizzled_builtins; *builtins; builtins++)
412
if (manifest->name != NULL)
414
module= new (std::nothrow) plugin::Module(manifest);
418
free_root(&tmp_root, MYF(memory::MARK_BLOCKS_FREE));
419
if (test_plugin_options(&tmp_root, module, argc, argv))
422
registry.add(module);
424
plugin_initialize_vars(module);
428
if (plugin_initialize(registry, module))
430
free_root(&tmp_root, MYF(0));
245
438
bool load_failed= false;
247
if (opt_plugin_add.size() > 0)
249
for (PluginOptions::iterator iter= opt_plugin_add.begin();
250
iter != opt_plugin_add.end();
253
if (find(builtin_list.begin(),
254
builtin_list.end(), *iter) != builtin_list.end())
256
builtin_load_list.push_back(*iter);
260
opt_plugin_load.push_back(*iter);
265
if (opt_plugin_remove.size() > 0)
267
plugin_prune_list(opt_plugin_load, opt_plugin_remove);
268
plugin_prune_list(builtin_load_list, opt_plugin_remove);
271
memory::Root tmp_root(4096);
273
First we register builtin plugins
275
const set<string> builtin_list_set(builtin_load_list.begin(),
276
builtin_load_list.end());
277
load_failed= plugin_load_list(registry, &tmp_root,
278
builtin_list_set, long_options, true);
281
tmp_root.free_root(MYF(0));
285
/* Uniquify the list */
286
const set<string> plugin_list_set(opt_plugin_load.begin(),
287
opt_plugin_load.end());
439
vector<string> plugin_list;
442
tokenize(opt_plugin_load, plugin_list, ",", true);
446
tokenize(opt_plugin_load_default, plugin_list, ",", true);
450
tokenize(opt_plugin_add, plugin_list, ",", true);
453
if (opt_plugin_remove)
455
vector<string> plugins_to_remove;
456
tokenize(opt_plugin_remove, plugins_to_remove, ",", true);
457
plugin_prune_list(plugin_list, plugins_to_remove);
289
460
/* Register all dynamic plugins */
290
load_failed= plugin_load_list(registry, &tmp_root,
291
plugin_list_set, long_options);
461
load_failed= plugin_load_list(registry, &tmp_root, argc, argv,
294
tmp_root.free_root(MYF(0));
465
free_root(&tmp_root, MYF(0));
298
tmp_root.free_root(MYF(0));
303
bool plugin_finalize(module::Registry ®istry)
471
free_root(&tmp_root, MYF(0));
306
476
Now we initialize all remaining plugins
308
BOOST_FOREACH(module::Registry::ModuleList::const_reference module, registry.getList())
478
std::map<std::string, plugin::Module *>::const_iterator modules=
479
registry.getModulesMap().begin();
481
while (modules != registry.getModulesMap().end())
310
if (not module->isInited && plugin_initialize(registry, module))
483
module= (*modules).second;
485
if (module->isInited == false)
312
registry.remove(module);
487
plugin_initialize_vars(module);
489
if (plugin_initialize(registry, module))
490
delete_module(registry, module);
317
BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
319
value.second->prime();
495
free_root(&tmp_root, MYF(0));
325
Window of opportunity for plugins to issue any queries with the database up and running but with no user's connected.
327
void plugin_startup_window(module::Registry ®istry, drizzled::Session &session)
329
BOOST_FOREACH(plugin::Plugin::map::value_type value, registry.getPluginsMap())
331
value.second->startup(session);
335
500
class PrunePlugin :
336
501
public unary_function<string, bool>
406
577
unlock_variables(NULL, &global_system_variables);
407
578
unlock_variables(NULL, &max_system_variables);
409
cleanup_variables(&global_system_variables);
410
cleanup_variables(&max_system_variables);
580
cleanup_variables(NULL, &global_system_variables);
581
cleanup_variables(NULL, &max_system_variables);
415
586
/* Dispose of the memory */
416
plugin_mem_root.free_root(MYF(0));
588
hash_free(&bookmark_hash);
589
free_root(&plugin_mem_root, MYF(0));
418
591
global_variables_dynamic_size= 0;
594
/****************************************************************************
595
Internal type declarations for variables support
596
****************************************************************************/
598
#undef DRIZZLE_SYSVAR_NAME
599
#define DRIZZLE_SYSVAR_NAME(name) name
600
#define PLUGIN_VAR_TYPEMASK 0x007f
602
static const uint32_t EXTRA_OPTIONS= 1; /* handle the NULL option */
604
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
605
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
606
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
607
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
609
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
610
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_set_t, uint64_t);
612
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
613
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
614
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
615
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
616
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
617
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
619
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int_t, int);
620
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_long_t, long);
621
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int64_t_t, int64_t);
622
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint_t, uint);
623
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_ulong_t, ulong);
624
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint64_t_t, uint64_t);
626
typedef bool *(*mysql_sys_var_ptr_p)(Session* a_session, int offset);
629
/****************************************************************************
630
default variable data check and update functions
631
****************************************************************************/
633
static int check_func_bool(Session *, drizzle_sys_var *var,
634
void *save, drizzle_value *value)
636
char buff[STRING_BUFFER_USUAL_SIZE];
637
const char *strvalue= "NULL", *str;
641
if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
643
length= sizeof(buff);
644
if (!(str= value->val_str(value, buff, &length)) ||
645
(result= find_type(&bool_typelib, str, length, 1)-1) < 0)
654
if (value->val_int(value, &tmp) < 0)
658
internal::llstr(tmp, buff);
664
*(int*)save= -result;
667
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
672
static int check_func_int(Session *session, drizzle_sys_var *var,
673
void *save, drizzle_value *value)
677
struct my_option options;
678
value->val_int(value, &tmp);
679
plugin_opt_set_limits(&options, var);
681
if (var->flags & PLUGIN_VAR_UNSIGNED)
682
*(uint32_t *)save= (uint32_t) getopt_ull_limit_value((uint64_t) tmp, &options,
685
*(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
687
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
688
var->name, (int64_t) tmp);
692
static int check_func_long(Session *session, drizzle_sys_var *var,
693
void *save, drizzle_value *value)
697
struct my_option options;
698
value->val_int(value, &tmp);
699
plugin_opt_set_limits(&options, var);
701
if (var->flags & PLUGIN_VAR_UNSIGNED)
702
*(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
705
*(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
707
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
708
var->name, (int64_t) tmp);
712
static int check_func_int64_t(Session *session, drizzle_sys_var *var,
713
void *save, drizzle_value *value)
717
struct my_option options;
718
value->val_int(value, &tmp);
719
plugin_opt_set_limits(&options, var);
721
if (var->flags & PLUGIN_VAR_UNSIGNED)
722
*(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
725
*(int64_t *)save= getopt_ll_limit_value(tmp, &options, &fixed);
727
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
728
var->name, (int64_t) tmp);
731
static int check_func_str(Session *session, drizzle_sys_var *,
732
void *save, drizzle_value *value)
734
char buff[STRING_BUFFER_USUAL_SIZE];
738
length= sizeof(buff);
739
if ((str= value->val_str(value, buff, &length)))
740
str= session->strmake(str, length);
741
*(const char**)save= str;
746
static void update_func_bool(Session *, drizzle_sys_var *,
747
void *tgt, const void *save)
749
*(bool *) tgt= *(int *) save ? 1 : 0;
753
static void update_func_int(Session *, drizzle_sys_var *,
754
void *tgt, const void *save)
756
*(int *)tgt= *(int *) save;
760
static void update_func_long(Session *, drizzle_sys_var *,
761
void *tgt, const void *save)
763
*(long *)tgt= *(long *) save;
767
static void update_func_int64_t(Session *, drizzle_sys_var *,
768
void *tgt, const void *save)
770
*(int64_t *)tgt= *(uint64_t *) save;
774
static void update_func_str(Session *, drizzle_sys_var *var,
775
void *tgt, const void *save)
777
char *old= *(char **) tgt;
778
*(char **)tgt= *(char **) save;
779
if (var->flags & PLUGIN_VAR_MEMALLOC)
781
*(char **)tgt= strdup(*(char **) save);
784
* There isn't a _really_ good thing to do here until this whole set_var
785
* mess gets redesigned
788
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
422
794
/****************************************************************************
423
795
System Variables support
424
796
****************************************************************************/
799
sys_var *find_sys_var(Session *, const char *str, uint32_t length)
802
sys_var_pluginvar *pi= NULL;
803
plugin::Module *module;
805
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
806
if ((var= intern_find_sys_var(str, length, false)) &&
807
(pi= var->cast_pluginvar()))
809
pthread_rwlock_unlock(&LOCK_system_variables_hash);
810
if (!(module= pi->plugin))
811
var= NULL; /* failed to lock it, it must be uninstalling */
812
else if (module->isInited == false)
818
pthread_rwlock_unlock(&LOCK_system_variables_hash);
821
If the variable exists but the plugin it is associated with is not ready
822
then the intern_plugin_lock did not raise an error, so we do it here.
825
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
829
static const string make_bookmark_name(const string &plugin, const char *name, int flags)
831
/* Embed the flags into the first char of the string */
832
string varname(1, static_cast<char>(flags & PLUGIN_VAR_TYPEMASK));
833
varname.append(plugin);
834
varname.push_back('_');
835
varname.append(name);
837
for (string::iterator p= varname.begin() + 1; p != varname.end(); ++p)
848
called by register_var, construct_options and test_plugin_options.
849
Returns the 'bookmark' for the named variable.
850
LOCK_system_variables_hash should be at least read locked
852
static st_bookmark *find_bookmark(const string &plugin, const char *name, int flags)
854
st_bookmark *result= NULL;
856
if (!(flags & PLUGIN_VAR_SessionLOCAL))
859
const string varname(make_bookmark_name(plugin, name, flags));
862
result= (st_bookmark*) hash_search(&bookmark_hash,
863
(const unsigned char*) varname.c_str(), varname.size() - 1);
870
returns a bookmark for session-local variables, creating if neccessary.
871
returns null for non session-local variables.
872
Requires that a write lock is obtained on LOCK_system_variables_hash
874
static st_bookmark *register_var(const string &plugin, const char *name,
877
if (!(flags & PLUGIN_VAR_SessionLOCAL))
880
uint32_t size= 0, offset, new_size;
883
switch (flags & PLUGIN_VAR_TYPEMASK) {
884
case PLUGIN_VAR_BOOL:
885
size= ALIGN_SIZE(sizeof(bool));
888
size= ALIGN_SIZE(sizeof(int));
890
case PLUGIN_VAR_LONG:
891
size= ALIGN_SIZE(sizeof(long));
893
case PLUGIN_VAR_LONGLONG:
894
size= ALIGN_SIZE(sizeof(uint64_t));
897
size= ALIGN_SIZE(sizeof(char*));
905
if (!(result= find_bookmark(plugin, name, flags)))
907
const string varname(make_bookmark_name(plugin, name, flags));
909
result= static_cast<st_bookmark*>(alloc_root(&plugin_mem_root,
910
sizeof(struct st_bookmark) + varname.size() + 1));
911
memset(result->key, 0, varname.size()+1);
912
memcpy(result->key, varname.c_str(), varname.size());
913
result->name_len= varname.size() - 2;
916
assert(size && !(size & (size-1))); /* must be power of 2 */
918
offset= global_system_variables.dynamic_variables_size;
919
offset= (offset + size - 1) & ~(size - 1);
920
result->offset= (int) offset;
922
new_size= (offset + size + 63) & ~63;
924
if (new_size > global_variables_dynamic_size)
928
(char *)realloc(global_system_variables.dynamic_variables_ptr,
931
global_system_variables.dynamic_variables_ptr= tmpptr;
934
(char *)realloc(max_system_variables.dynamic_variables_ptr,
937
max_system_variables.dynamic_variables_ptr= tmpptr;
940
Clear the new variable value space. This is required for string
941
variables. If their value is non-NULL, it must point to a valid
944
memset(global_system_variables.dynamic_variables_ptr +
945
global_variables_dynamic_size, 0,
946
new_size - global_variables_dynamic_size);
947
memset(max_system_variables.dynamic_variables_ptr +
948
global_variables_dynamic_size, 0,
949
new_size - global_variables_dynamic_size);
950
global_variables_dynamic_size= new_size;
953
global_system_variables.dynamic_variables_head= offset;
954
max_system_variables.dynamic_variables_head= offset;
955
global_system_variables.dynamic_variables_size= offset + size;
956
max_system_variables.dynamic_variables_size= offset + size;
957
global_system_variables.dynamic_variables_version++;
958
max_system_variables.dynamic_variables_version++;
960
result->version= global_system_variables.dynamic_variables_version;
962
/* this should succeed because we have already checked if a dup exists */
963
if (my_hash_insert(&bookmark_hash, (unsigned char*) result))
965
fprintf(stderr, "failed to add placeholder to hash");
974
returns a pointer to the memory which holds the session-local variable or
975
a pointer to the global variable if session==null.
976
If required, will sync with global variables if the requested variable
977
has not yet been allocated in the current thread.
979
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
982
assert((uint32_t)offset <= global_system_variables.dynamic_variables_head);
985
return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
988
dynamic_variables_head points to the largest valid offset
990
if (!session->variables.dynamic_variables_ptr ||
991
(uint32_t)offset > session->variables.dynamic_variables_head)
995
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
998
if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
999
global_variables_dynamic_size)))
1001
session->variables.dynamic_variables_ptr= tmpptr;
1004
pthread_mutex_lock(&LOCK_global_system_variables);
1006
//safe_mutex_assert_owner(&LOCK_global_system_variables);
1008
memcpy(session->variables.dynamic_variables_ptr +
1009
session->variables.dynamic_variables_size,
1010
global_system_variables.dynamic_variables_ptr +
1011
session->variables.dynamic_variables_size,
1012
global_system_variables.dynamic_variables_size -
1013
session->variables.dynamic_variables_size);
1016
now we need to iterate through any newly copied 'defaults'
1017
and if it is a string type with MEMALLOC flag, we need to strdup
1019
for (idx= 0; idx < bookmark_hash.records; idx++)
1021
sys_var_pluginvar *pi;
1023
st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
1025
if (v->version <= session->variables.dynamic_variables_version ||
1026
!(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
1027
!(pi= var->cast_pluginvar()) ||
1028
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
1031
/* Here we do anything special that may be required of the data types */
1033
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
1034
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
1036
char **pp= (char**) (session->variables.dynamic_variables_ptr +
1037
*(int*)(pi->plugin_var + 1));
1038
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
1039
*(int*)(pi->plugin_var + 1))))
1047
pthread_mutex_unlock(&LOCK_global_system_variables);
1049
session->variables.dynamic_variables_version=
1050
global_system_variables.dynamic_variables_version;
1051
session->variables.dynamic_variables_head=
1052
global_system_variables.dynamic_variables_head;
1053
session->variables.dynamic_variables_size=
1054
global_system_variables.dynamic_variables_size;
1056
pthread_rwlock_unlock(&LOCK_system_variables_hash);
1058
return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1061
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1063
return (bool *)intern_sys_var_ptr(a_session, offset, true);
1066
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1068
return (int *)intern_sys_var_ptr(a_session, offset, true);
1071
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1073
return (long *)intern_sys_var_ptr(a_session, offset, true);
1076
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1078
return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1081
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1083
return (char **)intern_sys_var_ptr(a_session, offset, true);
428
1086
void plugin_sessionvar_init(Session *session)
430
1088
session->variables.storage_engine= NULL;
431
cleanup_variables(&session->variables);
1089
cleanup_variables(session, &session->variables);
433
1091
session->variables= global_system_variables;
434
1092
session->variables.storage_engine= NULL;
471
1157
void plugin_sessionvar_cleanup(Session *session)
473
1159
unlock_variables(session, &session->variables);
474
cleanup_variables(&session->variables);
1160
cleanup_variables(session, &session->variables);
1165
@brief Free values of thread variables of a plugin.
1167
This must be called before a plugin is deleted. Otherwise its
1168
variables are no longer accessible and the value space is lost. Note
1169
that only string values with PLUGIN_VAR_MEMALLOC are allocated and
1172
@param[in] vars Chain of system variables of a plugin
1175
static void plugin_vars_free_values(sys_var *vars)
1178
for (sys_var *var= vars; var; var= var->getNext())
1180
sys_var_pluginvar *piv= var->cast_pluginvar();
1182
((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
1183
(piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
1185
/* Free the string from global_system_variables. */
1186
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
1195
bool sys_var_pluginvar::check_update_type(Item_result type)
1199
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1200
case PLUGIN_VAR_INT:
1201
case PLUGIN_VAR_LONG:
1202
case PLUGIN_VAR_LONGLONG:
1203
return type != INT_RESULT;
1204
case PLUGIN_VAR_STR:
1205
return type != STRING_RESULT;
1212
SHOW_TYPE sys_var_pluginvar::show_type()
1214
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1215
case PLUGIN_VAR_BOOL:
1216
return SHOW_MY_BOOL;
1217
case PLUGIN_VAR_INT:
1219
case PLUGIN_VAR_LONG:
1221
case PLUGIN_VAR_LONGLONG:
1222
return SHOW_LONGLONG;
1223
case PLUGIN_VAR_STR:
1224
return SHOW_CHAR_PTR;
1232
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, sql_var_t type)
1234
assert(session || (type == OPT_GLOBAL));
1235
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1237
if (type == OPT_GLOBAL)
1240
return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1242
return *(unsigned char**) (plugin_var+1);
1246
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
1248
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1249
case PLUGIN_VAR_SessionLOCAL:
1250
return ((sessionvar_enum_t *)plugin_var)->typelib;
1258
unsigned char* sys_var_pluginvar::value_ptr(Session *session, sql_var_t type, const LEX_STRING *)
1260
unsigned char* result;
1262
result= real_value_ptr(session, type);
1268
bool sys_var_pluginvar::check(Session *session, set_var *var)
1270
st_item_value_holder value;
1271
assert(is_readonly() || plugin_var->check);
1273
value.value_type= item_value_type;
1274
value.val_str= item_val_str;
1275
value.val_int= item_val_int;
1276
value.val_real= item_val_real;
1277
value.item= var->value;
1279
return is_readonly() ||
1280
plugin_var->check(session, plugin_var, &var->save_result, &value);
1284
void sys_var_pluginvar::set_default(Session *session, sql_var_t type)
1289
assert(is_readonly() || plugin_var->update);
1294
pthread_mutex_lock(&LOCK_global_system_variables);
1295
tgt= real_value_ptr(session, type);
1296
src= ((void **) (plugin_var + 1) + 1);
1298
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1300
if (type != OPT_GLOBAL)
1301
src= real_value_ptr(session, OPT_GLOBAL);
1303
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1304
case PLUGIN_VAR_INT:
1305
src= &((sessionvar_uint_t*) plugin_var)->def_val;
1307
case PLUGIN_VAR_LONG:
1308
src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1310
case PLUGIN_VAR_LONGLONG:
1311
src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1313
case PLUGIN_VAR_BOOL:
1314
src= &((sessionvar_bool_t*) plugin_var)->def_val;
1316
case PLUGIN_VAR_STR:
1317
src= &((sessionvar_str_t*) plugin_var)->def_val;
1324
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1325
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1326
session == current_session);
1328
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1330
plugin_var->update(session, plugin_var, tgt, src);
1331
pthread_mutex_unlock(&LOCK_global_system_variables);
1335
pthread_mutex_unlock(&LOCK_global_system_variables);
1336
plugin_var->update(session, plugin_var, tgt, src);
1341
bool sys_var_pluginvar::update(Session *session, set_var *var)
1345
assert(is_readonly() || plugin_var->update);
1347
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1348
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1349
session == current_session);
1354
pthread_mutex_lock(&LOCK_global_system_variables);
1355
tgt= real_value_ptr(session, var->type);
1357
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1359
/* variable we are updating has global scope, so we unlock after updating */
1360
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1361
pthread_mutex_unlock(&LOCK_global_system_variables);
1365
pthread_mutex_unlock(&LOCK_global_system_variables);
1366
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1372
#define OPTION_SET_LIMITS(type, options, opt) \
1373
options->var_type= type; \
1374
options->def_value= (opt)->def_val; \
1375
options->min_value= (opt)->min_val; \
1376
options->max_value= (opt)->max_val; \
1377
options->block_size= (long) (opt)->blk_sz
1380
void plugin_opt_set_limits(struct my_option *options,
1381
const drizzle_sys_var *opt)
1383
options->sub_size= 0;
1385
switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
1386
PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1387
/* global system variables */
1388
case PLUGIN_VAR_INT:
1389
OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
1391
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
1392
OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
1394
case PLUGIN_VAR_LONG:
1395
OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
1397
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
1398
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sysvar_ulong_t*) opt);
1400
case PLUGIN_VAR_LONGLONG:
1401
OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1403
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
1404
OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1406
case PLUGIN_VAR_BOOL:
1407
options->var_type= GET_BOOL;
1408
options->def_value= ((sysvar_bool_t*) opt)->def_val;
1410
case PLUGIN_VAR_STR:
1411
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1412
GET_STR_ALLOC : GET_STR);
1413
options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1415
/* threadlocal variables */
1416
case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
1417
OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1419
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1420
OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1422
case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
1423
OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1425
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1426
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sessionvar_ulong_t*) opt);
1428
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
1429
OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1431
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1432
OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1434
case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1435
options->var_type= GET_BOOL;
1436
options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1438
case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1439
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1440
GET_STR_ALLOC : GET_STR);
1441
options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1446
options->arg_type= REQUIRED_ARG;
1447
if (opt->flags & PLUGIN_VAR_NOCMDARG)
1448
options->arg_type= NO_ARG;
1449
if (opt->flags & PLUGIN_VAR_OPCMDARG)
1450
options->arg_type= OPT_ARG;
1453
static bool get_one_plugin_option(int, const struct my_option *, char *)
1459
static int construct_options(memory::Root *mem_root, plugin::Module *tmp,
1463
int localoptionid= 256;
1464
const string plugin_name(tmp->getManifest().name);
1466
size_t namelen= plugin_name.size(), optnamelen;
1469
int index= 0, offset= 0;
1470
drizzle_sys_var *opt, **plugin_option;
1473
string name(plugin_name);
1474
transform(name.begin(), name.end(), name.begin(), ::tolower);
1476
for (string::iterator iter= name.begin(); iter != name.end(); ++iter)
1483
Two passes as the 2nd pass will take pointer addresses for use
1484
by my_getopt and register_var() in the first pass uses realloc
1487
for (plugin_option= tmp->getManifest().system_vars;
1488
plugin_option && *plugin_option; plugin_option++, index++)
1490
opt= *plugin_option;
1491
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1493
if (!(register_var(name, opt->name, opt->flags)))
1495
switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
1496
case PLUGIN_VAR_BOOL:
1497
(((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1499
case PLUGIN_VAR_INT:
1500
(((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1502
case PLUGIN_VAR_LONG:
1503
(((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1505
case PLUGIN_VAR_LONGLONG:
1506
(((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1508
case PLUGIN_VAR_STR:
1509
(((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1512
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1513
opt->flags, plugin_name.c_str());
1518
for (plugin_option= tmp->getManifest().system_vars;
1519
plugin_option && *plugin_option; plugin_option++, index++)
1521
switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
1522
case PLUGIN_VAR_BOOL:
1524
opt->check= check_func_bool;
1526
opt->update= update_func_bool;
1528
case PLUGIN_VAR_INT:
1530
opt->check= check_func_int;
1532
opt->update= update_func_int;
1534
case PLUGIN_VAR_LONG:
1536
opt->check= check_func_long;
1538
opt->update= update_func_long;
1540
case PLUGIN_VAR_LONGLONG:
1542
opt->check= check_func_int64_t;
1544
opt->update= update_func_int64_t;
1546
case PLUGIN_VAR_STR:
1548
opt->check= check_func_str;
1551
opt->update= update_func_str;
1552
if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1554
opt->flags|= PLUGIN_VAR_READONLY;
1555
errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1556
"to be read-only: string variable without "
1557
"update_func and PLUGIN_VAR_MEMALLOC flag"),
1558
opt->name, plugin_name.c_str());
1563
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1564
opt->flags, plugin_name.c_str());
1568
if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1569
== PLUGIN_VAR_NOCMDOPT)
1574
errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1575
plugin_name.c_str());
1579
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1581
optnamelen= strlen(opt->name);
1582
optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
1583
sprintf(optname, "%s-%s", name.c_str(), opt->name);
1584
optnamelen= namelen + optnamelen + 1;
1588
/* this should not fail because register_var should create entry */
1589
if (!(v= find_bookmark(name, opt->name, opt->flags)))
1591
errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
1592
"in plugin '%s'."), opt->name, plugin_name.c_str());
1596
*(int*)(opt + 1)= offset= v->offset;
1598
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
1601
optname= (char*) memdup_root(mem_root, v->key + 1,
1602
(optnamelen= v->name_len) + 1);
1605
/* convert '_' to '-' */
1606
for (p= optname; *p; p++)
1610
options->name= optname;
1611
options->comment= opt->comment;
1612
options->app_type= opt;
1613
options->id= localoptionid++;
1615
plugin_opt_set_limits(options, opt);
1617
if (opt->flags & PLUGIN_VAR_SessionLOCAL)
1618
options->value= options->u_max_value= (char**)
1619
(global_system_variables.dynamic_variables_ptr + offset);
1621
options->value= options->u_max_value= *(char***) (opt + 1);
1630
static my_option *construct_help_options(memory::Root *mem_root, plugin::Module *p)
1632
drizzle_sys_var **opt;
1634
uint32_t count= EXTRA_OPTIONS;
1636
for (opt= p->getManifest().system_vars; opt && *opt; opt++, count++) {};
1638
opts= (my_option*)alloc_root(mem_root, (sizeof(my_option) * count));
1642
memset(opts, 0, sizeof(my_option) * count);
1644
if (construct_options(mem_root, p, opts))
1650
void drizzle_add_plugin_sysvar(sys_var_pluginvar *var)
1652
plugin_sysvar_vec.push_back(var);
1655
void drizzle_del_plugin_sysvar()
1657
vector<sys_var_pluginvar *>::iterator iter= plugin_sysvar_vec.begin();
1658
while(iter != plugin_sysvar_vec.end())
1663
plugin_sysvar_vec.clear();
481
1668
test_plugin_options()
482
1669
tmp_root temporary scratch space
483
1670
plugin internal plugin structure
1671
argc user supplied arguments
1672
argv user supplied arguments
484
1673
default_enabled default plugin enable status
486
1675
0 SUCCESS - plugin should be enabled/loaded
488
1677
Requires that a write-lock is held on LOCK_system_variables_hash
490
static int test_plugin_options(memory::Root *,
491
module::Module *test_module,
492
po::options_description &long_options)
1679
static int test_plugin_options(memory::Root *tmp_root, plugin::Module *tmp,
1680
int *argc, char **argv)
495
if (test_module->getManifest().init_options != NULL)
497
string plugin_section_title("Options used by ");
498
plugin_section_title.append(test_module->getName());
499
po::options_description module_options(plugin_section_title);
500
module::option_context opt_ctx(test_module->getName(),
501
module_options.add_options());
502
test_module->getManifest().init_options(opt_ctx);
503
long_options.add(module_options);
1682
struct sys_var_chain chain= { NULL, NULL };
1683
drizzle_sys_var **opt;
1684
my_option *opts= NULL;
1687
struct st_bookmark *var;
1688
uint32_t len, count= EXTRA_OPTIONS;
1690
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
1694
if (count > EXTRA_OPTIONS || (*argc > 1))
1696
if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
1698
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory for plugin '%s'."), tmp->getName().c_str());
1701
memset(opts, 0, sizeof(my_option) * count);
1703
if (construct_options(tmp_root, tmp, opts))
1705
errmsg_printf(ERRMSG_LVL_ERROR, _("Bad options for plugin '%s'."), tmp->getName().c_str());
1709
error= handle_options(argc, &argv, opts, get_one_plugin_option);
1710
(*argc)++; /* add back one for the program name */
1714
errmsg_printf(ERRMSG_LVL_ERROR, _("Parsing options for plugin '%s' failed."),
1715
tmp->getName().c_str());
1723
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
1726
if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
1729
if ((var= find_bookmark(tmp->getName(), o->name, o->flags)))
1730
v= new sys_var_pluginvar(var->key + 1, o);
1733
len= tmp->getName().length() + strlen(o->name) + 2;
1734
string vname(tmp->getName());
1735
vname.push_back('-');
1736
vname.append(o->name);
1737
transform(vname.begin(), vname.end(), vname.begin(), ::tolower);
1738
string::iterator p= vname.begin();
1739
while (p != vname.end())
1746
v= new sys_var_pluginvar(vname, o);
1748
assert(v); /* check that an object was actually constructed */
1750
drizzle_add_plugin_sysvar(static_cast<sys_var_pluginvar *>(v));
1752
Add to the chain of variables.
1753
Done like this for easier debugging so that the
1754
pointer to v is not lost on optimized builds.
1756
v->chain_sys_var(&chain);
1760
chain.last->setNext(NULL);
1761
if (mysql_add_sys_var_chain(chain.first, NULL))
1763
errmsg_printf(ERRMSG_LVL_ERROR, _("Plugin '%s' has conflicting system variables"),
1764
tmp->getName().c_str());
1767
tmp->system_vars= chain.first;
1774
my_cleanup_options(opts);