mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
mdev-20: INSTALL PLUGIN SONAME
This commit is contained in:
parent
98141ea42b
commit
1c530b36d1
11 changed files with 332 additions and 161 deletions
|
@ -462,8 +462,6 @@ extern "C" int madvise(void *addr, size_t len, int behav);
|
||||||
#ifndef SO_EXT
|
#ifndef SO_EXT
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define SO_EXT ".dll"
|
#define SO_EXT ".dll"
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#define SO_EXT ".dylib"
|
|
||||||
#else
|
#else
|
||||||
#define SO_EXT ".so"
|
#define SO_EXT ".so"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,15 +3,41 @@ Warnings:
|
||||||
Warning 1286 Unknown storage engine 'EXAMPLE'
|
Warning 1286 Unknown storage engine 'EXAMPLE'
|
||||||
Warning 1266 Using storage engine MyISAM for table 't1'
|
Warning 1266 Using storage engine MyISAM for table 't1'
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
INSTALL PLUGIN example SONAME 'ha_example.so';
|
INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
INSTALL PLUGIN EXAMPLE SONAME 'ha_example.so';
|
INSTALL PLUGIN EXAMPLE SONAME 'ha_example';
|
||||||
ERROR HY000: Function 'EXAMPLE' already exists
|
ERROR HY000: Function 'EXAMPLE' already exists
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL PLUGIN example;
|
||||||
INSTALL PLUGIN example SONAME 'ha_example.so';
|
INSTALL SONAME 'ha_example';
|
||||||
|
select * from information_schema.plugins where plugin_library like 'ha_example%';
|
||||||
|
PLUGIN_NAME EXAMPLE
|
||||||
|
PLUGIN_VERSION 0.1
|
||||||
|
PLUGIN_STATUS ACTIVE
|
||||||
|
PLUGIN_TYPE STORAGE ENGINE
|
||||||
|
PLUGIN_TYPE_VERSION #
|
||||||
|
PLUGIN_LIBRARY ha_example.so
|
||||||
|
PLUGIN_LIBRARY_VERSION 1.1
|
||||||
|
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
||||||
|
PLUGIN_DESCRIPTION Example storage engine
|
||||||
|
PLUGIN_LICENSE GPL
|
||||||
|
LOAD_OPTION ON
|
||||||
|
PLUGIN_MATURITY Experimental
|
||||||
|
PLUGIN_AUTH_VERSION 0.1
|
||||||
|
PLUGIN_NAME UNUSABLE
|
||||||
|
PLUGIN_VERSION 3.14
|
||||||
|
PLUGIN_STATUS ACTIVE
|
||||||
|
PLUGIN_TYPE DAEMON
|
||||||
|
PLUGIN_TYPE_VERSION #
|
||||||
|
PLUGIN_LIBRARY ha_example.so
|
||||||
|
PLUGIN_LIBRARY_VERSION 1.1
|
||||||
|
PLUGIN_AUTHOR Sergei Golubchik
|
||||||
|
PLUGIN_DESCRIPTION Unusable Daemon
|
||||||
|
PLUGIN_LICENSE GPL
|
||||||
|
LOAD_OPTION ON
|
||||||
|
PLUGIN_MATURITY Experimental
|
||||||
|
PLUGIN_AUTH_VERSION 3.14.15.926
|
||||||
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
a
|
a
|
||||||
DROP TABLE t1;
|
|
||||||
set global example_ulong_var=500;
|
set global example_ulong_var=500;
|
||||||
set global example_enum_var= e1;
|
set global example_enum_var= e1;
|
||||||
show status like 'example%';
|
show status like 'example%';
|
||||||
|
@ -21,7 +47,24 @@ show variables like 'example%';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
example_enum_var e1
|
example_enum_var e1
|
||||||
example_ulong_var 500
|
example_ulong_var 500
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL SONAME 'ha_example';
|
||||||
|
Warnings:
|
||||||
|
Warning 1620 Plugin is busy and will be uninstalled on shutdown
|
||||||
|
select * from information_schema.plugins where plugin_library like 'ha_example%';
|
||||||
|
PLUGIN_NAME EXAMPLE
|
||||||
|
PLUGIN_VERSION 0.1
|
||||||
|
PLUGIN_STATUS DELETED
|
||||||
|
PLUGIN_TYPE STORAGE ENGINE
|
||||||
|
PLUGIN_TYPE_VERSION #
|
||||||
|
PLUGIN_LIBRARY ha_example.so
|
||||||
|
PLUGIN_LIBRARY_VERSION 1.1
|
||||||
|
PLUGIN_AUTHOR Brian Aker, MySQL AB
|
||||||
|
PLUGIN_DESCRIPTION Example storage engine
|
||||||
|
PLUGIN_LICENSE GPL
|
||||||
|
LOAD_OPTION ON
|
||||||
|
PLUGIN_MATURITY Experimental
|
||||||
|
PLUGIN_AUTH_VERSION 0.1
|
||||||
|
DROP TABLE t1;
|
||||||
UNINSTALL PLUGIN EXAMPLE;
|
UNINSTALL PLUGIN EXAMPLE;
|
||||||
ERROR 42000: PLUGIN EXAMPLE does not exist
|
ERROR 42000: PLUGIN EXAMPLE does not exist
|
||||||
UNINSTALL PLUGIN non_exist;
|
UNINSTALL PLUGIN non_exist;
|
||||||
|
@ -30,13 +73,13 @@ ERROR 42000: PLUGIN non_exist does not exist
|
||||||
# Bug#32034: check_func_enum() does not check correct values but set it
|
# Bug#32034: check_func_enum() does not check correct values but set it
|
||||||
# to impossible int val
|
# to impossible int val
|
||||||
#
|
#
|
||||||
INSTALL PLUGIN example SONAME 'ha_example.so';
|
INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
SET GLOBAL example_enum_var= e1;
|
SET GLOBAL example_enum_var= e1;
|
||||||
SET GLOBAL example_enum_var= e2;
|
SET GLOBAL example_enum_var= e2;
|
||||||
SET GLOBAL example_enum_var= impossible;
|
SET GLOBAL example_enum_var= impossible;
|
||||||
ERROR 42000: Variable 'example_enum_var' can't be set to the value of 'impossible'
|
ERROR 42000: Variable 'example_enum_var' can't be set to the value of 'impossible'
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL PLUGIN example;
|
||||||
INSTALL PLUGIN example SONAME 'ha_example.so';
|
INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
select @@session.sql_mode into @old_sql_mode;
|
select @@session.sql_mode into @old_sql_mode;
|
||||||
set session sql_mode='';
|
set session sql_mode='';
|
||||||
set global example_ulong_var=500;
|
set global example_ulong_var=500;
|
||||||
|
|
|
@ -1,2 +1,8 @@
|
||||||
INSTALL PLUGIN example SONAME 'ha_example.so';
|
INSTALL PLUGIN example SONAME 'ha_example.so';
|
||||||
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugins is prohibited by --plugin-maturity=stable)
|
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
|
||||||
|
INSTALL SONAME 'ha_example.so';
|
||||||
|
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
|
||||||
|
show warnings;
|
||||||
|
Level Code Message
|
||||||
|
Error 1126 Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
|
||||||
|
Error 1126 Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin UNUSABLE is prohibited by --plugin-maturity=stable)
|
||||||
|
|
|
@ -4,23 +4,23 @@
|
||||||
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--replace_regex /\.dll/.so/
|
eval INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
|
||||||
--replace_regex /\.dll/.so/
|
--replace_regex /\.dll/.so/
|
||||||
--error 1125
|
--error 1125
|
||||||
eval INSTALL PLUGIN EXAMPLE SONAME '$HA_EXAMPLE_SO';
|
eval INSTALL PLUGIN EXAMPLE SONAME 'ha_example';
|
||||||
|
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL PLUGIN example;
|
||||||
|
|
||||||
|
eval INSTALL SONAME 'ha_example';
|
||||||
|
--replace_column 5 #
|
||||||
--replace_regex /\.dll/.so/
|
--replace_regex /\.dll/.so/
|
||||||
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
--query_vertical select * from information_schema.plugins where plugin_library like 'ha_example%'
|
||||||
|
|
||||||
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
|
||||||
|
|
||||||
# Let's do some advanced ops with the example engine :)
|
# Let's do some advanced ops with the example engine :)
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
|
||||||
|
|
||||||
# a couple of tests for variables
|
# a couple of tests for variables
|
||||||
set global example_ulong_var=500;
|
set global example_ulong_var=500;
|
||||||
|
@ -28,7 +28,13 @@ set global example_enum_var= e1;
|
||||||
show status like 'example%';
|
show status like 'example%';
|
||||||
show variables like 'example%';
|
show variables like 'example%';
|
||||||
|
|
||||||
UNINSTALL PLUGIN example;
|
eval UNINSTALL SONAME 'ha_example';
|
||||||
|
--replace_column 5 #
|
||||||
|
--replace_regex /\.dll/.so/
|
||||||
|
--query_vertical select * from information_schema.plugins where plugin_library like 'ha_example%'
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--error 1305
|
--error 1305
|
||||||
UNINSTALL PLUGIN EXAMPLE;
|
UNINSTALL PLUGIN EXAMPLE;
|
||||||
|
|
||||||
|
@ -40,8 +46,7 @@ UNINSTALL PLUGIN non_exist;
|
||||||
--echo # Bug#32034: check_func_enum() does not check correct values but set it
|
--echo # Bug#32034: check_func_enum() does not check correct values but set it
|
||||||
--echo # to impossible int val
|
--echo # to impossible int val
|
||||||
--echo #
|
--echo #
|
||||||
--replace_regex /\.dll/.so/
|
eval INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
|
||||||
|
|
||||||
SET GLOBAL example_enum_var= e1;
|
SET GLOBAL example_enum_var= e1;
|
||||||
SET GLOBAL example_enum_var= e2;
|
SET GLOBAL example_enum_var= e2;
|
||||||
|
@ -55,8 +60,7 @@ UNINSTALL PLUGIN example;
|
||||||
#
|
#
|
||||||
# Bug #32757 hang with sql_mode set when setting some global variables
|
# Bug #32757 hang with sql_mode set when setting some global variables
|
||||||
#
|
#
|
||||||
--replace_regex /\.dll/.so/
|
eval INSTALL PLUGIN example SONAME 'ha_example';
|
||||||
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
|
||||||
|
|
||||||
select @@session.sql_mode into @old_sql_mode;
|
select @@session.sql_mode into @old_sql_mode;
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
--replace_regex /\.dll/.so/
|
--replace_regex /\.dll/.so/
|
||||||
--error 1126
|
--error 1126
|
||||||
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO';
|
||||||
|
|
||||||
|
--replace_regex /\.dll/.so/
|
||||||
|
--error 1126
|
||||||
|
eval INSTALL SONAME '$HA_EXAMPLE_SO';
|
||||||
|
--replace_regex /\.dll/.so/
|
||||||
|
show warnings;
|
||||||
|
|
|
@ -2594,13 +2594,10 @@ drop table t1;
|
||||||
|
|
||||||
|
|
||||||
create procedure proc_1() install plugin my_plug soname 'some_plugin.so';
|
create procedure proc_1() install plugin my_plug soname 'some_plugin.so';
|
||||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
|
||||||
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
||||||
call proc_1();
|
call proc_1();
|
||||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
|
||||||
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
||||||
call proc_1();
|
call proc_1();
|
||||||
--replace_regex /(Can\'t open shared library).*$/\1/
|
|
||||||
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
--error ER_CANT_OPEN_LIBRARY,ER_FEATURE_DISABLED
|
||||||
call proc_1();
|
call proc_1();
|
||||||
drop procedure proc_1;
|
drop procedure proc_1;
|
||||||
|
|
|
@ -4363,7 +4363,8 @@ create_sp_error:
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_UNINSTALL_PLUGIN:
|
case SQLCOM_UNINSTALL_PLUGIN:
|
||||||
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
|
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment,
|
||||||
|
&thd->lex->ident)))
|
||||||
my_ok(thd);
|
my_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_BINLOG_BASE64_EVENT:
|
case SQLCOM_BINLOG_BASE64_EVENT:
|
||||||
|
|
|
@ -297,8 +297,7 @@ public:
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv);
|
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv);
|
||||||
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
static bool plugin_load_list(MEM_ROOT *, int *, char **, const char *);
|
||||||
const char *list);
|
|
||||||
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
|
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
|
||||||
int *, char **);
|
int *, char **);
|
||||||
static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
|
static bool register_builtin(struct st_maria_plugin *, struct st_plugin_int *,
|
||||||
|
@ -318,6 +317,7 @@ static void reap_plugins(void);
|
||||||
static void report_error(int where_to, uint error, ...)
|
static void report_error(int where_to, uint error, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
DBUG_ASSERT(where_to & (REPORT_TO_USER | REPORT_TO_LOG));
|
||||||
if (where_to & REPORT_TO_USER)
|
if (where_to & REPORT_TO_USER)
|
||||||
{
|
{
|
||||||
va_start(args, error);
|
va_start(args, error);
|
||||||
|
@ -351,6 +351,20 @@ bool check_valid_path(const char *path, size_t len)
|
||||||
return prefix < len;
|
return prefix < len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fix_dl_name(MEM_ROOT *root, LEX_STRING *dl)
|
||||||
|
{
|
||||||
|
const size_t so_ext_len= sizeof(SO_EXT) - 1;
|
||||||
|
if (my_strcasecmp(&my_charset_latin1, dl->str + dl->length - so_ext_len,
|
||||||
|
SO_EXT))
|
||||||
|
{
|
||||||
|
char *s= (char*)alloc_root(root, dl->length + so_ext_len + 1);
|
||||||
|
memcpy(s, dl->str, dl->length);
|
||||||
|
strcpy(s + dl->length, SO_EXT);
|
||||||
|
dl->str= s;
|
||||||
|
dl->length+= so_ext_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Value type thunks, allows the C world to play in the C++ world
|
Value type thunks, allows the C world to play in the C++ world
|
||||||
|
@ -1017,31 +1031,40 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
|
||||||
Requires that a write-lock is held on LOCK_system_variables_hash
|
Requires that a write-lock is held on LOCK_system_variables_hash
|
||||||
*/
|
*/
|
||||||
static bool plugin_add(MEM_ROOT *tmp_root,
|
static bool plugin_add(MEM_ROOT *tmp_root,
|
||||||
const LEX_STRING *name, const LEX_STRING *dl,
|
const LEX_STRING *name, LEX_STRING *dl,
|
||||||
int *argc, char **argv, int report)
|
int *argc, char **argv, int report)
|
||||||
{
|
{
|
||||||
struct st_plugin_int tmp;
|
struct st_plugin_int tmp;
|
||||||
struct st_maria_plugin *plugin;
|
struct st_maria_plugin *plugin;
|
||||||
|
uint oks= 0, errs= 0;
|
||||||
DBUG_ENTER("plugin_add");
|
DBUG_ENTER("plugin_add");
|
||||||
if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
|
if (name->str && plugin_find_internal(name, MYSQL_ANY_PLUGIN))
|
||||||
{
|
{
|
||||||
report_error(report, ER_UDF_EXISTS, name->str);
|
report_error(report, ER_UDF_EXISTS, name->str);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
/* Clear the whole struct to catch future extensions. */
|
/* Clear the whole struct to catch future extensions. */
|
||||||
bzero((char*) &tmp, sizeof(tmp));
|
bzero((char*) &tmp, sizeof(tmp));
|
||||||
|
fix_dl_name(tmp_root, dl);
|
||||||
if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
|
if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
/* Find plugin by name */
|
/* Find plugin by name */
|
||||||
for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++)
|
for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++)
|
||||||
{
|
{
|
||||||
uint name_len= strlen(plugin->name);
|
tmp.name.str= (char *)plugin->name;
|
||||||
if (plugin->type >= 0 && plugin->type < MYSQL_MAX_PLUGIN_TYPE_NUM &&
|
tmp.name.length= strlen(plugin->name);
|
||||||
! my_strnncoll(system_charset_info,
|
|
||||||
(const uchar *)name->str, name->length,
|
if (plugin->type < 0 || plugin->type >= MYSQL_MAX_PLUGIN_TYPE_NUM)
|
||||||
(const uchar *)plugin->name,
|
continue; // invalid plugin
|
||||||
name_len))
|
|
||||||
{
|
if (name->str && my_strnncoll(system_charset_info,
|
||||||
|
(const uchar *)name->str, name->length,
|
||||||
|
(const uchar *)tmp.name.str, tmp.name.length))
|
||||||
|
continue; // plugin name doesn't match
|
||||||
|
|
||||||
|
if (!name->str && plugin_find_internal(&tmp.name, MYSQL_ANY_PLUGIN))
|
||||||
|
continue; // already installed
|
||||||
|
|
||||||
struct st_plugin_int *tmp_plugin_ptr;
|
struct st_plugin_int *tmp_plugin_ptr;
|
||||||
if (*(int*)plugin->info <
|
if (*(int*)plugin->info <
|
||||||
min_plugin_info_interface_version[plugin->type] ||
|
min_plugin_info_interface_version[plugin->type] ||
|
||||||
|
@ -1051,7 +1074,8 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||||
char buf[256];
|
char buf[256];
|
||||||
strxnmov(buf, sizeof(buf) - 1, "API version for ",
|
strxnmov(buf, sizeof(buf) - 1, "API version for ",
|
||||||
plugin_type_names[plugin->type].str,
|
plugin_type_names[plugin->type].str,
|
||||||
" plugin is too different", NullS);
|
" plugin ", tmp.name.str,
|
||||||
|
" not supported by this version of the server", NullS);
|
||||||
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -1060,40 +1084,49 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
||||||
char buf[256];
|
char buf[256];
|
||||||
strxnmov(buf, sizeof(buf) - 1, "Loading of ",
|
strxnmov(buf, sizeof(buf) - 1, "Loading of ",
|
||||||
plugin_maturity_names[plugin->maturity],
|
plugin_maturity_names[plugin->maturity],
|
||||||
" plugins is prohibited by --plugin-maturity=",
|
" plugin ", tmp.name.str,
|
||||||
|
" is prohibited by --plugin-maturity=",
|
||||||
plugin_maturity_names[plugin_maturity],
|
plugin_maturity_names[plugin_maturity],
|
||||||
NullS);
|
NullS);
|
||||||
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, 0, buf);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
tmp.plugin= plugin;
|
tmp.plugin= plugin;
|
||||||
tmp.name.str= (char *)plugin->name;
|
|
||||||
tmp.name.length= name_len;
|
|
||||||
tmp.ref_count= 0;
|
tmp.ref_count= 0;
|
||||||
tmp.state= PLUGIN_IS_UNINITIALIZED;
|
tmp.state= PLUGIN_IS_UNINITIALIZED;
|
||||||
tmp.load_option= PLUGIN_ON;
|
tmp.load_option= PLUGIN_ON;
|
||||||
if (test_plugin_options(tmp_root, &tmp, argc, argv))
|
if (test_plugin_options(tmp_root, &tmp, argc, argv))
|
||||||
tmp.state= PLUGIN_IS_DISABLED;
|
tmp.state= PLUGIN_IS_DISABLED;
|
||||||
|
|
||||||
if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
|
if (!(tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
|
||||||
{
|
{
|
||||||
plugin_array_version++;
|
mysql_del_sys_var_chain(tmp.system_vars);
|
||||||
if (!my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
|
restore_pluginvar_names(tmp.system_vars);
|
||||||
{
|
goto err;
|
||||||
init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
}
|
|
||||||
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
|
||||||
}
|
}
|
||||||
mysql_del_sys_var_chain(tmp.system_vars);
|
plugin_array_version++;
|
||||||
restore_pluginvar_names(tmp.system_vars);
|
if (my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr))
|
||||||
goto err;
|
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
|
||||||
}
|
init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
|
||||||
}
|
|
||||||
report_error(report, ER_CANT_FIND_DL_ENTRY, name->str);
|
if (name->str)
|
||||||
|
DBUG_RETURN(FALSE); // all done
|
||||||
|
|
||||||
|
oks++;
|
||||||
|
tmp.plugin_dl->ref_count++;
|
||||||
|
continue; // otherwise - go on
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
errs++;
|
||||||
|
if (name->str)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errs == 0 && oks == 0) // no plugin was found
|
||||||
|
report_error(report, ER_CANT_FIND_DL_ENTRY, name->str);
|
||||||
|
|
||||||
plugin_dl_del(dl);
|
plugin_dl_del(dl);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(errs > 0 || oks == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1760,8 +1793,6 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
||||||
{
|
{
|
||||||
char buffer[FN_REFLEN];
|
char buffer[FN_REFLEN];
|
||||||
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
|
LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
|
||||||
struct st_plugin_dl *plugin_dl;
|
|
||||||
struct st_maria_plugin *plugin;
|
|
||||||
char *p= buffer;
|
char *p= buffer;
|
||||||
DBUG_ENTER("plugin_load_list");
|
DBUG_ENTER("plugin_load_list");
|
||||||
while (list)
|
while (list)
|
||||||
|
@ -1791,19 +1822,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
|
||||||
|
|
||||||
dl= name;
|
dl= name;
|
||||||
mysql_mutex_lock(&LOCK_plugin);
|
mysql_mutex_lock(&LOCK_plugin);
|
||||||
if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
|
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
||||||
{
|
name.str= 0; // load everything
|
||||||
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
|
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
||||||
{
|
goto error;
|
||||||
name.str= (char *) plugin->name;
|
|
||||||
name.length= strlen(name.str);
|
|
||||||
|
|
||||||
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
|
|
||||||
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
plugin_dl_del(&dl); // reduce ref count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1970,14 +1992,68 @@ void plugin_shutdown(void)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
complete plugin installation (after plugin_add).
|
||||||
|
|
||||||
bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl)
|
That is, initialize it, and update mysql.plugin table
|
||||||
|
*/
|
||||||
|
static bool finalize_install(THD *thd, TABLE *table, const LEX_STRING *name)
|
||||||
|
{
|
||||||
|
struct st_plugin_int *tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
|
||||||
|
int error;
|
||||||
|
DBUG_ASSERT(tmp);
|
||||||
|
mysql_mutex_assert_owner(&LOCK_plugin);
|
||||||
|
|
||||||
|
if (tmp->state == PLUGIN_IS_DISABLED)
|
||||||
|
{
|
||||||
|
if (global_system_variables.log_warnings)
|
||||||
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
|
||||||
|
name->str, "Plugin is disabled");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
|
||||||
|
if (plugin_initialize(tmp))
|
||||||
|
{
|
||||||
|
report_error(REPORT_TO_USER, ER_CANT_INITIALIZE_UDF, name->str,
|
||||||
|
"Plugin initialization function failed.");
|
||||||
|
tmp->state= PLUGIN_IS_DELETED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We do not replicate the INSTALL PLUGIN statement. Disable binlogging
|
||||||
|
of the insert into the plugin table, so that it is not replicated in
|
||||||
|
row based mode.
|
||||||
|
*/
|
||||||
|
tmp_disable_binlog(thd);
|
||||||
|
table->use_all_columns();
|
||||||
|
restore_record(table, s->default_values);
|
||||||
|
table->field[0]->store(name->str, name->length, system_charset_info);
|
||||||
|
table->field[1]->store(tmp->plugin_dl->dl.str, tmp->plugin_dl->dl.length,
|
||||||
|
files_charset_info);
|
||||||
|
error= table->file->ha_write_row(table->record[0]);
|
||||||
|
reenable_binlog(thd);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
table->file->print_error(error, MYF(0));
|
||||||
|
tmp->state= PLUGIN_IS_DELETED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
|
||||||
|
const LEX_STRING *dl_arg)
|
||||||
{
|
{
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
int error, argc=orig_argc;
|
LEX_STRING dl= *dl_arg;
|
||||||
|
bool error;
|
||||||
|
int argc=orig_argc;
|
||||||
char **argv=orig_argv;
|
char **argv=orig_argv;
|
||||||
struct st_plugin_int *tmp;
|
|
||||||
DBUG_ENTER("mysql_install_plugin");
|
DBUG_ENTER("mysql_install_plugin");
|
||||||
|
|
||||||
if (opt_noacl)
|
if (opt_noacl)
|
||||||
|
@ -2024,53 +2100,34 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
|
||||||
report_error(REPORT_TO_USER, ER_PLUGIN_IS_NOT_LOADED, name->str);
|
report_error(REPORT_TO_USER, ER_PLUGIN_IS_NOT_LOADED, name->str);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
error= plugin_add(thd->mem_root, name, dl, &argc, argv, REPORT_TO_USER);
|
error= plugin_add(thd->mem_root, name, &dl, &argc, argv, REPORT_TO_USER);
|
||||||
if (argv)
|
if (argv)
|
||||||
free_defaults(argv);
|
free_defaults(argv);
|
||||||
mysql_rwlock_unlock(&LOCK_system_variables_hash);
|
mysql_rwlock_unlock(&LOCK_system_variables_hash);
|
||||||
|
|
||||||
if (error || !(tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
|
if (error)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (tmp->state == PLUGIN_IS_DISABLED)
|
if (name->str)
|
||||||
{
|
error= finalize_install(thd, table, name);
|
||||||
if (global_system_variables.log_warnings)
|
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
|
|
||||||
name->str, "Plugin is disabled");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (plugin_initialize(tmp))
|
st_plugin_dl *plugin_dl= plugin_dl_find(&dl);
|
||||||
|
struct st_maria_plugin *plugin;
|
||||||
|
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
LEX_STRING str= { const_cast<char*>(plugin->name), strlen(plugin->name) };
|
||||||
"Plugin initialization function failed.");
|
error|= finalize_install(thd, table, &str);
|
||||||
goto deinit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
We do not replicate the INSTALL PLUGIN statement. Disable binlogging
|
|
||||||
of the insert into the plugin table, so that it is not replicated in
|
|
||||||
row based mode.
|
|
||||||
*/
|
|
||||||
tmp_disable_binlog(thd);
|
|
||||||
table->use_all_columns();
|
|
||||||
restore_record(table, s->default_values);
|
|
||||||
table->field[0]->store(name->str, name->length, system_charset_info);
|
|
||||||
table->field[1]->store(dl->str, dl->length, files_charset_info);
|
|
||||||
error= table->file->ha_write_row(table->record[0]);
|
|
||||||
reenable_binlog(thd);
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
|
||||||
table->file->print_error(error, MYF(0));
|
|
||||||
goto deinit;
|
goto deinit;
|
||||||
}
|
|
||||||
|
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
mysql_mutex_unlock(&LOCK_plugin);
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
deinit:
|
deinit:
|
||||||
tmp->state= PLUGIN_IS_DELETED;
|
|
||||||
reap_needed= true;
|
reap_needed= true;
|
||||||
reap_plugins();
|
reap_plugins();
|
||||||
err:
|
err:
|
||||||
|
@ -2079,11 +2136,70 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
|
static bool do_uninstall(THD *thd, TABLE *table, const LEX_STRING *name)
|
||||||
|
{
|
||||||
|
struct st_plugin_int *plugin;
|
||||||
|
mysql_mutex_assert_owner(&LOCK_plugin);
|
||||||
|
|
||||||
|
if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
|
||||||
|
{
|
||||||
|
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!plugin->plugin_dl)
|
||||||
|
{
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
WARN_PLUGIN_DELETE_BUILTIN, ER(WARN_PLUGIN_DELETE_BUILTIN));
|
||||||
|
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
|
||||||
|
{
|
||||||
|
my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->state= PLUGIN_IS_DELETED;
|
||||||
|
if (plugin->ref_count)
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
WARN_PLUGIN_BUSY, ER(WARN_PLUGIN_BUSY));
|
||||||
|
else
|
||||||
|
reap_needed= true;
|
||||||
|
|
||||||
|
uchar user_key[MAX_KEY_LENGTH];
|
||||||
|
table->use_all_columns();
|
||||||
|
table->field[0]->store(name->str, name->length, system_charset_info);
|
||||||
|
key_copy(user_key, table->record[0], table->key_info,
|
||||||
|
table->key_info->key_length);
|
||||||
|
if (! table->file->ha_index_read_idx_map(table->record[0], 0, user_key,
|
||||||
|
HA_WHOLE_KEY, HA_READ_KEY_EXACT))
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
/*
|
||||||
|
We do not replicate the UNINSTALL PLUGIN statement. Disable binlogging
|
||||||
|
of the delete from the plugin table, so that it is not replicated in
|
||||||
|
row based mode.
|
||||||
|
*/
|
||||||
|
tmp_disable_binlog(thd);
|
||||||
|
error= table->file->ha_delete_row(table->record[0]);
|
||||||
|
reenable_binlog(thd);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
table->file->print_error(error, MYF(0));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
|
||||||
|
const LEX_STRING *dl_arg)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
struct st_plugin_int *plugin;
|
LEX_STRING dl= *dl_arg;
|
||||||
|
bool error= false;
|
||||||
DBUG_ENTER("mysql_uninstall_plugin");
|
DBUG_ENTER("mysql_uninstall_plugin");
|
||||||
|
|
||||||
if (opt_noacl)
|
if (opt_noacl)
|
||||||
|
@ -2116,67 +2232,28 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
|
||||||
When audit event is triggered during [UN]INSTALL PLUGIN, plugin
|
When audit event is triggered during [UN]INSTALL PLUGIN, plugin
|
||||||
list iterator acquires the same lock (within the same thread)
|
list iterator acquires the same lock (within the same thread)
|
||||||
second time.
|
second time.
|
||||||
|
|
||||||
This hack should be removed when LOCK_plugin is fixed so it
|
|
||||||
protects only what it supposed to protect.
|
|
||||||
*/
|
*/
|
||||||
mysql_audit_acquire_plugins(thd, MYSQL_AUDIT_GENERAL_CLASS);
|
mysql_audit_acquire_plugins(thd, MYSQL_AUDIT_GENERAL_CLASS);
|
||||||
|
|
||||||
mysql_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);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!plugin->plugin_dl)
|
|
||||||
{
|
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
WARN_PLUGIN_DELETE_BUILTIN, ER(WARN_PLUGIN_DELETE_BUILTIN));
|
|
||||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (plugin->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
|
|
||||||
{
|
|
||||||
my_error(ER_PLUGIN_IS_PERMANENT, MYF(0), name->str);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin->state= PLUGIN_IS_DELETED;
|
if (name->str)
|
||||||
if (plugin->ref_count)
|
error= do_uninstall(thd, table, name);
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
WARN_PLUGIN_BUSY, ER(WARN_PLUGIN_BUSY));
|
|
||||||
else
|
else
|
||||||
reap_needed= true;
|
|
||||||
reap_plugins();
|
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
|
||||||
|
|
||||||
uchar user_key[MAX_KEY_LENGTH];
|
|
||||||
table->use_all_columns();
|
|
||||||
table->field[0]->store(name->str, name->length, system_charset_info);
|
|
||||||
key_copy(user_key, table->record[0], table->key_info,
|
|
||||||
table->key_info->key_length);
|
|
||||||
if (! table->file->ha_index_read_idx_map(table->record[0], 0, user_key,
|
|
||||||
HA_WHOLE_KEY, HA_READ_KEY_EXACT))
|
|
||||||
{
|
{
|
||||||
int error;
|
fix_dl_name(thd->mem_root, &dl);
|
||||||
/*
|
st_plugin_dl *plugin_dl= plugin_dl_find(&dl);
|
||||||
We do not replicate the UNINSTALL PLUGIN statement. Disable binlogging
|
struct st_maria_plugin *plugin;
|
||||||
of the delete from the plugin table, so that it is not replicated in
|
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
|
||||||
row based mode.
|
|
||||||
*/
|
|
||||||
tmp_disable_binlog(thd);
|
|
||||||
error= table->file->ha_delete_row(table->record[0]);
|
|
||||||
reenable_binlog(thd);
|
|
||||||
if (error)
|
|
||||||
{
|
{
|
||||||
table->file->print_error(error, MYF(0));
|
LEX_STRING str= { const_cast<char*>(plugin->name), strlen(plugin->name) };
|
||||||
DBUG_RETURN(TRUE);
|
error|= do_uninstall(thd, table, &str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN(FALSE);
|
reap_plugins();
|
||||||
err:
|
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
mysql_mutex_unlock(&LOCK_plugin);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,8 @@ extern void plugin_unlock(THD *thd, plugin_ref plugin);
|
||||||
extern void plugin_unlock_list(THD *thd, plugin_ref *list, uint count);
|
extern void plugin_unlock_list(THD *thd, plugin_ref *list, uint count);
|
||||||
extern bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
|
extern bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
|
||||||
const LEX_STRING *dl);
|
const LEX_STRING *dl);
|
||||||
extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
|
extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
|
||||||
|
const LEX_STRING *dl);
|
||||||
extern bool plugin_register_builtin(struct st_mysql_plugin *plugin);
|
extern bool plugin_register_builtin(struct st_mysql_plugin *plugin);
|
||||||
extern void plugin_thdvar_init(THD *thd);
|
extern void plugin_thdvar_init(THD *thd);
|
||||||
extern void plugin_thdvar_cleanup(THD *thd);
|
extern void plugin_thdvar_cleanup(THD *thd);
|
||||||
|
|
|
@ -15141,6 +15141,13 @@ install:
|
||||||
lex->comment= $3;
|
lex->comment= $3;
|
||||||
lex->ident= $5;
|
lex->ident= $5;
|
||||||
}
|
}
|
||||||
|
| INSTALL_SYM SONAME_SYM TEXT_STRING_sys
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->sql_command= SQLCOM_INSTALL_PLUGIN;
|
||||||
|
lex->comment= null_lex_str;
|
||||||
|
lex->ident= $3;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
|
@ -15150,6 +15157,13 @@ uninstall:
|
||||||
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
|
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
|
||||||
lex->comment= $3;
|
lex->comment= $3;
|
||||||
}
|
}
|
||||||
|
| UNINSTALL_SYM SONAME_SYM TEXT_STRING_sys
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
|
||||||
|
lex->comment= null_lex_str;
|
||||||
|
lex->ident= $3;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Avoid compiler warning from sql_yacc.cc where yyerrlab1 is not used */
|
/* Avoid compiler warning from sql_yacc.cc where yyerrlab1 is not used */
|
||||||
|
|
|
@ -19,17 +19,23 @@
|
||||||
|
|
||||||
@brief
|
@brief
|
||||||
The ha_example engine is a stubbed storage engine for example purposes only;
|
The ha_example engine is a stubbed storage engine for example purposes only;
|
||||||
it does nothing at this point. Its purpose is to provide a source
|
it does almost nothing at this point. Its purpose is to provide a source
|
||||||
code illustration of how to begin writing new storage engines; see also
|
code illustration of how to begin writing new storage engines; see also
|
||||||
/storage/example/ha_example.h.
|
storage/example/ha_example.h.
|
||||||
|
|
||||||
|
Additionally, this file includes an example of a daemon plugin which does
|
||||||
|
nothing at all - absolutely nothing, even less than example storage engine.
|
||||||
|
But it shows that one dll/so can contain more than one plugin.
|
||||||
|
|
||||||
@details
|
@details
|
||||||
ha_example will let you create/open/delete tables, but
|
ha_example will let you create/open/delete tables, but
|
||||||
nothing further (for example, indexes are not supported nor can data
|
nothing further (for example, indexes are not supported nor can data
|
||||||
be stored in the table). Use this example as a template for
|
be stored in the table). It also provides new status (example_func_example)
|
||||||
implementing the same functionality in your own storage engine. You
|
and system (example_ulong_var and example_enum_var) variables.
|
||||||
can enable the example storage engine in your build by doing the
|
|
||||||
following during your build process:<br> ./configure
|
Use this example as a template for implementing the same functionality in
|
||||||
|
your own storage engine. You can enable the example storage engine in your
|
||||||
|
build by doing the following during your build process:<br> ./configure
|
||||||
--with-example-storage-engine
|
--with-example-storage-engine
|
||||||
|
|
||||||
Once this is done, MySQL will let you create tables with:<br>
|
Once this is done, MySQL will let you create tables with:<br>
|
||||||
|
@ -1111,6 +1117,9 @@ static struct st_mysql_show_var func_status[]=
|
||||||
{0,0,SHOW_UNDEF}
|
{0,0,SHOW_UNDEF}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct st_mysql_daemon unusable_example=
|
||||||
|
{ MYSQL_DAEMON_INTERFACE_VERSION };
|
||||||
|
|
||||||
mysql_declare_plugin(example)
|
mysql_declare_plugin(example)
|
||||||
{
|
{
|
||||||
MYSQL_STORAGE_ENGINE_PLUGIN,
|
MYSQL_STORAGE_ENGINE_PLUGIN,
|
||||||
|
@ -1138,10 +1147,25 @@ maria_declare_plugin(example)
|
||||||
PLUGIN_LICENSE_GPL,
|
PLUGIN_LICENSE_GPL,
|
||||||
example_init_func, /* Plugin Init */
|
example_init_func, /* Plugin Init */
|
||||||
example_done_func, /* Plugin Deinit */
|
example_done_func, /* Plugin Deinit */
|
||||||
0x0001 /* 0.1 */,
|
0x0001, /* version number (0.1) */
|
||||||
func_status, /* status variables */
|
func_status, /* status variables */
|
||||||
example_system_variables, /* system variables */
|
example_system_variables, /* system variables */
|
||||||
"0.1", /* string version */
|
"0.1", /* string version */
|
||||||
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
|
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MYSQL_DAEMON_PLUGIN,
|
||||||
|
&unusable_example,
|
||||||
|
"UNUSABLE",
|
||||||
|
"Sergei Golubchik",
|
||||||
|
"Unusable Daemon",
|
||||||
|
PLUGIN_LICENSE_GPL,
|
||||||
|
NULL, /* Plugin Init */
|
||||||
|
NULL, /* Plugin Deinit */
|
||||||
|
0x030E, /* version number (3.14) */
|
||||||
|
NULL, /* status variables */
|
||||||
|
NULL, /* system variables */
|
||||||
|
"3.14.15.926" , /* version, as a string */
|
||||||
|
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
|
||||||
}
|
}
|
||||||
maria_declare_plugin_end;
|
maria_declare_plugin_end;
|
||||||
|
|
Loading…
Reference in a new issue