diff --git a/mysql-test/main/plugin.result b/mysql-test/main/plugin.result index 3a141a25b5c..b5ac9d3160a 100644 --- a/mysql-test/main/plugin.result +++ b/mysql-test/main/plugin.result @@ -331,3 +331,34 @@ UNINSTALL PLUGIN example; RENAME TABLE t1 TO t2; ERROR 42S02: Table 'test.t1' doesn't exist DROP TABLE t1; +# +# INSTALL IF NOT EXISTS [PLUGIN name] SONAME library / +# UNINSTALL IF EXISTS PLUGIN|SONAME name +# +# +select plugin_name from information_schema.plugins where plugin_library like 'ha_example%'; +plugin_name +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'; +SHOW WARNINGS; +Level Code Message +Note 1968 Plugin 'EXAMPLE' already installed +INSTALL SONAME IF NOT EXISTS 'ha_example'; +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 +UNINSTALL SONAME IF EXISTS 'ha_example'; +Warnings: +Note 1305 PLUGIN EXAMPLE 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 diff --git a/mysql-test/main/plugin.test b/mysql-test/main/plugin.test index 68c4d5afd64..3dad1ab2f73 100644 --- a/mysql-test/main/plugin.test +++ b/mysql-test/main/plugin.test @@ -265,3 +265,22 @@ UNINSTALL PLUGIN example; --error ER_NO_SUCH_TABLE RENAME TABLE t1 TO t2; DROP TABLE t1; + +--echo # +--echo # INSTALL IF NOT EXISTS [PLUGIN name] SONAME library / +--echo # UNINSTALL IF EXISTS PLUGIN|SONAME name +--echo # +--echo # + +select plugin_name from information_schema.plugins where plugin_library like '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%'; +UNINSTALL SONAME IF EXISTS 'ha_example'; +SHOW WARNINGS; +select plugin_name from information_schema.plugins where plugin_library like 'ha_example%'; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8c231d9b8f7..1a288716953 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1077,7 +1077,7 @@ 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, +static bool plugin_add(MEM_ROOT *tmp_root, THD *thd, const LEX_CSTRING *name, LEX_CSTRING *dl, myf MyFlags) { struct st_plugin_int tmp, *maybe_dupe; @@ -1088,7 +1088,14 @@ static bool plugin_add(MEM_ROOT *tmp_root, if (name->str && plugin_find_internal(name, MYSQL_ANY_PLUGIN)) { - my_error(ER_PLUGIN_INSTALLED, MyFlags, name->str); + if (thd && thd->lex->create_info.if_not_exists()) + { + my_error(ER_PLUGIN_INSTALLED, MyFlags & ME_WARNING, name->str); + } + else + { + my_error(ER_PLUGIN_INSTALLED, MyFlags, name->str); + } DBUG_RETURN(TRUE); } /* Clear the whole struct to catch future extensions. */ @@ -1847,7 +1854,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, &name, &dl, MYF(ME_ERROR_LOG)); + plugin_add(tmp_root, NULL, &name, &dl, MYF(ME_ERROR_LOG)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); mysql_mutex_unlock(&LOCK_plugin); } @@ -1902,7 +1909,7 @@ 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, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, + if (plugin_add(tmp_root, NULL, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, MYF(ME_ERROR_LOG))) goto error; } @@ -1910,7 +1917,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list) { free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); mysql_mutex_lock(&LOCK_plugin); - if (plugin_add(tmp_root, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, + if (plugin_add(tmp_root, NULL, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, MYF(ME_ERROR_LOG))) goto error; } @@ -2194,7 +2201,7 @@ 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, name, &dl, MYF(0)); + error= plugin_add(thd->mem_root, thd, name, &dl, MYF(0)); if (unlikely(error)) goto err; @@ -2236,8 +2243,17 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_CSTRING *name) if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)) || plugin->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_DYING)) { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); - return 1; + if (thd->lex->if_exists()) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, + ER_THD(thd, ER_SP_DOES_NOT_EXIST), "PLUGIN", name->str); + return 0; + } + else + { + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); + return 1; + } } if (!plugin->plugin_dl) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3e4648f4fd1..0d5c6608ec1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -17490,35 +17490,45 @@ opt_migrate: ; install: - INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys + INSTALL_SYM PLUGIN_SYM opt_if_not_exists ident SONAME_SYM TEXT_STRING_sys { LEX *lex= Lex; + lex->create_info.init(); + if (lex->add_create_options_with_check($3)) + MYSQL_YYABORT; lex->sql_command= SQLCOM_INSTALL_PLUGIN; - lex->comment= $3; - lex->ident= $5; + lex->comment= $4; + lex->ident= $6; } - | INSTALL_SYM SONAME_SYM TEXT_STRING_sys + | INSTALL_SYM SONAME_SYM opt_if_not_exists TEXT_STRING_sys { LEX *lex= Lex; + lex->create_info.init(); + if (lex->add_create_options_with_check($3)) + MYSQL_YYABORT; lex->sql_command= SQLCOM_INSTALL_PLUGIN; lex->comment= null_clex_str; - lex->ident= $3; + lex->ident= $4; } ; uninstall: - UNINSTALL_SYM PLUGIN_SYM ident + UNINSTALL_SYM PLUGIN_SYM opt_if_exists ident { LEX *lex= Lex; + if (lex->add_create_options_with_check($3)) + MYSQL_YYABORT; lex->sql_command= SQLCOM_UNINSTALL_PLUGIN; - lex->comment= $3; + lex->comment= $4; } - | UNINSTALL_SYM SONAME_SYM TEXT_STRING_sys + | UNINSTALL_SYM SONAME_SYM opt_if_exists TEXT_STRING_sys { LEX *lex= Lex; + if (lex->add_create_options_with_check($3)) + MYSQL_YYABORT; lex->sql_command= SQLCOM_UNINSTALL_PLUGIN; lex->comment= null_clex_str; - lex->ident= $3; + lex->ident= $4; } ;