summaryrefslogtreecommitdiff
path: root/sql/sql_plugin.cc
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
commitd95c1e3b470506c7df6dfce3fe6dc7e5b46930ee (patch)
tree9f13d4fcc3ac732dc94fe2cae446f6f8c2b4e02b /sql/sql_plugin.cc
parentabc6846d5b1df4846c4ffc03f4c93c82f874dd96 (diff)
parentae715642f46d4ed9ea8b5dd9b5cc9f3cace7f437 (diff)
downloadmariadb-git-d95c1e3b470506c7df6dfce3fe6dc7e5b46930ee.tar.gz
Manual merge of mysql-trunk into mysql-trunk-merge.
Conflicts: Text conflict in client/mysqlbinlog.cc Text conflict in mysql-test/Makefile.am Text conflict in mysql-test/collections/default.daily Text conflict in mysql-test/r/mysqlbinlog_row_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_typeconv_innodb.result Text conflict in mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test Text conflict in mysql-test/suite/rpl/t/rpl_row_create_table.test Text conflict in mysql-test/suite/rpl/t/rpl_slave_skip.test Text conflict in mysql-test/suite/rpl/t/rpl_typeconv_innodb.test Text conflict in mysys/charset.c Text conflict in sql/field.cc Text conflict in sql/field.h Text conflict in sql/item.h Text conflict in sql/item_func.cc Text conflict in sql/log.cc Text conflict in sql/log_event.cc Text conflict in sql/log_event_old.cc Text conflict in sql/mysqld.cc Text conflict in sql/rpl_utility.cc Text conflict in sql/rpl_utility.h Text conflict in sql/set_var.cc Text conflict in sql/share/Makefile.am Text conflict in sql/sql_delete.cc Text conflict in sql/sql_plugin.cc Text conflict in sql/sql_select.cc Text conflict in sql/sql_table.cc Text conflict in storage/example/ha_example.h Text conflict in storage/federated/ha_federated.cc Text conflict in storage/myisammrg/ha_myisammrg.cc Text conflict in storage/myisammrg/myrg_open.c
Diffstat (limited to 'sql/sql_plugin.cc')
-rw-r--r--sql/sql_plugin.cc939
1 files changed, 484 insertions, 455 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index c15cc6df4f5..3ff5e91ccb6 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -13,13 +13,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mysql_priv.h"
+#include "sys_vars_shared.h"
#include <my_pthread.h>
#include <my_getopt.h>
+#include <mysql/plugin_audit.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_mysql_plugin *mysql_optional_plugins[];
+extern struct st_mysql_plugin *mysql_mandatory_plugins[];
/**
@note The order of the enumeration is critical.
@@ -54,6 +56,9 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
extern int initialize_schema_table(st_plugin_int *plugin);
extern int finalize_schema_table(st_plugin_int *plugin);
+extern int initialize_audit_plugin(st_plugin_int *plugin);
+extern int finalize_audit_plugin(st_plugin_int *plugin);
+
/*
The number of elements in both plugin_type_initialize and
plugin_type_deinitialize should equal to the number of plugins
@@ -61,12 +66,14 @@ extern int finalize_schema_table(st_plugin_int *plugin);
*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_initialize_handlerton,0,0,initialize_schema_table
+ 0,ha_initialize_handlerton,0,0,initialize_schema_table,
+ initialize_audit_plugin
};
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
- 0,ha_finalize_handlerton,0,0,finalize_schema_table
+ 0,ha_finalize_handlerton,0,0,finalize_schema_table,
+ finalize_audit_plugin
};
#ifdef HAVE_DLOPEN
@@ -88,8 +95,8 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
- 0x0000, /* place holder for audit plugin */
- MYSQL_REPLICATION_INTERFACE_VERSION,
+ MYSQL_AUDIT_INTERFACE_VERSION,
+ MYSQL_REPLICATION_INTERFACE_VERSION
};
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
@@ -98,8 +105,8 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
MYSQL_FTPARSER_INTERFACE_VERSION,
MYSQL_DAEMON_INTERFACE_VERSION,
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
- 0x0000, /* place holder for audit plugin */
- MYSQL_REPLICATION_INTERFACE_VERSION,
+ MYSQL_AUDIT_INTERFACE_VERSION,
+ MYSQL_REPLICATION_INTERFACE_VERSION
};
/* support for Services */
@@ -111,7 +118,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
following variables/structures.
We are always manipulating ref count, so a rwlock here is unneccessary.
*/
-pthread_mutex_t LOCK_plugin;
+mysql_mutex_t LOCK_plugin;
static DYNAMIC_ARRAY plugin_dl_array;
static DYNAMIC_ARRAY plugin_array;
static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
@@ -167,6 +174,8 @@ struct st_mysql_sys_var
MYSQL_PLUGIN_VAR_HEADER;
};
+static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var);
+
/*
sys_var class for access to all plugin variables visible to the user
@@ -176,28 +185,44 @@ class sys_var_pluginvar: public sys_var
public:
struct st_plugin_int *plugin;
struct st_mysql_sys_var *plugin_var;
+ /**
+ variable name from whatever is hard-coded in the plugin source
+ and doesn't have pluginname- prefix is replaced by an allocated name
+ with a plugin prefix. When plugin is uninstalled we need to restore the
+ pointer to point to the hard-coded value, because plugin may be
+ installed/uninstalled many times without reloading the shared object.
+ */
+ const char *orig_pluginvar_name;
static void *operator new(size_t size, MEM_ROOT *mem_root)
- { return (void*) alloc_root(mem_root, (uint) size); }
+ { return (void*) alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg,size_t size)
{ TRASH(ptr_arg, size); }
- sys_var_pluginvar(const char *name_arg,
+ sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
struct st_mysql_sys_var *plugin_var_arg)
- :sys_var(name_arg), plugin_var(plugin_var_arg) {}
+ :sys_var(chain, name_arg, plugin_var_arg->comment,
+ (plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) |
+ (plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0),
+ 0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0,
+ VARIABLE_NOT_IN_BINLOG, 0, 0, 0, 0, PARSE_NORMAL),
+ plugin_var(plugin_var_arg), orig_pluginvar_name(plugin_var_arg->name)
+ { plugin_var->name= name_arg; }
sys_var_pluginvar *cast_pluginvar() { return this; }
- bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
- bool check_type(enum_var_type type)
- { return !(plugin_var->flags & PLUGIN_VAR_THDLOCAL) && type != OPT_GLOBAL; }
bool check_update_type(Item_result type);
SHOW_TYPE show_type();
uchar* real_value_ptr(THD *thd, enum_var_type type);
TYPELIB* plugin_var_typelib(void);
- uchar* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check(THD *thd, set_var *var);
- bool check_default(enum_var_type type) { return is_readonly(); }
- void set_default(THD *thd, enum_var_type type);
- bool update(THD *thd, set_var *var);
+ uchar* do_value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ uchar* session_value_ptr(THD *thd, LEX_STRING *base)
+ { return do_value_ptr(thd, OPT_SESSION, base); }
+ uchar* global_value_ptr(THD *thd, LEX_STRING *base)
+ { return do_value_ptr(thd, OPT_GLOBAL, base); }
+ bool do_check(THD *thd, set_var *var);
+ virtual void session_save_default(THD *thd, set_var *var) {}
+ virtual void global_save_default(THD *thd, set_var *var) {}
+ bool session_update(THD *thd, set_var *var);
+ bool global_update(THD *thd, set_var *var);
};
@@ -212,8 +237,9 @@ static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
static void unlock_variables(THD *thd, struct system_variables *vars);
static void cleanup_variables(THD *thd, struct system_variables *vars);
static void plugin_vars_free_values(sys_var *vars);
-static void plugin_opt_set_limits(struct my_option *options,
- const struct st_mysql_sys_var *opt);
+static void restore_pluginvar_names(sys_var *first);
+static void plugin_opt_set_limits(struct my_option *,
+ const struct st_mysql_sys_var *);
#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B CALLER_INFO)
#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B ORIG_CALLER_INFO)
static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin
@@ -221,12 +247,6 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
static void reap_plugins(void);
-
-/* declared in set_var.cc */
-extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
-extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
- const char *name, longlong val);
-
#ifdef EMBEDDED_LIBRARY
/* declared in sql_base.cc */
extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
@@ -292,6 +312,11 @@ static int item_val_int(struct st_mysql_value *value, long long *buf)
return 0;
}
+static int item_is_unsigned(struct st_mysql_value *value)
+{
+ Item *item= ((st_item_value_holder*)value)->item;
+ return item->unsigned_flag;
+}
static int item_val_real(struct st_mysql_value *value, double *buf)
{
@@ -424,7 +449,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
(plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
{
free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
+ report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, 0,
"plugin interface version mismatch");
DBUG_RETURN(0);
}
@@ -453,8 +478,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
{
free_plugin_mem(&plugin_dl);
- report_error(report, ER_CANT_FIND_DL_ENTRY, MYF(0),
- plugin_declarations_sym);
+ report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym);
DBUG_RETURN(0);
}
@@ -542,7 +566,7 @@ static void plugin_dl_del(const LEX_STRING *dl)
uint i;
DBUG_ENTER("plugin_dl_del");
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
for (i= 0; i < plugin_dl_array.elements; i++)
{
@@ -574,7 +598,7 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty
if (! initialized)
DBUG_RETURN(0);
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
if (type == MYSQL_ANY_PLUGIN)
{
@@ -599,14 +623,14 @@ static SHOW_COMP_OPTION plugin_status(const LEX_STRING *name, int type)
SHOW_COMP_OPTION rc= SHOW_OPTION_NO;
struct st_plugin_int *plugin;
DBUG_ENTER("plugin_is_ready");
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
if ((plugin= plugin_find_internal(name, type)))
{
rc= SHOW_OPTION_DISABLED;
if (plugin->state == PLUGIN_IS_READY)
rc= SHOW_OPTION_YES;
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -620,10 +644,10 @@ bool plugin_is_ready(const LEX_STRING *name, int type)
}
-SHOW_COMP_OPTION sys_var_have_plugin::get_option()
+SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type)
{
- LEX_STRING plugin_name= { (char *) plugin_name_str, plugin_name_len };
- return plugin_status(&plugin_name, plugin_type);
+ LEX_STRING plugin_name= { (char *) name, len };
+ return plugin_status(&plugin_name, type);
}
@@ -632,7 +656,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
st_plugin_int *pi= plugin_ref_to_int(rc);
DBUG_ENTER("intern_plugin_lock");
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
{
@@ -671,9 +695,9 @@ plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
LEX *lex= thd ? thd->lex : 0;
plugin_ref rc;
DBUG_ENTER("plugin_lock");
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
rc= my_intern_plugin_lock_ci(lex, *ptr);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -685,10 +709,10 @@ plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type
plugin_ref rc= NULL;
st_plugin_int *plugin;
DBUG_ENTER("plugin_lock_by_name");
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
if ((plugin= plugin_find_internal(name, type)))
rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin));
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -748,14 +772,6 @@ static bool plugin_add(MEM_ROOT *tmp_root,
name_len))
{
struct st_plugin_int *tmp_plugin_ptr;
-
- if (plugin->type == MYSQL_AUDIT_PLUGIN)
- {
- /* Bug#49894 */
- sql_print_error("Plugin type 'AUDIT' not supported by this server.");
- goto err;
- }
-
if (*(int*)plugin->info <
min_plugin_info_interface_version[plugin->type] ||
((*(int*)plugin->info) >> 8) >
@@ -787,6 +803,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
}
mysql_del_sys_var_chain(tmp.system_vars);
+ restore_pluginvar_names(tmp.system_vars);
goto err;
/* plugin was disabled */
@@ -808,17 +825,17 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
deinitialization to deadlock if plugins have worker threads
with plugin locks
*/
- safe_mutex_assert_not_owner(&LOCK_plugin);
+ mysql_mutex_assert_not_owner(&LOCK_plugin);
if (plugin->plugin->status_vars)
{
#ifdef FIX_LATER
- /*
- We have a problem right now where we can not prepend without
- breaking backwards compatibility. We will fix this shortly so
- that engines have "use names" and we wil use those for
- CREATE TABLE, and use the plugin name then for adding automatic
- variable names.
+ /**
+ @todo
+ unfortunately, status variables were introduced without a
+ pluginname_ namespace, that is pluginname_ was not added automatically
+ to status variable names. It should be fixed together with the next
+ incompatible API change.
*/
SHOW_VAR array[2]= {
{plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
@@ -858,21 +875,21 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
plugin->name.str, plugin->ref_count);
}
-
static void plugin_del(struct st_plugin_int *plugin)
{
DBUG_ENTER("plugin_del(plugin)");
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
/* Free allocated strings before deleting the plugin. */
+ mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+ mysql_del_sys_var_chain(plugin->system_vars);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ restore_pluginvar_names(plugin->system_vars);
plugin_vars_free_values(plugin->system_vars);
my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
if (plugin->plugin_dl)
plugin_dl_del(&plugin->plugin_dl->dl);
plugin->state= PLUGIN_IS_FREED;
plugin_array_version++;
- rw_wrlock(&LOCK_system_variables_hash);
- mysql_del_sys_var_chain(plugin->system_vars);
- rw_unlock(&LOCK_system_variables_hash);
free_root(&plugin->mem_root, MYF(0));
DBUG_VOID_RETURN;
}
@@ -895,7 +912,7 @@ static void reap_plugins(void)
uint count, idx;
struct st_plugin_int *plugin, **reap, **list;
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
if (!reap_needed)
return;
@@ -916,13 +933,13 @@ static void reap_plugins(void)
}
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
list= reap;
while ((plugin= *(--list)))
plugin_deinitialize(plugin, true);
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
while ((plugin= *(--reap)))
plugin_del(plugin);
@@ -936,7 +953,7 @@ static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
st_plugin_int *pi;
DBUG_ENTER("intern_plugin_unlock");
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
if (!plugin)
DBUG_VOID_RETURN;
@@ -989,10 +1006,10 @@ void plugin_unlock(THD *thd, plugin_ref plugin)
if (!plugin_dlib(plugin))
DBUG_VOID_RETURN;
#endif
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
intern_plugin_unlock(lex, plugin);
reap_plugins();
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_VOID_RETURN;
}
@@ -1002,20 +1019,25 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
LEX *lex= thd ? thd->lex : 0;
DBUG_ENTER("plugin_unlock_list");
DBUG_ASSERT(list);
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
while (count--)
intern_plugin_unlock(lex, *list++);
reap_plugins();
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_VOID_RETURN;
}
static int plugin_initialize(struct st_plugin_int *plugin)
{
+ int ret= 1;
DBUG_ENTER("plugin_initialize");
- safe_mutex_assert_owner(&LOCK_plugin);
+ mysql_mutex_assert_owner(&LOCK_plugin);
+ uint state= plugin->state;
+ DBUG_ASSERT(state == PLUGIN_IS_UNINITIALIZED);
+
+ mysql_mutex_unlock(&LOCK_plugin);
if (plugin_type_initialize[plugin->plugin->type])
{
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
@@ -1034,8 +1056,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
goto err;
}
}
-
- plugin->state= PLUGIN_IS_READY;
+ state= PLUGIN_IS_READY; // plugin->init() succeeded
if (plugin->plugin->status_vars)
{
@@ -1054,7 +1075,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
if (add_status_vars(array)) // add_status_vars makes a copy
goto err;
#else
- add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
+ if (add_status_vars(plugin->plugin->status_vars))
+ goto err;
#endif /* FIX_LATER */
}
@@ -1074,9 +1096,18 @@ static int plugin_initialize(struct st_plugin_int *plugin)
}
}
- DBUG_RETURN(0);
+ ret= 0;
+
err:
- DBUG_RETURN(1);
+ mysql_mutex_lock(&LOCK_plugin);
+ plugin->state= state;
+
+ /* maintain the obsolete @@have_innodb variable */
+ if (!my_strcasecmp(&my_charset_latin1, plugin->name.str, "InnoDB"))
+ have_innodb= state & PLUGIN_IS_READY ? SHOW_OPTION_YES
+ : SHOW_OPTION_DISABLED;
+
+ DBUG_RETURN(ret);
}
@@ -1115,6 +1146,26 @@ static inline void convert_underscore_to_dash(char *str, int len)
*p= '-';
}
+#ifdef HAVE_PSI_INTERFACE
+static PSI_mutex_key key_LOCK_plugin;
+
+static PSI_mutex_info all_plugin_mutexes[]=
+{
+ { &key_LOCK_plugin, "LOCK_plugin", PSI_FLAG_GLOBAL}
+};
+
+static void init_plugin_psi_keys(void)
+{
+ const char* category= "sql";
+ int count;
+
+ if (PSI_server == NULL)
+ return;
+
+ count= array_elements(all_plugin_mutexes);
+ PSI_server->register_mutex(category, all_plugin_mutexes, count);
+}
+#endif /* HAVE_PSI_INTERFACE */
/*
The logic is that we first load and initialize all compiled in plugins.
@@ -1131,12 +1182,17 @@ int plugin_init(int *argc, char **argv, int flags)
struct st_mysql_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
- bool reaped_mandatory_plugin= FALSE;
+ bool reaped_mandatory_plugin= false;
+ bool mandatory= true;
DBUG_ENTER("plugin_init");
if (initialized)
DBUG_RETURN(0);
+#ifdef HAVE_PSI_INTERFACE
+ init_plugin_psi_keys();
+#endif
+
init_alloc_root(&plugin_mem_root, 4096, 4096);
init_alloc_root(&tmp_root, 4096, 4096);
@@ -1145,7 +1201,7 @@ int plugin_init(int *argc, char **argv, int flags)
goto err;
- pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_plugin, &LOCK_plugin, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&plugin_dl_array,
sizeof(struct st_plugin_dl *),16,16) ||
@@ -1160,15 +1216,22 @@ int plugin_init(int *argc, char **argv, int flags)
goto err;
}
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
initialized= 1;
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mysql_mandatory_plugins; *builtins || mandatory; builtins++)
{
+ if (!*builtins)
+ {
+ builtins= mysql_optional_plugins;
+ mandatory= false;
+ if (!*builtins)
+ break;
+ }
for (plugin= *builtins; plugin->info; plugin++)
{
if (opt_ignore_builtin_innodb &&
@@ -1180,6 +1243,27 @@ int plugin_init(int *argc, char **argv, int flags)
tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name);
tmp.state= 0;
+ tmp.is_mandatory= mandatory;
+
+ /*
+ If the performance schema is compiled in,
+ treat the storage engine plugin as 'mandatory',
+ to suppress any plugin-level options such as '--performance-schema'.
+ This is specific to the performance schema, and is done on purpose:
+ the server-level option '--performance-schema' controls the overall
+ performance schema initialization, which consists of much more that
+ the underlying storage engine initialization.
+ See mysqld.cc, set_vars.cc.
+ Suppressing ways to interfere directly with the storage engine alone
+ prevents awkward situations where:
+ - the user wants the performance schema functionality, by using
+ '--enable-performance-schema' (the server option),
+ - yet disable explicitly a component needed for the functionality
+ to work, by using '--skip-performance-schema' (the plugin)
+ */
+ if (!my_strcasecmp(&my_charset_latin1, plugin->name, "PERFORMANCE_SCHEMA"))
+ tmp.is_mandatory= true;
+
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (test_plugin_options(&tmp_root, &tmp, argc, argv))
tmp.state= PLUGIN_IS_DISABLED;
@@ -1194,7 +1278,7 @@ int plugin_init(int *argc, char **argv, int flags)
my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
continue;
- if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
+ if (plugin_ptr->state != PLUGIN_IS_UNINITIALIZED ||
plugin_initialize(plugin_ptr))
goto err_unlock;
@@ -1215,7 +1299,7 @@ int plugin_init(int *argc, char **argv, int flags)
/* should now be set to MyISAM storage engine */
DBUG_ASSERT(global_system_variables.table_plugin);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
/* Register all dynamic plugins */
if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
@@ -1233,7 +1317,7 @@ int plugin_init(int *argc, char **argv, int flags)
Now we initialize all remaining plugins
*/
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
*(reap++)= NULL;
@@ -1255,15 +1339,15 @@ int plugin_init(int *argc, char **argv, int flags)
*/
while ((plugin_ptr= *(--reap)))
{
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
if (plugin_ptr->is_mandatory)
reaped_mandatory_plugin= TRUE;
plugin_deinitialize(plugin_ptr, true);
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
plugin_del(plugin_ptr);
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
my_afree(reap);
if (reaped_mandatory_plugin)
goto err;
@@ -1274,7 +1358,7 @@ end:
DBUG_RETURN(0);
err_unlock:
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
err:
free_root(&tmp_root, MYF(0));
DBUG_RETURN(1);
@@ -1303,7 +1387,6 @@ static bool register_builtin(struct st_mysql_plugin *plugin,
DBUG_RETURN(0);
}
-
#ifdef NOT_USED_YET
/*
Register a plugin at run time. (note, this doesn't initialize a plugin)
@@ -1329,18 +1412,21 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name);
- pthread_mutex_lock(&LOCK_plugin);
- rw_wrlock(&LOCK_system_variables_hash);
+ mysql_mutex_lock(&LOCK_plugin);
+ mysql_rwlock_wrlock(&LOCK_system_variables_hash);
if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL))
goto end;
tmp.state= PLUGIN_IS_UNINITIALIZED;
if ((result= register_builtin(plugin, &tmp, &ptr)))
+ {
mysql_del_sys_var_chain(tmp.system_vars);
+ restore_pluginvar_names(tmp.system_vars);
+ }
end:
- rw_unlock(&LOCK_system_variables_hash);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(result);;
}
@@ -1352,46 +1438,38 @@ end:
*/
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
{
+ THD thd;
TABLE_LIST tables;
TABLE *table;
READ_RECORD read_record_info;
int error;
- THD *new_thd;
+ THD *new_thd= &thd;
#ifdef EMBEDDED_LIBRARY
bool table_exists;
#endif /* EMBEDDED_LIBRARY */
DBUG_ENTER("plugin_load");
- if (!(new_thd= new THD))
- {
- sql_print_error("Can't allocate memory for plugin structures");
- delete new_thd;
- DBUG_VOID_RETURN;
- }
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
- lex_start(new_thd);
new_thd->db= my_strdup("mysql", MYF(0));
new_thd->db_length= 5;
- bzero((uchar*)&tables, sizeof(tables));
- tables.alias= tables.table_name= (char*)"plugin";
- tables.lock_type= TL_READ;
- tables.db= new_thd->db;
+ bzero((char*) &thd.net, sizeof(thd.net));
+ tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_READ);
#ifdef EMBEDDED_LIBRARY
/*
When building an embedded library, if the mysql.plugin table
does not exist, we silently ignore the missing table
*/
- pthread_mutex_lock(&LOCK_open);
+ mysql_mutex_lock(&LOCK_open);
if (check_if_table_exists(new_thd, &tables, &table_exists))
table_exists= FALSE;
- pthread_mutex_unlock(&LOCK_open);
+ mysql_mutex_unlock(&LOCK_open);
if (!table_exists)
goto end;
#endif /* EMBEDDED_LIBRARY */
- if (simple_open_n_lock_tables(new_thd, &tables))
+ if (open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
DBUG_PRINT("error",("Can't open plugin table"));
sql_print_error("Can't open the mysql.plugin table. Please "
@@ -1404,10 +1482,10 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
/*
there're no other threads running yet, so we don't need a mutex.
but plugin_add() before is designed to work in multi-threaded
- environment, and it uses safe_mutex_assert_owner(), so we lock
+ environment, and it uses mysql_mutex_assert_owner(), so we lock
the mutex here to satisfy the assert
*/
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info", ("init plugin record"));
@@ -1423,14 +1501,13 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
str_name.c_ptr(), str_dl.c_ptr());
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info);
new_thd->version--; // Force close to free memory
end:
close_thread_tables(new_thd);
- delete new_thd;
/* Remember that we don't have a THD */
my_pthread_setspecific_ptr(THR_THD, 0);
DBUG_VOID_RETURN;
@@ -1475,7 +1552,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
}
dl= name;
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
{
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
@@ -1493,11 +1570,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
else
{
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
goto error;
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
name.length= dl.length= 0;
dl.str= NULL; name.str= p= buffer;
str= &name;
@@ -1518,7 +1595,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
}
DBUG_RETURN(FALSE);
error:
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
sql_print_error("Couldn't load plugin named '%s' with soname '%s'.",
name.str, dl.str);
DBUG_RETURN(TRUE);
@@ -1534,7 +1611,7 @@ void plugin_shutdown(void)
if (initialized)
{
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
reap_needed= true;
@@ -1579,7 +1656,7 @@ void plugin_shutdown(void)
if (plugins[i]->state == PLUGIN_IS_DELETED)
plugins[i]->state= PLUGIN_IS_DYING;
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
/*
We loop through all plugins and call deinit() if they have one.
@@ -1600,9 +1677,9 @@ void plugin_shutdown(void)
/*
It's perfectly safe not to lock LOCK_plugin, as there're no
concurrent threads anymore. But some functions called from here
- use safe_mutex_assert_owner(), so we lock the mutex to satisfy it
+ use mysql_mutex_assert_owner(), so we lock the mutex to satisfy it
*/
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
/*
We defer checking ref_counts until after all plugins are deinitialized
@@ -1623,10 +1700,10 @@ void plugin_shutdown(void)
cleanup_variables(NULL, &global_system_variables);
cleanup_variables(NULL, &max_system_variables);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
initialized= 0;
- pthread_mutex_destroy(&LOCK_plugin);
+ mysql_mutex_destroy(&LOCK_plugin);
my_afree(plugins);
}
@@ -1664,24 +1741,23 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
- bzero(&tables, sizeof(tables));
- tables.db= (char *)"mysql";
- tables.table_name= tables.alias= (char *)"plugin";
+ tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
if (check_table_access(thd, INSERT_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
/* need to open before acquiring LOCK_plugin or it will deadlock */
- if (! (table = open_ltable(thd, &tables, TL_WRITE, 0)))
+ if (! (table = open_ltable(thd, &tables, TL_WRITE,
+ MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
- pthread_mutex_lock(&LOCK_plugin);
- rw_wrlock(&LOCK_system_variables_hash);
+ mysql_mutex_lock(&LOCK_plugin);
+ mysql_rwlock_wrlock(&LOCK_system_variables_hash);
my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL);
error= plugin_add(thd->mem_root, name, dl, &argc, argv, REPORT_TO_USER);
if (argv)
free_defaults(argv);
- rw_unlock(&LOCK_system_variables_hash);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
if (error || !(tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
goto err;
@@ -1694,7 +1770,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
}
else
{
- DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
if (plugin_initialize(tmp))
{
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
@@ -1721,14 +1796,14 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
goto deinit;
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(FALSE);
deinit:
tmp->state= PLUGIN_IS_DELETED;
reap_needed= true;
reap_plugins();
err:
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(TRUE);
}
@@ -1740,17 +1815,16 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
struct st_plugin_int *plugin;
DBUG_ENTER("mysql_uninstall_plugin");
- bzero(&tables, sizeof(tables));
- tables.db= (char *)"mysql";
- tables.table_name= tables.alias= (char *)"plugin";
+ tables.init_one_table("mysql", 5, "plugin", 6, "plugin", TL_WRITE);
+
if (check_table_access(thd, DELETE_ACL, &tables, FALSE, 1, FALSE))
DBUG_RETURN(TRUE);
/* need to open before acquiring LOCK_plugin or it will deadlock */
- if (! (table= open_ltable(thd, &tables, TL_WRITE, 0)))
+ if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
@@ -1771,7 +1845,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
else
reap_needed= true;
reap_plugins();
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
uchar user_key[MAX_KEY_LENGTH];
table->use_all_columns();
@@ -1798,7 +1872,7 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
}
DBUG_RETURN(FALSE);
err:
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(TRUE);
}
@@ -1816,7 +1890,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
state_mask= ~state_mask; // do it only once
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements
: plugin_hash[type].records;
/*
@@ -1841,17 +1915,17 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
}
}
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
for (idx= 0; idx < total; idx++)
{
if (unlikely(version != plugin_array_version))
{
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
for (uint i=idx; i < total; i++)
if (plugins[i] && plugins[i]->state & state_mask)
plugins[i]=0;
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
}
plugin= plugins[idx];
/* It will stop iterating on first engine error when "func" returns TRUE */
@@ -1914,7 +1988,7 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
char buff[STRING_BUFFER_USUAL_SIZE];
- const char *strvalue= "NULL", *str;
+ const char *str;
int result, length;
long long tmp;
@@ -1923,28 +1997,19 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
length= sizeof(buff);
if (!(str= value->val_str(value, buff, &length)) ||
(result= find_type(&bool_typelib, str, length, 1)-1) < 0)
- {
- if (str)
- strvalue= str;
goto err;
- }
}
else
{
if (value->val_int(value, &tmp) < 0)
goto err;
if (tmp > 1)
- {
- llstr(tmp, buff);
- strvalue= buff;
goto err;
- }
result= (int) tmp;
}
*(my_bool *) save= -result;
return 0;
err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
return 1;
}
@@ -1952,60 +2017,87 @@ err:
static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(int *)save= (int) getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_long(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(long *)save= (long) getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(ulonglong *)save= getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(ulonglong *)save= getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(longlong *)save= getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_str(THD *thd, struct st_mysql_sys_var *var,
@@ -2027,7 +2119,7 @@ static int check_func_enum(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
char buff[STRING_BUFFER_USUAL_SIZE];
- const char *strvalue= "NULL", *str;
+ const char *str;
TYPELIB *typelib;
long long tmp;
long result;
@@ -2043,28 +2135,20 @@ static int check_func_enum(THD *thd, struct st_mysql_sys_var *var,
length= sizeof(buff);
if (!(str= value->val_str(value, buff, &length)))
goto err;
- if ((result= (long)find_type(typelib, str, length, 1)-1) < 0)
- {
- strvalue= str;
+ if ((result= (long)find_type(typelib, str, length, 0) - 1) < 0)
goto err;
- }
}
else
{
if (value->val_int(value, &tmp))
goto err;
- if (tmp >= typelib->count)
- {
- llstr(tmp, buff);
- strvalue= buff;
+ if (tmp < 0 || tmp >= typelib->count)
goto err;
- }
result= (long) tmp;
}
*(long*)save= result;
return 0;
err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
return 1;
}
@@ -2073,7 +2157,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
- const char *strvalue= "NULL", *str;
+ const char *str;
TYPELIB *typelib;
ulonglong result;
uint error_len= 0; // init as only set on error
@@ -2093,28 +2177,19 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
result= find_set(typelib, str, length, NULL,
&error, &error_len, &not_used);
if (error_len)
- {
- strmake(buff, error, min(sizeof(buff) - 1, error_len));
- strvalue= buff;
goto err;
- }
}
else
{
if (value->val_int(value, (long long *)&result))
goto err;
- if (unlikely((result >= (ULL(1) << typelib->count)) &&
+ if (unlikely((result >= (1ULL << typelib->count)) &&
(typelib->count < sizeof(long)*8)))
- {
- llstr(result, buff);
- strvalue= buff;
goto err;
- }
}
*(ulonglong*)save= result;
return 0;
err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
return 1;
}
@@ -2172,12 +2247,12 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
plugin_ref plugin;
DBUG_ENTER("find_sys_var");
- pthread_mutex_lock(&LOCK_plugin);
- rw_rdlock(&LOCK_system_variables_hash);
- if ((var= intern_find_sys_var(str, length, false)) &&
+ mysql_mutex_lock(&LOCK_plugin);
+ mysql_rwlock_rdlock(&LOCK_system_variables_hash);
+ if ((var= intern_find_sys_var(str, length)) &&
(pi= var->cast_pluginvar()))
{
- rw_unlock(&LOCK_system_variables_hash);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
LEX *lex= thd ? thd->lex : 0;
if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
var= NULL; /* failed to lock it, it must be uninstalling */
@@ -2190,14 +2265,10 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
}
}
else
- rw_unlock(&LOCK_system_variables_hash);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
+ mysql_mutex_unlock(&LOCK_plugin);
- /*
- If the variable exists but the plugin it is associated with is not ready
- then the intern_plugin_lock did not raise an error, so we do it here.
- */
- if (pi && !var)
+ if (!var)
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
DBUG_RETURN(var);
}
@@ -2347,6 +2418,15 @@ static st_bookmark *register_var(const char *plugin, const char *name,
return result;
}
+static void restore_pluginvar_names(sys_var *first)
+{
+ for (sys_var *var= first; var; var= var->next)
+ {
+ sys_var_pluginvar *pv= var->cast_pluginvar();
+ pv->plugin_var->name= pv->orig_pluginvar_name;
+ }
+}
+
/*
returns a pointer to the memory which holds the thd-local variable or
@@ -2370,7 +2450,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
{
uint idx;
- rw_rdlock(&LOCK_system_variables_hash);
+ mysql_rwlock_rdlock(&LOCK_system_variables_hash);
thd->variables.dynamic_variables_ptr= (char*)
my_realloc(thd->variables.dynamic_variables_ptr,
@@ -2378,9 +2458,9 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
if (global_lock)
- pthread_mutex_lock(&LOCK_global_system_variables);
+ mysql_mutex_lock(&LOCK_global_system_variables);
- safe_mutex_assert_owner(&LOCK_global_system_variables);
+ mysql_mutex_assert_owner(&LOCK_global_system_variables);
memcpy(thd->variables.dynamic_variables_ptr +
thd->variables.dynamic_variables_size,
@@ -2400,7 +2480,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
st_bookmark *v= (st_bookmark*) my_hash_element(&bookmark_hash,idx);
if (v->version <= thd->variables.dynamic_variables_version ||
- !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pi= var->cast_pluginvar()) ||
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
continue;
@@ -2419,7 +2499,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
}
if (global_lock)
- pthread_mutex_unlock(&LOCK_global_system_variables);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
thd->variables.dynamic_variables_version=
global_system_variables.dynamic_variables_version;
@@ -2428,7 +2508,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
thd->variables.dynamic_variables_size=
global_system_variables.dynamic_variables_size;
- rw_unlock(&LOCK_system_variables_hash);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
}
return (uchar*)thd->variables.dynamic_variables_ptr + offset;
}
@@ -2455,11 +2535,11 @@ void plugin_thdvar_init(THD *thd)
thd->variables.dynamic_variables_size= 0;
thd->variables.dynamic_variables_ptr= 0;
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
thd->variables.table_plugin=
my_intern_plugin_lock(NULL, global_system_variables.table_plugin);
intern_plugin_unlock(NULL, old_table_plugin);
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
DBUG_VOID_RETURN;
}
@@ -2488,12 +2568,12 @@ static void cleanup_variables(THD *thd, struct system_variables *vars)
int flags;
uint idx;
- rw_rdlock(&LOCK_system_variables_hash);
+ mysql_rwlock_rdlock(&LOCK_system_variables_hash);
for (idx= 0; idx < bookmark_hash.records; idx++)
{
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
if (v->version > vars->dynamic_variables_version ||
- !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pivar= var->cast_pluginvar()) ||
v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
continue;
@@ -2508,7 +2588,7 @@ static void cleanup_variables(THD *thd, struct system_variables *vars)
*ptr= NULL;
}
}
- rw_unlock(&LOCK_system_variables_hash);
+ mysql_rwlock_unlock(&LOCK_system_variables_hash);
DBUG_ASSERT(vars->table_plugin == NULL);
@@ -2525,7 +2605,7 @@ void plugin_thdvar_cleanup(THD *thd)
plugin_ref *list;
DBUG_ENTER("plugin_thdvar_cleanup");
- pthread_mutex_lock(&LOCK_plugin);
+ mysql_mutex_lock(&LOCK_plugin);
unlock_variables(thd, &thd->variables);
cleanup_variables(thd, &thd->variables);
@@ -2539,7 +2619,7 @@ void plugin_thdvar_cleanup(THD *thd)
}
reap_plugins();
- pthread_mutex_unlock(&LOCK_plugin);
+ mysql_mutex_unlock(&LOCK_plugin);
reset_dynamic(&thd->lex->plugins);
@@ -2572,7 +2652,7 @@ static void plugin_vars_free_values(sys_var *vars)
/* Free the string from global_system_variables. */
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
DBUG_PRINT("plugin", ("freeing value for: '%s' addr: 0x%lx",
- var->name, (long) valptr));
+ var->name.str, (long) valptr));
my_free(*valptr, MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
*valptr= NULL;
}
@@ -2580,43 +2660,44 @@ static void plugin_vars_free_values(sys_var *vars)
DBUG_VOID_RETURN;
}
-
-bool sys_var_pluginvar::check_update_type(Item_result type)
+static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var)
{
- if (is_readonly())
- return 1;
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_BOOL:
+ return SHOW_MY_BOOL;
case PLUGIN_VAR_INT:
+ return SHOW_INT;
case PLUGIN_VAR_LONG:
+ return SHOW_LONG;
case PLUGIN_VAR_LONGLONG:
- return type != INT_RESULT;
+ return SHOW_LONGLONG;
case PLUGIN_VAR_STR:
- return type != STRING_RESULT;
+ return SHOW_CHAR_PTR;
+ case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_SET:
+ return SHOW_CHAR;
default:
- return 0;
+ DBUG_ASSERT(0);
+ return SHOW_UNDEF;
}
}
-SHOW_TYPE sys_var_pluginvar::show_type()
+bool sys_var_pluginvar::check_update_type(Item_result type)
{
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
- case PLUGIN_VAR_BOOL:
- return SHOW_MY_BOOL;
case PLUGIN_VAR_INT:
- return SHOW_INT;
case PLUGIN_VAR_LONG:
- return SHOW_LONG;
case PLUGIN_VAR_LONGLONG:
- return SHOW_LONGLONG;
+ return type != INT_RESULT;
case PLUGIN_VAR_STR:
- return SHOW_CHAR_PTR;
+ return type != STRING_RESULT;
case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_BOOL:
case PLUGIN_VAR_SET:
- return SHOW_CHAR;
+ return type != STRING_RESULT && type != INT_RESULT;
default:
- DBUG_ASSERT(0);
- return SHOW_UNDEF;
+ return true;
}
}
@@ -2649,12 +2730,12 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
default:
return NULL;
}
- return NULL;
+ return NULL; /* Keep compiler happy */
}
-uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
+uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
{
uchar* result;
@@ -2663,139 +2744,104 @@ uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
result= (uchar*) get_type(plugin_var_typelib(), *(ulong*)result);
else if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
- {
- char buffer[STRING_BUFFER_USUAL_SIZE];
- String str(buffer, sizeof(buffer), system_charset_info);
- TYPELIB *typelib= plugin_var_typelib();
- ulonglong mask= 1, value= *(ulonglong*) result;
- uint i;
-
- str.length(0);
- for (i= 0; i < typelib->count; i++, mask<<=1)
- {
- if (!(value & mask))
- continue;
- str.append(typelib->type_names[i], typelib->type_lengths
- ? typelib->type_lengths[i]
- : strlen(typelib->type_names[i]));
- str.append(',');
- }
-
- result= (uchar*) "";
- if (str.length())
- result= (uchar*) thd->strmake(str.ptr(), str.length()-1);
- }
+ result= (uchar*) set_to_string(thd, 0, *(ulonglong*) result,
+ plugin_var_typelib()->type_names);
return result;
}
-
-bool sys_var_pluginvar::check(THD *thd, set_var *var)
+bool sys_var_pluginvar::do_check(THD *thd, set_var *var)
{
st_item_value_holder value;
- DBUG_ASSERT(is_readonly() || plugin_var->check);
+ DBUG_ASSERT(!is_readonly());
+ DBUG_ASSERT(plugin_var->check);
value.value_type= item_value_type;
value.val_str= item_val_str;
value.val_int= item_val_int;
value.val_real= item_val_real;
+ value.is_unsigned= item_is_unsigned;
value.item= var->value;
- return is_readonly() ||
- plugin_var->check(thd, plugin_var, &var->save_result, &value);
+ return plugin_var->check(thd, plugin_var, &var->save_result, &value);
}
-
-void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
+bool sys_var_pluginvar::session_update(THD *thd, set_var *var)
{
- const void *src;
- void *tgt;
-
- DBUG_ASSERT(is_readonly() || plugin_var->update);
+ DBUG_ASSERT(!is_readonly());
+ DBUG_ASSERT(plugin_var->flags & PLUGIN_VAR_THDLOCAL);
+ DBUG_ASSERT(thd == current_thd);
- if (is_readonly())
- return;
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- tgt= real_value_ptr(thd, type);
- src= ((void **) (plugin_var + 1) + 1);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ void *tgt= real_value_ptr(thd, var->type);
+ const void *src= var->value ? (void*)&var->save_result
+ : (void*)real_value_ptr(thd, OPT_GLOBAL);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ plugin_var->update(thd, plugin_var, tgt, src);
- if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
- {
- if (type != OPT_GLOBAL)
- src= real_value_ptr(thd, OPT_GLOBAL);
- else
- switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
- case PLUGIN_VAR_INT:
- src= &((thdvar_uint_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_LONG:
- src= &((thdvar_ulong_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_LONGLONG:
- src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_ENUM:
- src= &((thdvar_enum_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_SET:
- src= &((thdvar_set_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_BOOL:
- src= &((thdvar_bool_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_STR:
- src= &((thdvar_str_t*) plugin_var)->def_val;
- break;
- default:
- DBUG_ASSERT(0);
- }
- }
-
- /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
- DBUG_ASSERT(!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) ||
- thd == current_thd);
-
- if (!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) || type == OPT_GLOBAL)
- {
- plugin_var->update(thd, plugin_var, tgt, src);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- {
- pthread_mutex_unlock(&LOCK_global_system_variables);
- plugin_var->update(thd, plugin_var, tgt, src);
- }
+ return false;
}
-
-bool sys_var_pluginvar::update(THD *thd, set_var *var)
+bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
{
- void *tgt;
+ DBUG_ASSERT(!is_readonly());
+ mysql_mutex_assert_owner(&LOCK_global_system_variables);
- DBUG_ASSERT(is_readonly() || plugin_var->update);
+ void *tgt= real_value_ptr(thd, var->type);
+ const void *src= &var->save_result;
- /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
- DBUG_ASSERT(!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) ||
- thd == current_thd);
-
- if (is_readonly())
- return 1;
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- tgt= real_value_ptr(thd, var->type);
-
- if (!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) || var->type == OPT_GLOBAL)
- {
- /* variable we are updating has global scope, so we unlock after updating */
- plugin_var->update(thd, plugin_var, tgt, &var->save_result);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
+ if (!var->value)
{
- pthread_mutex_unlock(&LOCK_global_system_variables);
- plugin_var->update(thd, plugin_var, tgt, &var->save_result);
+ switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
+ case PLUGIN_VAR_INT:
+ src= &((sysvar_uint_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONG:
+ src= &((sysvar_ulong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ src= &((sysvar_ulonglong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_ENUM:
+ src= &((sysvar_enum_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_SET:
+ src= &((sysvar_set_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_BOOL:
+ src= &((sysvar_bool_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_STR:
+ src= &((sysvar_str_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_uint_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_ulong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_enum_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_set_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_bool_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_str_t*) plugin_var)->def_val;
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
}
- return 0;
+
+ plugin_var->update(thd, plugin_var, tgt, src);
+
+ return false;
}
@@ -2845,7 +2891,7 @@ static void plugin_opt_set_limits(struct my_option *options,
options->typelib= ((sysvar_set_t*) opt)->typelib;
options->def_value= ((sysvar_set_t*) opt)->def_val;
options->min_value= options->block_size= 0;
- options->max_value= (ULL(1) << options->typelib->count) - 1;
+ options->max_value= (1ULL << options->typelib->count) - 1;
break;
case PLUGIN_VAR_BOOL:
options->var_type= GET_BOOL;
@@ -2887,7 +2933,7 @@ static void plugin_opt_set_limits(struct my_option *options,
options->typelib= ((thdvar_set_t*) opt)->typelib;
options->def_value= ((thdvar_set_t*) opt)->def_val;
options->min_value= options->block_size= 0;
- options->max_value= (ULL(1) << options->typelib->count) - 1;
+ options->max_value= (1ULL << options->typelib->count) - 1;
break;
case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
options->var_type= GET_BOOL;
@@ -2958,40 +3004,48 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
DBUG_ENTER("construct_options");
- options[0].name= plugin_name_ptr= (char*) alloc_root(mem_root,
- plugin_name_len + 1);
+ plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1);
strcpy(plugin_name_ptr, plugin_name);
my_casedn_str(&my_charset_latin1, plugin_name_ptr);
convert_underscore_to_dash(plugin_name_ptr, plugin_name_len);
- /* support --skip-plugin-foo syntax */
- options[1].name= plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root,
- plugin_name_len +
- plugin_dash.length + 1);
- strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, options[0].name, NullS);
-
- options[0].id= options[1].id= 256; /* must be >255. dup id ok */
- options[0].var_type= options[1].var_type= GET_ENUM;
- options[0].arg_type= options[1].arg_type= OPT_ARG;
- options[0].def_value= options[1].def_value= 1; /* ON */
- options[0].typelib= options[1].typelib= &global_plugin_typelib;
-
- strxnmov(comment, max_comment_len, "Enable or disable ", plugin_name,
- " plugin. Possible values are ON, OFF, FORCE (don't start "
- "if the plugin fails to load).", NullS);
- options[0].comment= comment;
+ plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root,
+ plugin_name_len +
+ plugin_dash.length + 1);
+ strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
+
+ if (!tmp->is_mandatory)
+ {
+ /* support --skip-plugin-foo syntax */
+ options[0].name= plugin_name_ptr;
+ options[1].name= plugin_name_with_prefix_ptr;
+ options[0].id= options[1].id= 0;
+ options[0].var_type= options[1].var_type= GET_ENUM;
+ options[0].arg_type= options[1].arg_type= OPT_ARG;
+ options[0].def_value= options[1].def_value= 1; /* ON */
+ options[0].typelib= options[1].typelib= &global_plugin_typelib;
+
+ strxnmov(comment, max_comment_len, "Enable or disable ", plugin_name,
+ " plugin. Possible values are ON, OFF, FORCE (don't start "
+ "if the plugin fails to load).", NullS);
+ options[0].comment= comment;
+ /*
+ Allocate temporary space for the value of the tristate.
+ This option will have a limited lifetime and is not used beyond
+ server initialization.
+ GET_ENUM value is an unsigned integer.
+ */
+ options[0].value= options[1].value=
+ (uchar **)alloc_root(mem_root, sizeof(uint));
+ *((uint*) options[0].value)= (uint) options[0].def_value;
- /*
- Allocate temporary space for the value of the tristate.
- This option will have a limited lifetime and is not used beyond
- server initialization.
- GET_ENUM value is an integer.
- */
- options[0].value= options[1].value= (uchar **)alloc_root(mem_root,
- sizeof(int));
- *((uint*) options[0].value)= *((uint*) options[1].value)=
- (uint) options[0].def_value;
+ options+= 2;
+ }
- options+= 2;
+ if (!my_strcasecmp(&my_charset_latin1, plugin_name_ptr, "NDBCLUSTER"))
+ {
+ plugin_name_ptr= const_cast<char*>("ndb"); // Use legacy "ndb" prefix
+ plugin_name_len= 3;
+ }
/*
Two passes as the 2nd pass will take pointer addresses for use
@@ -3139,7 +3193,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
options->name= optname;
options->comment= opt->comment;
options->app_type= opt;
- options->id= (options-1)->id + 1;
+ options->id= 0;
plugin_opt_set_limits(options, opt);
@@ -3180,13 +3234,20 @@ static my_option *construct_help_options(MEM_ROOT *mem_root,
bzero(opts, sizeof(my_option) * count);
+ /**
+ some plugin variables (those that don't have PLUGIN_VAR_NOSYSVAR flag)
+ have their names prefixed with the plugin name. Restore the names here
+ to get the correct (not double-prefixed) help text.
+ We won't need @@sysvars anymore and don't care about their proper names.
+ */
+ restore_pluginvar_names(p->system_vars);
+
if (construct_options(mem_root, p, opts))
DBUG_RETURN(NULL);
DBUG_RETURN(opts);
}
-
/**
Create and register system variables supplied from the plugin and
assigns initial values from corresponding command line arguments.
@@ -3211,18 +3272,17 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
int *argc, char **argv)
{
struct sys_var_chain chain= { NULL, NULL };
- my_bool can_disable;
bool disable_plugin;
- enum_plugin_load_policy plugin_load_policy= PLUGIN_ON;
+ enum_plugin_load_policy plugin_load_policy= tmp->is_mandatory ? PLUGIN_FORCE : PLUGIN_ON;
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
&tmp->mem_root : &plugin_mem_root;
st_mysql_sys_var **opt;
my_option *opts= NULL;
+ LEX_STRING plugin_name;
char *varname;
int error;
- st_mysql_sys_var *o;
- sys_var *v;
+ sys_var *v __attribute__((unused));
struct st_bookmark *var;
uint len, count= EXTRA_OPTIONS;
DBUG_ENTER("test_plugin_options");
@@ -3258,9 +3318,10 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
We adjust the default value to account for the hardcoded exceptions
we have set for the federated and ndbcluster storage engines.
*/
- opts[0].def_value= opts[1].def_value= (int)plugin_load_policy;
+ if (!tmp->is_mandatory)
+ opts[0].def_value= opts[1].def_value= plugin_load_policy;
- error= handle_options(argc, &argv, opts, get_one_plugin_option);
+ error= handle_options(argc, &argv, opts, NULL);
(*argc)++; /* add back one for the program name */
if (error)
@@ -3273,24 +3334,12 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
Set plugin loading policy from option value. First element in the option
list is always the <plugin name> option value.
*/
- plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value;
+ if (!tmp->is_mandatory)
+ plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value;
}
disable_plugin= (plugin_load_policy == PLUGIN_OFF);
- /*
- The 'MyISAM' and 'Memory' storage engines currently can't be disabled.
- */
- can_disable=
- my_strcasecmp(&my_charset_latin1, tmp->name.str, "MyISAM") &&
- my_strcasecmp(&my_charset_latin1, tmp->name.str, "MEMORY");
-
- tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE) || !can_disable;
-
- if (disable_plugin && !can_disable)
- {
- sql_print_warning("Plugin '%s' cannot be disabled", tmp->name.str);
- disable_plugin= FALSE;
- }
+ tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE);
/*
If the plugin is disabled it should not be initialized.
@@ -3305,34 +3354,37 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
DBUG_RETURN(1);
}
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "NDBCLUSTER"))
+ {
+ plugin_name.str= const_cast<char*>("ndb"); // Use legacy "ndb" prefix
+ plugin_name.length= 3;
+ }
+ else
+ plugin_name= tmp->name;
+
error= 1;
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
{
+ st_mysql_sys_var *o;
if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
continue;
- if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
- v= new (mem_root) sys_var_pluginvar(var->key + 1, o);
+ if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
+ v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o);
else
{
- len= tmp->name.length + strlen(o->name) + 2;
+ len= plugin_name.length + strlen(o->name) + 2;
varname= (char*) alloc_root(mem_root, len);
- strxmov(varname, tmp->name.str, "-", o->name, NullS);
+ strxmov(varname, plugin_name.str, "-", o->name, NullS);
my_casedn_str(&my_charset_latin1, varname);
convert_dash_to_underscore(varname, len-1);
- v= new (mem_root) sys_var_pluginvar(varname, o);
+ v= new (mem_root) sys_var_pluginvar(&chain, varname, o);
}
DBUG_ASSERT(v); /* check that an object was actually constructed */
- /*
- Add to the chain of variables.
- Done like this for easier debugging so that the
- pointer to v is not lost on optimized builds.
- */
- v->chain_sys_var(&chain);
} /* end for */
if (chain.first)
{
chain.last->next = NULL;
- if (mysql_add_sys_var_chain(chain.first, NULL))
+ if (mysql_add_sys_var_chain(chain.first))
{
sql_print_error("Plugin '%s' has conflicting system variables",
tmp->name.str);
@@ -3353,49 +3405,26 @@ err:
Help Verbose text with Plugin System Variables
****************************************************************************/
-static int option_cmp(my_option *a, my_option *b)
-{
- return my_strcasecmp(&my_charset_latin1, a->name, b->name);
-}
-
-void my_print_help_inc_plugins(my_option *main_options, uint size)
+void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root)
{
- DYNAMIC_ARRAY all_options;
struct st_plugin_int *p;
- MEM_ROOT mem_root;
my_option *opt;
- init_alloc_root(&mem_root, 4096, 4096);
- my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
-
- if (initialized)
- for (uint idx= 0; idx < plugin_array.elements; idx++)
- {
- p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
-
- if (!p->plugin->system_vars ||
- !(opt= construct_help_options(&mem_root, p)))
- continue;
-
- /* Only options with a non-NULL comment are displayed in help text */
- for (;opt->id; opt++)
- if (opt->comment)
- insert_dynamic(&all_options, (uchar*) opt);
- }
-
- for (;main_options->id; main_options++)
- insert_dynamic(&all_options, (uchar*) main_options);
-
- sort_dynamic(&all_options, (qsort_cmp) option_cmp);
+ if (!initialized)
+ return;
- /* main_options now points to the empty option terminator */
- insert_dynamic(&all_options, (uchar*) main_options);
+ for (uint idx= 0; idx < plugin_array.elements; idx++)
+ {
+ p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
- my_print_help((my_option*) all_options.buffer);
- my_print_variables((my_option*) all_options.buffer);
+ if (!(opt= construct_help_options(mem_root, p)))
+ continue;
- delete_dynamic(&all_options);
- free_root(&mem_root, MYF(0));
+ /* Only options with a non-NULL comment are displayed in help text */
+ for (;opt->name; opt++)
+ if (opt->comment)
+ insert_dynamic(options, (uchar*) opt);
+ }
}