127
124
static bookmark_unordered_map bookmark_hash;
128
sys_var class for access to all plugin variables visible to the user
130
class sys_var_pluginvar: public sys_var
133
module::Module *plugin;
134
drizzle_sys_var *plugin_var;
136
sys_var_pluginvar(const std::string name_arg,
137
drizzle_sys_var *plugin_var_arg)
138
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
139
sys_var_pluginvar *cast_pluginvar() { return this; }
140
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
141
bool check_type(sql_var_t type)
142
{ return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
143
bool check_update_type(Item_result type);
144
SHOW_TYPE show_type();
145
unsigned char* real_value_ptr(Session *session, sql_var_t type);
146
TYPELIB* plugin_var_typelib(void);
147
unsigned char* value_ptr(Session *session, sql_var_t type,
148
const LEX_STRING *base);
149
bool check(Session *session, set_var *var);
150
bool check_default(sql_var_t)
151
{ return is_readonly(); }
152
void set_default(Session *session, sql_var_t);
153
bool update(Session *session, set_var *var);
132
158
static void plugin_prune_list(vector<string> &plugin_list,
133
159
const vector<string> &plugins_to_remove);
134
160
static bool plugin_load_list(module::Registry ®istry,
135
memory::Root *tmp_root,
161
memory::Root *tmp_root, int *argc, char **argv,
136
162
const set<string> &plugin_list,
137
163
po::options_description &long_options,
138
164
bool builtin= false);
139
165
static int test_plugin_options(memory::Root *, module::Module *,
140
167
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);
168
static void unlock_variables(Session *session, struct system_variables *vars);
169
static void cleanup_variables(Session *session, struct system_variables *vars);
170
static void plugin_vars_free_values(sys_var *vars);
144
172
/* declared in set_var.cc */
145
173
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
174
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
175
const std::string &name, int64_t val);
177
static bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
178
const char *name, int64_t val)
180
const std::string name_str(name);
181
return throw_bounds_warning(session, fixed, unsignd, name_str, val);
184
/****************************************************************************
185
Value type thunks, allows the C world to play in the C++ world
186
****************************************************************************/
188
static int item_value_type(drizzle_value *value)
190
switch (((st_item_value_holder*)value)->item->result_type()) {
192
return DRIZZLE_VALUE_TYPE_INT;
194
return DRIZZLE_VALUE_TYPE_REAL;
196
return DRIZZLE_VALUE_TYPE_STRING;
200
static const char *item_val_str(drizzle_value *value,
201
char *buffer, int *length)
203
String str(buffer, *length, system_charset_info), *res;
204
if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
206
*length= res->length();
207
if (res->c_ptr_quick() == buffer)
211
Lets be nice and create a temporary string since the
214
return current_session->strmake(res->c_ptr_quick(), res->length());
218
static int item_val_int(drizzle_value *value, int64_t *buf)
220
Item *item= ((st_item_value_holder*)value)->item;
221
*buf= item->val_int();
228
static int item_val_real(drizzle_value *value, double *buf)
230
Item *item= ((st_item_value_holder*)value)->item;
231
*buf= item->val_real();
148
238
/****************************************************************************
494
551
global_variables_dynamic_size= 0;
554
/****************************************************************************
555
Internal type declarations for variables support
556
****************************************************************************/
558
#undef DRIZZLE_SYSVAR_NAME
559
#define DRIZZLE_SYSVAR_NAME(name) name
560
#define PLUGIN_VAR_TYPEMASK 0x007f
562
static const uint32_t EXTRA_OPTIONS= 1; /* handle the NULL option */
564
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
565
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
566
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
567
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
569
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
570
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_set_t, uint64_t);
572
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
573
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
574
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
575
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
576
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
577
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
579
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int_t, int);
580
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_long_t, long);
581
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int64_t_t, int64_t);
582
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint_t, uint);
583
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_ulong_t, ulong);
584
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint64_t_t, uint64_t);
586
typedef bool *(*mysql_sys_var_ptr_p)(Session* a_session, int offset);
589
/****************************************************************************
590
default variable data check and update functions
591
****************************************************************************/
593
static int check_func_bool(Session *, drizzle_sys_var *var,
594
void *save, drizzle_value *value)
596
char buff[STRING_BUFFER_USUAL_SIZE];
597
const char *strvalue= "NULL", *str;
601
if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
603
length= sizeof(buff);
604
if (!(str= value->val_str(value, buff, &length)) ||
605
(result= find_type(&bool_typelib, str, length, 1)-1) < 0)
614
if (value->val_int(value, &tmp) < 0)
618
internal::llstr(tmp, buff);
624
*(int*)save= -result;
627
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
632
static int check_func_int(Session *session, drizzle_sys_var *var,
633
void *save, drizzle_value *value)
637
struct option options;
638
value->val_int(value, &tmp);
639
plugin_opt_set_limits(&options, var);
641
if (var->flags & PLUGIN_VAR_UNSIGNED)
642
*(uint32_t *)save= (uint32_t) getopt_ull_limit_value((uint64_t) tmp, &options,
645
*(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
647
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
648
var->name, (int64_t) tmp);
652
static int check_func_long(Session *session, drizzle_sys_var *var,
653
void *save, drizzle_value *value)
657
struct option options;
658
value->val_int(value, &tmp);
659
plugin_opt_set_limits(&options, var);
661
if (var->flags & PLUGIN_VAR_UNSIGNED)
662
*(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
665
*(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
667
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
668
var->name, (int64_t) tmp);
672
static int check_func_int64_t(Session *session, drizzle_sys_var *var,
673
void *save, drizzle_value *value)
677
struct option options;
678
value->val_int(value, &tmp);
679
plugin_opt_set_limits(&options, var);
681
if (var->flags & PLUGIN_VAR_UNSIGNED)
682
*(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
685
*(int64_t *)save= 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);
691
static int check_func_str(Session *session, drizzle_sys_var *,
692
void *save, drizzle_value *value)
694
char buff[STRING_BUFFER_USUAL_SIZE];
698
length= sizeof(buff);
699
if ((str= value->val_str(value, buff, &length)))
700
str= session->strmake(str, length);
701
*(const char**)save= str;
706
static void update_func_bool(Session *, drizzle_sys_var *,
707
void *tgt, const void *save)
709
*(bool *) tgt= *(int *) save ? 1 : 0;
713
static void update_func_int(Session *, drizzle_sys_var *,
714
void *tgt, const void *save)
716
*(int *)tgt= *(int *) save;
720
static void update_func_long(Session *, drizzle_sys_var *,
721
void *tgt, const void *save)
723
*(long *)tgt= *(long *) save;
727
static void update_func_int64_t(Session *, drizzle_sys_var *,
728
void *tgt, const void *save)
730
*(int64_t *)tgt= *(uint64_t *) save;
734
static void update_func_str(Session *, drizzle_sys_var *var,
735
void *tgt, const void *save)
737
char *old= *(char **) tgt;
738
*(char **)tgt= *(char **) save;
739
if (var->flags & PLUGIN_VAR_MEMALLOC)
741
*(char **)tgt= strdup(*(char **) save);
744
* There isn't a _really_ good thing to do here until this whole set_var
745
* mess gets redesigned
748
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
498
754
/****************************************************************************
499
755
System Variables support
500
756
****************************************************************************/
503
sys_var *find_sys_var(const char *str, uint32_t length)
505
return intern_find_sys_var(str, length, false);
759
sys_var *find_sys_var(Session *, const char *str, uint32_t length)
762
sys_var_pluginvar *pi= NULL;
763
module::Module *module;
765
if ((var= intern_find_sys_var(str, length, false)) &&
766
(pi= var->cast_pluginvar()))
768
if (!(module= pi->plugin))
769
var= NULL; /* failed to lock it, it must be uninstalling */
770
else if (module->isInited == false)
777
If the variable exists but the plugin it is associated with is not ready
778
then the intern_plugin_lock did not raise an error, so we do it here.
781
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
785
static const string make_bookmark_name(const string &plugin, const char *name)
787
string varname(plugin);
788
varname.push_back('_');
789
varname.append(name);
791
for (string::iterator p= varname.begin() + 1; p != varname.end(); ++p)
802
called by register_var, construct_options and test_plugin_options.
803
Returns the 'bookmark' for the named variable.
804
LOCK_system_variables_hash should be at least read locked
806
static Bookmark *find_bookmark(const string &plugin, const char *name, int flags)
808
if (!(flags & PLUGIN_VAR_SessionLOCAL))
811
const string varname(make_bookmark_name(plugin, name));
813
bookmark_unordered_map::iterator iter= bookmark_hash.find(varname);
814
if (iter != bookmark_hash.end())
816
return &((*iter).second);
823
returns a bookmark for session-local variables, creating if neccessary.
824
returns null for non session-local variables.
825
Requires that a write lock is obtained on LOCK_system_variables_hash
827
static Bookmark *register_var(const string &plugin, const char *name,
830
if (!(flags & PLUGIN_VAR_SessionLOCAL))
833
uint32_t size= 0, offset, new_size;
834
Bookmark *result= NULL;
836
switch (flags & PLUGIN_VAR_TYPEMASK) {
837
case PLUGIN_VAR_BOOL:
838
size= ALIGN_SIZE(sizeof(bool));
841
size= ALIGN_SIZE(sizeof(int));
843
case PLUGIN_VAR_LONG:
844
size= ALIGN_SIZE(sizeof(long));
846
case PLUGIN_VAR_LONGLONG:
847
size= ALIGN_SIZE(sizeof(uint64_t));
850
size= ALIGN_SIZE(sizeof(char*));
858
if (!(result= find_bookmark(plugin, name, flags)))
860
const string varname(make_bookmark_name(plugin, name));
862
Bookmark new_bookmark;
863
new_bookmark.key= varname;
864
new_bookmark.offset= -1;
866
assert(size && !(size & (size-1))); /* must be power of 2 */
868
offset= global_system_variables.dynamic_variables_size;
869
offset= (offset + size - 1) & ~(size - 1);
870
new_bookmark.offset= (int) offset;
872
new_size= (offset + size + 63) & ~63;
874
if (new_size > global_variables_dynamic_size)
878
(char *)realloc(global_system_variables.dynamic_variables_ptr,
881
global_system_variables.dynamic_variables_ptr= tmpptr;
884
(char *)realloc(max_system_variables.dynamic_variables_ptr,
887
max_system_variables.dynamic_variables_ptr= tmpptr;
890
Clear the new variable value space. This is required for string
891
variables. If their value is non-NULL, it must point to a valid
894
memset(global_system_variables.dynamic_variables_ptr +
895
global_variables_dynamic_size, 0,
896
new_size - global_variables_dynamic_size);
897
memset(max_system_variables.dynamic_variables_ptr +
898
global_variables_dynamic_size, 0,
899
new_size - global_variables_dynamic_size);
900
global_variables_dynamic_size= new_size;
903
global_system_variables.dynamic_variables_head= offset;
904
max_system_variables.dynamic_variables_head= offset;
905
global_system_variables.dynamic_variables_size= offset + size;
906
max_system_variables.dynamic_variables_size= offset + size;
907
global_system_variables.dynamic_variables_version++;
908
max_system_variables.dynamic_variables_version++;
910
new_bookmark.version= global_system_variables.dynamic_variables_version;
911
new_bookmark.type_code= flags;
913
/* this should succeed because we have already checked if a dup exists */
914
bookmark_hash.insert(make_pair(varname, new_bookmark));
915
result= find_bookmark(plugin, name, flags);
922
returns a pointer to the memory which holds the session-local variable or
923
a pointer to the global variable if session==null.
924
If required, will sync with global variables if the requested variable
925
has not yet been allocated in the current thread.
927
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
930
assert((uint32_t)offset <= global_system_variables.dynamic_variables_head);
933
return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
936
dynamic_variables_head points to the largest valid offset
938
if (!session->variables.dynamic_variables_ptr ||
939
(uint32_t)offset > session->variables.dynamic_variables_head)
942
if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
943
global_variables_dynamic_size)))
945
session->variables.dynamic_variables_ptr= tmpptr;
948
LOCK_global_system_variables.lock();
950
//safe_mutex_assert_owner(&LOCK_global_system_variables);
952
memcpy(session->variables.dynamic_variables_ptr +
953
session->variables.dynamic_variables_size,
954
global_system_variables.dynamic_variables_ptr +
955
session->variables.dynamic_variables_size,
956
global_system_variables.dynamic_variables_size -
957
session->variables.dynamic_variables_size);
960
now we need to iterate through any newly copied 'defaults'
961
and if it is a string type with MEMALLOC flag, we need to strdup
963
bookmark_unordered_map::iterator iter= bookmark_hash.begin();
964
for (; iter != bookmark_hash.end() ; ++iter)
966
sys_var_pluginvar *pi;
968
const Bookmark &v= (*iter).second;
969
const string var_name((*iter).first);
971
if (v.version <= session->variables.dynamic_variables_version ||
972
!(var= intern_find_sys_var(var_name.c_str(), var_name.size(), true)) ||
973
!(pi= var->cast_pluginvar()) ||
974
v.type_code != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
977
/* Here we do anything special that may be required of the data types */
979
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
980
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
982
char **pp= (char**) (session->variables.dynamic_variables_ptr +
983
*(int*)(pi->plugin_var + 1));
984
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
985
*(int*)(pi->plugin_var + 1))))
993
LOCK_global_system_variables.unlock();
995
session->variables.dynamic_variables_version=
996
global_system_variables.dynamic_variables_version;
997
session->variables.dynamic_variables_head=
998
global_system_variables.dynamic_variables_head;
999
session->variables.dynamic_variables_size=
1000
global_system_variables.dynamic_variables_size;
1002
return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1005
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1007
return (bool *)intern_sys_var_ptr(a_session, offset, true);
1010
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1012
return (int *)intern_sys_var_ptr(a_session, offset, true);
1015
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1017
return (long *)intern_sys_var_ptr(a_session, offset, true);
1020
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1022
return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1025
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1027
return (char **)intern_sys_var_ptr(a_session, offset, true);
509
1030
void plugin_sessionvar_init(Session *session)
511
1032
session->variables.storage_engine= NULL;
512
cleanup_variables(&session->variables);
1033
cleanup_variables(session, &session->variables);
514
1035
session->variables= global_system_variables;
515
1036
session->variables.storage_engine= NULL;
552
1099
void plugin_sessionvar_cleanup(Session *session)
554
1101
unlock_variables(session, &session->variables);
555
cleanup_variables(&session->variables);
1102
cleanup_variables(session, &session->variables);
1107
@brief Free values of thread variables of a plugin.
1109
This must be called before a plugin is deleted. Otherwise its
1110
variables are no longer accessible and the value space is lost. Note
1111
that only string values with PLUGIN_VAR_MEMALLOC are allocated and
1114
@param[in] vars Chain of system variables of a plugin
1117
static void plugin_vars_free_values(sys_var *vars)
1120
for (sys_var *var= vars; var; var= var->getNext())
1122
sys_var_pluginvar *piv= var->cast_pluginvar();
1124
((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
1125
(piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
1127
/* Free the string from global_system_variables. */
1128
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
1137
bool sys_var_pluginvar::check_update_type(Item_result type)
1141
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1142
case PLUGIN_VAR_INT:
1143
case PLUGIN_VAR_LONG:
1144
case PLUGIN_VAR_LONGLONG:
1145
return type != INT_RESULT;
1146
case PLUGIN_VAR_STR:
1147
return type != STRING_RESULT;
1154
SHOW_TYPE sys_var_pluginvar::show_type()
1156
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1157
case PLUGIN_VAR_BOOL:
1158
return SHOW_MY_BOOL;
1159
case PLUGIN_VAR_INT:
1161
case PLUGIN_VAR_LONG:
1163
case PLUGIN_VAR_LONGLONG:
1164
return SHOW_LONGLONG;
1165
case PLUGIN_VAR_STR:
1166
return SHOW_CHAR_PTR;
1174
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, sql_var_t type)
1176
assert(session || (type == OPT_GLOBAL));
1177
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1179
if (type == OPT_GLOBAL)
1182
return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1184
return *(unsigned char**) (plugin_var+1);
1188
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
1190
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1191
case PLUGIN_VAR_SessionLOCAL:
1192
return ((sessionvar_enum_t *)plugin_var)->typelib;
1200
unsigned char* sys_var_pluginvar::value_ptr(Session *session, sql_var_t type, const LEX_STRING *)
1202
unsigned char* result;
1204
result= real_value_ptr(session, type);
1210
bool sys_var_pluginvar::check(Session *session, set_var *var)
1212
st_item_value_holder value;
1213
assert(is_readonly() || plugin_var->check);
1215
value.value_type= item_value_type;
1216
value.val_str= item_val_str;
1217
value.val_int= item_val_int;
1218
value.val_real= item_val_real;
1219
value.item= var->value;
1221
return is_readonly() ||
1222
plugin_var->check(session, plugin_var, &var->save_result, &value);
1226
void sys_var_pluginvar::set_default(Session *session, sql_var_t type)
1231
assert(is_readonly() || plugin_var->update);
1236
LOCK_global_system_variables.lock();
1237
tgt= real_value_ptr(session, type);
1238
src= ((void **) (plugin_var + 1) + 1);
1240
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1242
if (type != OPT_GLOBAL)
1243
src= real_value_ptr(session, OPT_GLOBAL);
1245
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1246
case PLUGIN_VAR_INT:
1247
src= &((sessionvar_uint_t*) plugin_var)->def_val;
1249
case PLUGIN_VAR_LONG:
1250
src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1252
case PLUGIN_VAR_LONGLONG:
1253
src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1255
case PLUGIN_VAR_BOOL:
1256
src= &((sessionvar_bool_t*) plugin_var)->def_val;
1258
case PLUGIN_VAR_STR:
1259
src= &((sessionvar_str_t*) plugin_var)->def_val;
1266
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1267
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1268
session == current_session);
1270
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1272
plugin_var->update(session, plugin_var, tgt, src);
1273
LOCK_global_system_variables.unlock();
1277
LOCK_global_system_variables.unlock();
1278
plugin_var->update(session, plugin_var, tgt, src);
1283
bool sys_var_pluginvar::update(Session *session, set_var *var)
1287
assert(is_readonly() || plugin_var->update);
1289
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1290
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1291
session == current_session);
1296
LOCK_global_system_variables.lock();
1297
tgt= real_value_ptr(session, var->type);
1299
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1301
/* variable we are updating has global scope, so we unlock after updating */
1302
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1303
LOCK_global_system_variables.unlock();
1307
LOCK_global_system_variables.unlock();
1308
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1314
#define OPTION_SET_LIMITS(type, options, opt) \
1315
options->var_type= type; \
1316
options->def_value= (opt)->def_val; \
1317
options->min_value= (opt)->min_val; \
1318
options->max_value= (opt)->max_val; \
1319
options->block_size= (long) (opt)->blk_sz
1322
void plugin_opt_set_limits(struct option *options,
1323
const drizzle_sys_var *opt)
1325
options->sub_size= 0;
1327
switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
1328
PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1329
/* global system variables */
1330
case PLUGIN_VAR_INT:
1331
OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
1333
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
1334
OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
1336
case PLUGIN_VAR_LONG:
1337
OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
1339
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
1340
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sysvar_ulong_t*) opt);
1342
case PLUGIN_VAR_LONGLONG:
1343
OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1345
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
1346
OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1348
case PLUGIN_VAR_BOOL:
1349
options->var_type= GET_BOOL;
1350
options->def_value= ((sysvar_bool_t*) opt)->def_val;
1352
case PLUGIN_VAR_STR:
1353
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1354
GET_STR_ALLOC : GET_STR);
1355
options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1357
/* threadlocal variables */
1358
case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
1359
OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1361
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1362
OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1364
case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
1365
OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1367
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1368
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sessionvar_ulong_t*) opt);
1370
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
1371
OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1373
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1374
OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1376
case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1377
options->var_type= GET_BOOL;
1378
options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1380
case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1381
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1382
GET_STR_ALLOC : GET_STR);
1383
options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1388
options->arg_type= REQUIRED_ARG;
1389
if (opt->flags & PLUGIN_VAR_NOCMDARG)
1390
options->arg_type= NO_ARG;
1391
if (opt->flags & PLUGIN_VAR_OPCMDARG)
1392
options->arg_type= OPT_ARG;
1395
static int get_one_plugin_option(int, const struct option *, char *)
1401
static int construct_options(memory::Root *mem_root, module::Module *tmp,
1405
int localoptionid= 256;
1406
const string plugin_name(tmp->getManifest().name);
1408
size_t namelen= plugin_name.size(), optnamelen;
1411
int index= 0, offset= 0;
1412
drizzle_sys_var *opt, **plugin_option;
1415
string name(plugin_name);
1416
transform(name.begin(), name.end(), name.begin(), ::tolower);
1418
for (string::iterator iter= name.begin(); iter != name.end(); ++iter)
1425
Two passes as the 2nd pass will take pointer addresses for use
1426
by my_getopt and register_var() in the first pass uses realloc
1429
for (plugin_option= tmp->getManifest().system_vars;
1430
plugin_option && *plugin_option; plugin_option++, index++)
1432
opt= *plugin_option;
1433
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1435
if (!(register_var(name, opt->name, opt->flags)))
1437
switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
1438
case PLUGIN_VAR_BOOL:
1439
(((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1441
case PLUGIN_VAR_INT:
1442
(((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1444
case PLUGIN_VAR_LONG:
1445
(((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1447
case PLUGIN_VAR_LONGLONG:
1448
(((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1450
case PLUGIN_VAR_STR:
1451
(((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1454
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1455
opt->flags, plugin_name.c_str());
1460
for (plugin_option= tmp->getManifest().system_vars;
1461
plugin_option && *plugin_option; plugin_option++, index++)
1463
switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
1464
case PLUGIN_VAR_BOOL:
1466
opt->check= check_func_bool;
1468
opt->update= update_func_bool;
1470
case PLUGIN_VAR_INT:
1472
opt->check= check_func_int;
1474
opt->update= update_func_int;
1476
case PLUGIN_VAR_LONG:
1478
opt->check= check_func_long;
1480
opt->update= update_func_long;
1482
case PLUGIN_VAR_LONGLONG:
1484
opt->check= check_func_int64_t;
1486
opt->update= update_func_int64_t;
1488
case PLUGIN_VAR_STR:
1490
opt->check= check_func_str;
1493
opt->update= update_func_str;
1494
if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1496
opt->flags|= PLUGIN_VAR_READONLY;
1497
errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1498
"to be read-only: string variable without "
1499
"update_func and PLUGIN_VAR_MEMALLOC flag"),
1500
opt->name, plugin_name.c_str());
1505
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1506
opt->flags, plugin_name.c_str());
1510
if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1511
== PLUGIN_VAR_NOCMDOPT)
1516
errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1517
plugin_name.c_str());
1521
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1523
optnamelen= strlen(opt->name);
1524
optname= (char*) mem_root->alloc_root(namelen + optnamelen + 2);
1525
sprintf(optname, "%s-%s", name.c_str(), opt->name);
1526
optnamelen= namelen + optnamelen + 1;
1530
/* this should not fail because register_var should create entry */
1531
if (!(v= find_bookmark(name, opt->name, opt->flags)))
1533
errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
1534
"in plugin '%s'."), opt->name, plugin_name.c_str());
1538
*(int*)(opt + 1)= offset= v->offset;
1540
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
1543
optname= (char*) mem_root->memdup_root(v->key.c_str(), (optnamelen= v->key.size()) + 1);
1546
/* convert '_' to '-' */
1547
for (p= optname; *p; p++)
1551
options->name= optname;
1552
options->comment= opt->comment;
1553
options->app_type= opt;
1554
options->id= localoptionid++;
1556
plugin_opt_set_limits(options, opt);
1558
if (opt->flags & PLUGIN_VAR_SessionLOCAL)
1559
options->value= options->u_max_value= (char**)
1560
(global_system_variables.dynamic_variables_ptr + offset);
1562
options->value= options->u_max_value= *(char***) (opt + 1);
1571
static option *construct_help_options(memory::Root *mem_root, module::Module *p)
1573
drizzle_sys_var **opt;
1575
uint32_t count= EXTRA_OPTIONS;
1577
for (opt= p->getManifest().system_vars; opt && *opt; opt++, count++) {};
1579
opts= (option*)mem_root->alloc_root((sizeof(option) * count));
1583
memset(opts, 0, sizeof(option) * count);
1585
if (construct_options(mem_root, p, opts))
1591
void drizzle_add_plugin_sysvar(sys_var_pluginvar *var)
1593
plugin_sysvar_vec.push_back(var);
1596
void drizzle_del_plugin_sysvar()
1598
vector<sys_var_pluginvar *>::iterator iter= plugin_sysvar_vec.begin();
1599
while(iter != plugin_sysvar_vec.end())
1604
plugin_sysvar_vec.clear();
562
1609
test_plugin_options()
563
1610
tmp_root temporary scratch space
564
1611
plugin internal plugin structure
1612
argc user supplied arguments
1613
argv user supplied arguments
565
1614
default_enabled default plugin enable status
567
1616
0 SUCCESS - plugin should be enabled/loaded
569
1618
Requires that a write-lock is held on LOCK_system_variables_hash
571
static int test_plugin_options(memory::Root *,
1620
static int test_plugin_options(memory::Root *module_root,
572
1621
module::Module *test_module,
1622
int *argc, char **argv,
573
1623
po::options_description &long_options)
1625
struct sys_var_chain chain= { NULL, NULL };
1626
drizzle_sys_var **opt;
1631
uint32_t len, count= EXTRA_OPTIONS;
576
1633
if (test_module->getManifest().init_options != NULL)