Commit 6513b838 authored by Daniel Black's avatar Daniel Black Committed by Sergei Golubchik

MDEV-16294: postfix - INSTALL PLUGIN IF NOT EXISTS

Fix also UNINSTALL SONAME IF EXISTS

Complete test case to INSTALL/UNINSTALL errors are generated
parent bb85d92d
......@@ -336,29 +336,45 @@ DROP TABLE t1;
# UNINSTALL IF EXISTS PLUGIN|SONAME name
#
#
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
plugin_name
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE
INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
plugin_name
EXAMPLE
INSTALL PLUGIN IF NOT EXISTS EXAMPLE SONAME 'ha_example';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE
EXAMPLE ACTIVE STORAGE ENGINE
INSTALL PLUGIN example SONAME 'ha_example';
ERROR HY000: Plugin 'example' already installed
INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
Warnings:
Note 1968 Plugin 'example' already installed
SHOW WARNINGS;
Level Code Message
Note 1968 Plugin 'EXAMPLE' already installed
INSTALL SONAME IF NOT EXISTS 'ha_example';
Note 1968 Plugin 'example' already installed
UNINSTALL PLUGIN IF EXISTS example;
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE
UNINSTALL PLUGIN IF EXISTS example;
Warnings:
Note 1305 PLUGIN example does not exist
SHOW WARNINGS;
Level Code Message
Note 1968 Plugin 'EXAMPLE' already installed
UNINSTALL PLUGIN IF EXISTS example;
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
plugin_name
UNUSABLE
Note 1305 PLUGIN example does not exist
UNINSTALL PLUGIN example;
ERROR 42000: PLUGIN example does not exist
INSTALL SONAME IF NOT EXISTS 'ha_example';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE
EXAMPLE ACTIVE STORAGE ENGINE
UNUSABLE ACTIVE DAEMON
INSTALL SONAME IF NOT EXISTS 'ha_example';
UNINSTALL SONAME IF EXISTS 'ha_example';
UNINSTALL SONAME IF EXISTS 'ha_example';
Warnings:
Note 1305 PLUGIN EXAMPLE does not exist
Note 1305 SONAME ha_example.so does not exist
SHOW WARNINGS;
Level Code Message
Note 1305 PLUGIN EXAMPLE does not exist
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
plugin_name
Note 1305 SONAME ha_example.so does not exist
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME PLUGIN_STATUS PLUGIN_TYPE
UNINSTALL SONAME 'ha_example';
ERROR 42000: SONAME ha_example.so does not exist
......@@ -272,15 +272,38 @@ DROP TABLE t1;
--echo #
--echo #
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
--replace_regex /\.dll/.so/
--error ER_PLUGIN_INSTALLED
INSTALL PLUGIN example SONAME 'ha_example';
INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
INSTALL PLUGIN IF NOT EXISTS EXAMPLE SONAME 'ha_example';
SHOW WARNINGS;
INSTALL SONAME IF NOT EXISTS 'ha_example';
SHOW WARNINGS;
UNINSTALL PLUGIN IF EXISTS example;
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
UNINSTALL PLUGIN IF EXISTS example;
SHOW WARNINGS;
--error 1305
UNINSTALL PLUGIN example;
INSTALL SONAME IF NOT EXISTS 'ha_example';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
# note: installing soname multiple times doesn't cause errors or warnings
INSTALL SONAME IF NOT EXISTS 'ha_example';
UNINSTALL SONAME IF EXISTS 'ha_example';
UNINSTALL SONAME IF EXISTS 'ha_example';
SHOW WARNINGS;
select plugin_name from information_schema.plugins where plugin_library like 'ha_example%';
select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%';
--error 1305
UNINSTALL SONAME 'ha_example';
......@@ -280,6 +280,7 @@ struct st_mysql_sys_var
MYSQL_PLUGIN_VAR_HEADER;
};
enum install_status { INSTALL_GOOD, INSTALL_FAIL_WARN_OK, INSTALL_FAIL_NOT_OK };
/*
sys_var class for access to all plugin variables visible to the user
*/
......@@ -1077,8 +1078,8 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
NOTE
Requires that a write-lock is held on LOCK_system_variables_hash
*/
static bool plugin_add(MEM_ROOT *tmp_root, THD *thd,
const LEX_CSTRING *name, LEX_CSTRING *dl, myf MyFlags)
static enum install_status plugin_add(MEM_ROOT *tmp_root, bool if_not_exists,
const LEX_CSTRING *name, LEX_CSTRING *dl, myf MyFlags)
{
struct st_plugin_int tmp, *maybe_dupe;
struct st_maria_plugin *plugin;
......@@ -1088,21 +1089,22 @@ static bool plugin_add(MEM_ROOT *tmp_root, THD *thd,
if (name->str && plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
if (thd && thd->lex->create_info.if_not_exists())
if (if_not_exists)
{
my_error(ER_PLUGIN_INSTALLED, MyFlags & ME_WARNING, name->str);
my_error(ER_PLUGIN_INSTALLED, MyFlags | ME_NOTE, name->str);
DBUG_RETURN(INSTALL_FAIL_WARN_OK);
}
else
{
my_error(ER_PLUGIN_INSTALLED, MyFlags, name->str);
DBUG_RETURN(INSTALL_FAIL_NOT_OK);
}
DBUG_RETURN(TRUE);
}
/* Clear the whole struct to catch future extensions. */
bzero((char*) &tmp, sizeof(tmp));
fix_dl_name(tmp_root, dl);
if (! (tmp.plugin_dl= plugin_dl_add(dl, MyFlags)))
DBUG_RETURN(TRUE);
DBUG_RETURN(INSTALL_FAIL_NOT_OK);
/* Find plugin by name */
for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++)
{
......@@ -1128,7 +1130,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, THD *thd,
if (plugin->name != maybe_dupe->plugin->name)
{
my_error(ER_UDF_EXISTS, MyFlags, plugin->name);
DBUG_RETURN(TRUE);
DBUG_RETURN(INSTALL_FAIL_NOT_OK);
}
dupes++;
continue; // already installed
......@@ -1180,7 +1182,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, THD *thd,
init_alloc_root(&tmp_plugin_ptr->mem_root, "plugin", 4096, 4096, MYF(0));
if (name->str)
DBUG_RETURN(FALSE); // all done
DBUG_RETURN(INSTALL_GOOD); // all done
oks++;
tmp.plugin_dl->ref_count++;
......@@ -1198,7 +1200,9 @@ static bool plugin_add(MEM_ROOT *tmp_root, THD *thd,
my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, name->str);
plugin_dl_del(tmp.plugin_dl);
DBUG_RETURN(errs > 0 || oks + dupes == 0);
if (errs > 0 || oks + dupes == 0)
DBUG_RETURN(INSTALL_FAIL_NOT_OK);
DBUG_RETURN(INSTALL_GOOD);
}
static void plugin_variables_deinit(struct st_plugin_int *plugin)
......@@ -1854,7 +1858,7 @@ static void plugin_load(MEM_ROOT *tmp_root)
the mutex here to satisfy the assert
*/
mysql_mutex_lock(&LOCK_plugin);
plugin_add(tmp_root, NULL, &name, &dl, MYF(ME_ERROR_LOG));
plugin_add(tmp_root, false, &name, &dl, MYF(ME_ERROR_LOG));
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
mysql_mutex_unlock(&LOCK_plugin);
}
......@@ -1909,16 +1913,16 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list)
mysql_mutex_lock(&LOCK_plugin);
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
name.str= 0; // load everything
if (plugin_add(tmp_root, NULL, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl,
MYF(ME_ERROR_LOG)))
if (plugin_add(tmp_root, false, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl,
MYF(ME_ERROR_LOG)) != INSTALL_GOOD)
goto error;
}
else
{
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
mysql_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, NULL, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl,
MYF(ME_ERROR_LOG)))
if (plugin_add(tmp_root, false, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl,
MYF(ME_ERROR_LOG)) != INSTALL_GOOD)
goto error;
}
mysql_mutex_unlock(&LOCK_plugin);
......@@ -2153,7 +2157,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name,
TABLE_LIST tables;
TABLE *table;
LEX_CSTRING dl= *dl_arg;
bool error;
enum install_status error;
int argc=orig_argc;
char **argv=orig_argv;
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] =
......@@ -2201,12 +2205,13 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name,
mysql_audit_acquire_plugins(thd, event_class_mask);
mysql_mutex_lock(&LOCK_plugin);
error= plugin_add(thd->mem_root, thd, name, &dl, MYF(0));
if (unlikely(error))
error= plugin_add(thd->mem_root, thd->lex->create_info.if_not_exists(), name, &dl, MYF(0));
if (unlikely(error != INSTALL_GOOD))
goto err;
if (name->str)
error= finalize_install(thd, table, name, &argc, argv);
error= finalize_install(thd, table, name, &argc, argv)
? INSTALL_FAIL_NOT_OK : INSTALL_GOOD;
else
{
st_plugin_dl *plugin_dl= plugin_dl_find(&dl);
......@@ -2214,11 +2219,12 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name,
for (plugin= plugin_dl->plugins; plugin->info; plugin++)
{
LEX_CSTRING str= { plugin->name, strlen(plugin->name) };
error|= finalize_install(thd, table, &str, &argc, argv);
if (finalize_install(thd, table, &str, &argc, argv))
error= INSTALL_FAIL_NOT_OK;
}
}
if (unlikely(error))
if (unlikely(error != INSTALL_GOOD))
{
reap_needed= true;
reap_plugins();
......@@ -2227,7 +2233,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name,
mysql_mutex_unlock(&LOCK_plugin);
if (argv)
free_defaults(argv);
DBUG_RETURN(error);
DBUG_RETURN(error == INSTALL_FAIL_NOT_OK);
#ifdef WITH_WSREP
error:
DBUG_RETURN(TRUE);
......@@ -2375,8 +2381,15 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_CSTRING *name,
}
else
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SONAME", dl.str);
error= true;
if (thd->lex->if_exists())
{
my_error(ER_SP_DOES_NOT_EXIST, ME_NOTE, "SONAME", dl.str);
}
else
{
error= true;
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SONAME", dl.str);
}
}
}
reap_plugins();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment