List:Internals« Previous MessageNext Message »
From:svoj Date:September 20 2005 6:46pm
Subject:bk commit into 5.0 tree (svoj:1.1910)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of svoj. When svoj does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1910 05/09/20 23:46:36 svoj@stripped +9 -0
  WL#2575 - Fulltext: Parser plugin for FTS
  Added INSTALL PLUGIN syntax and handler.
  Added UNINSTALL PLUGIN syntax (no handler yet).
  Slightly improved coding style.
  HAVE_DLOPEN moved into sql_plugin.cc.

  sql/table.cc
    1.180 05/09/20 23:46:30 svoj@stripped +0 -2
    HAVE_DLOPEN moved into sql_plugin.cc.

  sql/sql_yacc.yy
    1.415 05/09/20 23:46:30 svoj@stripped +27 -7
    Added INSTALL/UNINSTALL plugin syntax.

  sql/sql_plugin.h
    1.6 05/09/20 23:46:30 svoj@stripped +2 -2
    HAVE_DLOPEN moved into sql_plugin.cc.
    Added INSTALL/UNINSTALL plugin handlers.

  sql/sql_plugin.cc
    1.9 05/09/20 23:46:30 svoj@stripped +137 -31
    Removed space after function name.
    All plugin related HAVE_DLOPEN moved into sql_plugin.cc.
    Added INSTALL PLUGIN handler.
    UNINSTALL PLUGIN handler does nothing yet.

  sql/sql_parse.cc
    1.453 05/09/20 23:46:30 svoj@stripped +13 -0
    Added INSTALL/UNINSTALL SQL commands.

  sql/sql_lex.h
    1.191 05/09/20 23:46:30 svoj@stripped +2 -1
    Added INSTALL/UNINSTALL SQL commands.
    Added plugin_name, plugin_dl variables.

  sql/set_var.cc
    1.127 05/09/20 23:46:30 svoj@stripped +0 -2
    HAVE_DLOPEN moved into sql_plugin.cc.

  sql/mysqld.cc
    1.488 05/09/20 23:46:29 svoj@stripped +4 -8
    HAVE_DLOPEN moved into sql_plugin.cc.

  sql/lex.h
    1.140 05/09/20 23:46:29 svoj@stripped +4 -1
    INSTALL/UNINSTALL/PLUGIN symbols added.
    UDF_SONAME_SYM renamed to SONAME_SYM.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	svoj
# Host:	svoj-laptop.mysql.com
# Root:	/home/svoj/devel/mysql/CNET/mysql-5.0

--- 1.139/sql/lex.h	2005-08-20 23:24:23 +05:00
+++ 1.140/sql/lex.h	2005-09-20 23:46:29 +05:00
@@ -245,6 +245,7 @@
   { "INSENSITIVE",      SYM(INSENSITIVE_SYM)},
   { "INSERT",		SYM(INSERT)},
   { "INSERT_METHOD",    SYM(INSERT_METHOD)},
+  { "INSTALL",          SYM(INSTALL_SYM)},
   { "INT",		SYM(INT_SYM)},
   { "INT1",		SYM(TINYINT)},
   { "INT2",		SYM(SMALLINT)},
@@ -368,6 +369,7 @@
   { "PARTIAL",		SYM(PARTIAL)},
   { "PASSWORD",		SYM(PASSWORD)},
   { "PHASE",            SYM(PHASE_SYM)},
+  { "PLUGIN",           SYM(PLUGIN_SYM)},
   { "POINT",		SYM(POINT_SYM)},
   { "POLYGON",		SYM(POLYGON)},
   { "PRECISION",	SYM(PRECISION)},
@@ -443,7 +445,7 @@
   { "SNAPSHOT",         SYM(SNAPSHOT_SYM)},
   { "SMALLINT",		SYM(SMALLINT)},
   { "SOME",             SYM(ANY_SYM)},
-  { "SONAME",		SYM(UDF_SONAME_SYM)},
+  { "SONAME",		SYM(SONAME_SYM)},
   { "SOUNDS",		SYM(SOUNDS_SYM)},
   { "SPATIAL",		SYM(SPATIAL_SYM)},
   { "SPECIFIC",         SYM(SPECIFIC_SYM)},
@@ -511,6 +513,7 @@
   { "UNIQUE",		SYM(UNIQUE_SYM)},
   { "UNKNOWN",		SYM(UNKNOWN_SYM)},
   { "UNLOCK",		SYM(UNLOCK_SYM)},
+  { "UNINSTALL",        SYM(UNINSTALL_SYM)},
   { "UNSIGNED",		SYM(UNSIGNED)},
   { "UNTIL",		SYM(UNTIL_SYM)},
   { "UPDATE",		SYM(UPDATE_SYM)},

--- 1.487/sql/mysqld.cc	2005-09-02 01:45:36 +05:00
+++ 1.488/sql/mysqld.cc	2005-09-20 23:46:29 +05:00
@@ -1005,13 +1005,13 @@
   lex_free();				/* Free some memory */
   set_var_free();
   free_charsets();
-#ifdef HAVE_DLOPEN
   if (!opt_noacl)
   {
+#ifdef HAVE_DLOPEN
     udf_free();
+#endif
     plugin_free();
   }
-#endif
   (void) ha_panic(HA_PANIC_CLOSE);	/* close all tables and logs */
   if (tc_log)
     tc_log->close();
@@ -3203,13 +3203,13 @@
   if (!opt_noacl)
     (void) grant_init((THD *)0);
 
-#ifdef HAVE_DLOPEN
   if (!opt_noacl)
   {
     plugin_init();
+#ifdef HAVE_DLOPEN
     udf_init();
-  }
 #endif
+  }
   if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
     opt_skip_slave_start= 1;
   /*
@@ -5469,12 +5469,10 @@
    (gptr*) &global_system_variables.optimizer_search_depth,
    (gptr*) &max_system_variables.optimizer_search_depth,
    0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
-#ifdef HAVE_DLOPEN
   {"plugin-dir", OPT_PLUGIN_DIR,
    "Directory for plugins.",
    (gptr*) &opt_plugin_dir, (gptr*) &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-#endif
    {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
     "The size of the buffer that is allocated when preloading indexes",
     (gptr*) &global_system_variables.preload_buff_size,
@@ -6046,9 +6044,7 @@
 	  sizeof(mysql_real_data_home)-1);
   mysql_data_home_buff[0]=FN_CURLIB;	// all paths are relative from here
   mysql_data_home_buff[1]=0;
-#ifdef HAVE_DLOPEN
   opt_plugin_dir= get_relative_path(LIBDIR);
-#endif
 
   /* Replication parameters */
   master_user= (char*) "test";

--- 1.190/sql/sql_lex.h	2005-07-19 21:06:43 +05:00
+++ 1.191/sql/sql_lex.h	2005-09-20 23:46:30 +05:00
@@ -90,6 +90,7 @@
   SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER,
   SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
   SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
+  SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
   /* This should be the last !!! */
 
   SQLCOM_END
@@ -706,7 +707,7 @@
   sql_exchange *exchange;
   select_result *result;
   Item *default_value, *on_update_value;
-  LEX_STRING comment, ident;
+  LEX_STRING comment, ident, plugin_name, plugin_dl;
   LEX_USER *grant_user;
   XID *xid;
   gptr yacc_yyss,yacc_yyvs;

--- 1.452/sql/sql_parse.cc	2005-07-23 00:37:48 +05:00
+++ 1.453/sql/sql_parse.cc	2005-09-20 23:46:30 +05:00
@@ -4652,6 +4652,19 @@
   case SQLCOM_XA_RECOVER:
     res= mysql_xa_recover(thd);
     break;
+  case SQLCOM_INSTALL_PLUGIN:
+    if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 0))
+      break;
+    if (! (res= mysql_install_plugin(thd, &thd->lex->plugin_name,
+                                     &thd->lex->plugin_dl)))
+      send_ok(thd);
+    break;
+  case SQLCOM_UNINSTALL_PLUGIN:
+    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
+      break;
+    if (! (res= mysql_uninstall_plugin(thd, &thd->lex->plugin_name)))
+      send_ok(thd);
+    break;
   default:
     DBUG_ASSERT(0);                             /* Impossible */
     send_ok(thd);

--- 1.414/sql/sql_yacc.yy	2005-09-02 02:59:48 +05:00
+++ 1.415/sql/sql_yacc.yy	2005-09-20 23:46:30 +05:00
@@ -334,6 +334,7 @@
 %token  INSENSITIVE_SYM
 %token  INSERT
 %token  INSERT_METHOD
+%token  INSTALL_SYM
 %token  INTERVAL_SYM
 %token  INTO
 %token  INT_SYM
@@ -469,6 +470,7 @@
 %token  PASSWORD
 %token  PARAM_MARKER
 %token  PHASE_SYM
+%token  PLUGIN_SYM
 %token  POINTFROMTEXT
 %token  POINT_SYM
 %token  POLYFROMTEXT
@@ -608,13 +610,14 @@
 %token  TYPES_SYM
 %token  TYPE_SYM
 %token  UDF_RETURNS_SYM
-%token  UDF_SONAME_SYM
+%token  SONAME_SYM
 %token  ULONGLONG_NUM
 %token  UNCOMMITTED_SYM
 %token  UNDEFINED_SYM
 %token  UNDERSCORE_CHARSET
 %token  UNDO_SYM
 %token  UNICODE_SYM
+%token  UNINSTALL_SYM
 %token  UNION_SYM
 %token  UNIQUE_SYM
 %token  UNIQUE_USERS
@@ -826,6 +829,7 @@
 	statement sp_suid opt_view_list view_list or_replace algorithm
 	sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
         load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
+        install uninstall
 END_OF_INPUT
 
 %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -886,6 +890,7 @@
 	| handler
 	| help
 	| insert
+        | install
 	| kill
 	| load
 	| lock
@@ -909,6 +914,7 @@
 	| slave
 	| start
 	| truncate
+        | uninstall
 	| unlock
 	| update
 	| use
@@ -1364,7 +1370,7 @@
 	;
 
 create_function_tail:
-	  RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys
+	  RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
 	  {
 	    LEX *lex=Lex;
 	    lex->sql_command = SQLCOM_CREATE_FUNCTION;
@@ -2825,7 +2831,6 @@
         /* empty */               { $$= (struct st_plugin_int*)0; }
 	| WITH PARSER_SYM IDENT_sys
           {
-#ifdef HAVE_DLOPEN
             struct st_plugin_int *plugin;
             if ((plugin= plugin_find(&$3, MYSQL_FTPARSER_PLUGIN)))
               $$= plugin;
@@ -2834,10 +2839,6 @@
               my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
               YYABORT;
             }
-#else
-            my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
-            YYABORT;
-#endif
           }
         ;
 
@@ -7406,10 +7407,12 @@
 	| FLUSH_SYM		{}
 	| HANDLER_SYM		{}
 	| HELP_SYM		{}
+        | INSTALL_SYM           {}
 	| LANGUAGE_SYM          {}
 	| NO_SYM		{}
 	| OPEN_SYM		{}
         | PARSER_SYM            {}
+        | PLUGIN_SYM            {}
         | PREPARE_SYM           {}
 	| REPAIR		{}
 	| RESET_SYM		{}
@@ -7419,10 +7422,12 @@
 	| SECURITY_SYM		{}
 	| SIGNED_SYM		{}
 	| SLAVE			{}
+        | SONAME_SYM            {}
 	| START_SYM		{}
 	| STOP_SYM		{}
 	| TRUNCATE_SYM		{}
 	| UNICODE_SYM		{}
+        | UNINSTALL_SYM         {}
         | XA_SYM                {}
 	;
 
@@ -8869,4 +8874,19 @@
     | FOR_SYM MIGRATE_SYM   { Lex->xa_opt=XA_FOR_MIGRATE; }
     ;
 
+install:
+  INSTALL_SYM PLUGIN_SYM IDENT_sys SONAME_SYM TEXT_STRING_sys
+  {
+    LEX *lex= Lex;
+    lex->sql_command= SQLCOM_INSTALL_PLUGIN;
+    lex->plugin_name= $3;
+    lex->plugin_dl= $5;
+  };
 
+uninstall:
+  UNINSTALL_SYM PLUGIN_SYM IDENT_sys
+  {
+    LEX *lex= Lex;
+    lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
+    lex->plugin_name= $3;
+  };

--- 1.179/sql/table.cc	2005-09-02 02:59:49 +05:00
+++ 1.180/sql/table.cc	2005-09-20 23:46:30 +05:00
@@ -368,9 +368,7 @@
         }
         parser_name.str= next_chunk;
         parser_name.length= strlen(next_chunk);
-#ifdef HAVE_DLOPEN
         keyinfo->parser= plugin_find(&parser_name, MYSQL_FTPARSER_PLUGIN);
-#endif
         if (! keyinfo->parser)
         {
           my_free(buff, MYF(0));

--- 1.126/sql/set_var.cc	2005-08-20 20:40:38 +05:00
+++ 1.127/sql/set_var.cc	2005-09-20 23:46:30 +05:00
@@ -913,9 +913,7 @@
   {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
    SHOW_SYS},
   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
-#ifdef HAVE_DLOPEN
   {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
-#endif
   {"port",                    (char*) &mysqld_port,                  SHOW_INT},
   {sys_preload_buff_size.name, (char*) &sys_preload_buff_size,      SHOW_SYS},
   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},

--- 1.8/sql/sql_plugin.cc	2005-09-02 02:59:48 +05:00
+++ 1.9/sql/sql_plugin.cc	2005-09-20 23:46:30 +05:00
@@ -16,8 +16,9 @@
 
 #include "mysql_priv.h"
 #include <my_pthread.h>
+#define REPORT_TO_LOG  1
+#define REPORT_TO_USER 2
 
-#ifdef HAVE_DLOPEN
 char *opt_plugin_dir;
 static const char *plugin_interface_version_sym=
                    "_mysql_plugin_interface_version_";
@@ -30,7 +31,7 @@
 static bool initialized= 0;
 
 
-static struct st_plugin_dl *plugin_dl_find (LEX_STRING *dl)
+static struct st_plugin_dl *plugin_dl_find(LEX_STRING *dl)
 {
   uint i;
   DBUG_ENTER("plugin_dl_find");
@@ -48,8 +49,9 @@
 }
 
 
-static st_plugin_dl *plugin_dl_add (LEX_STRING *dl)
+static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report)
 {
+#ifdef HAVE_DLOPEN
   char dlpath[FN_REFLEN];
   uint plugin_dir_len;
   struct st_plugin_dl *tmp, plugin_dl;
@@ -68,7 +70,10 @@
       dl->length > NAME_LEN ||
       plugin_dir_len + dl->length + 1 >= FN_REFLEN)
   {
-    sql_print_error("Cannot open plugin with path '%.64s'", dl->str);
+    if (report & REPORT_TO_USER)
+      my_error(ER_UDF_NO_PATHS, MYF(0));
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_UDF_NO_PATHS));
     DBUG_RETURN(0);
   }
   /* If this dll is already loaded just increase ref_count. */
@@ -83,14 +88,20 @@
   /* Open new dll handle */
   if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW)))
   {
-    sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, errno, dlerror());
+    if (report & REPORT_TO_USER)
+      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, errno, dlerror());
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, errno, dlerror());
     DBUG_RETURN(0);
   }
   /* Determine interface version */
   if (!(sym= dlsym(plugin_dl.handle, plugin_interface_version_sym)))
   {
     dlclose(plugin_dl.handle);
-    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
+    if (report & REPORT_TO_USER)
+      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_interface_version_sym);
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_interface_version_sym);
     DBUG_RETURN(0);
   }
   plugin_dl.version= *(int *)sym;
@@ -99,15 +110,22 @@
       (plugin_dl.version >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8))
   {
     dlclose(plugin_dl.handle);
-    sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
-                    "plugin interface version mismatch");
+    if (report & REPORT_TO_USER)
+      my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dlpath, 0,
+               "plugin interface version mismatch");
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 0,
+                      "plugin interface version mismatch");
     DBUG_RETURN(0);
   }
   /* Find plugin declarations */
   if (!(sym= dlsym(plugin_dl.handle, plugin_declarations_sym)))
   {
     dlclose(plugin_dl.handle);
-    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
+    if (report & REPORT_TO_USER)
+      my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), plugin_declarations_sym);
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), plugin_declarations_sym);
     DBUG_RETURN(0);
   }
   plugin_dl.plugins= (struct st_mysql_plugin *)sym;
@@ -115,7 +133,10 @@
   if (!(plugin_dl.dl.str= my_strdup(dl->str, MYF(0))))
   {
     dlclose(plugin_dl.handle);
-    sql_print_error(ER(ER_OUTOFMEMORY), dl->length + 1);
+    if (report & REPORT_TO_USER)
+      my_error(ER_OUTOFMEMORY, MYF(0), dl->length + 1);
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_OUTOFMEMORY), dl->length + 1);
     DBUG_RETURN(0);
   }
   plugin_dl.dl.length= dl->length;
@@ -124,16 +145,27 @@
   {
     dlclose(plugin_dl.handle);
     my_free(plugin_dl.dl.str, MYF(0));
-    sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
+    if (report & REPORT_TO_USER)
+      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
     DBUG_RETURN(0);
   }
   DBUG_RETURN(dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
                               struct st_plugin_dl *));
+#else
+  if (report & REPORT_TO_USER)
+    my_error(ER_CANT_OPEN_LIBRARY, MYF(0), dl->name, 0, "not implemented");
+  if (report & REPORT_TO_LOG)
+    sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dl->name, 0, "not implemented");
+  DBUG_RETURN(0);
+#endif
 }
 
 
-static void plugin_dl_del (LEX_STRING *dl)
+static void plugin_dl_del(LEX_STRING *dl)
 {
+#ifdef HAVE_DLOPEN
   uint i;
   DBUG_ENTER("plugin_dl_del");
   for (i= 0; i < plugin_dl_array.elements; i++)
@@ -156,16 +188,16 @@
     }
   }
   DBUG_VOID_RETURN;
+#endif
 }
 
 
-struct st_plugin_int *plugin_find (LEX_STRING *name, int type)
+static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type)
 {
   uint i;
-  DBUG_ENTER("plugin_find");
+  DBUG_ENTER("plugin_find_internal");
   if (! initialized)
     DBUG_RETURN(0);
-  rw_rdlock(&THR_LOCK_plugin);
   for (i= 0; i < plugin_array.elements; i++)
   {
     struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
@@ -174,24 +206,37 @@
         ! my_strnncoll(system_charset_info,
                        (const uchar *)name->str, name->length,
                        (const uchar *)tmp->name.str, tmp->name.length))
-    {
-      rw_unlock(&THR_LOCK_plugin);
       DBUG_RETURN(tmp);
-    }
   }
-  rw_unlock(&THR_LOCK_plugin);
   DBUG_RETURN(0);
 }
 
 
-static my_bool plugin_add (LEX_STRING *name, LEX_STRING *dl)
+struct st_plugin_int *plugin_find(LEX_STRING *name, int type)
+{
+  struct st_plugin_int *rc;
+  DBUG_ENTER("plugin_find");
+  rw_rdlock(&THR_LOCK_plugin);
+  rc= plugin_find_internal(name, type);
+  rw_unlock(&THR_LOCK_plugin);
+  DBUG_RETURN(rc);
+}
+
+
+static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
 {
   struct st_plugin_int tmp;
   struct st_mysql_plugin *plugin;
   DBUG_ENTER("plugin_add");
-  if (plugin_find(name, MYSQL_ANY_PLUGIN))
-    DBUG_RETURN(FALSE);
-  if (! (tmp.plugin_dl= plugin_dl_add(dl)))
+  if (plugin_find_internal(name, MYSQL_ANY_PLUGIN))
+  {
+    if (report & REPORT_TO_USER)
+      my_error(ER_UDF_EXISTS, MYF(0), name->str);
+    if (report & REPORT_TO_LOG)
+      sql_print_error(ER(ER_UDF_EXISTS), name->str);
+    DBUG_RETURN(TRUE);
+  }
+  if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
     DBUG_RETURN(TRUE);
   /* Find plugin by name */
   for (plugin= tmp.plugin_dl->plugins; plugin->type; plugin++)
@@ -206,16 +251,26 @@
       tmp.name.str= (char *)plugin->name;
       tmp.name.length= name_len;
       if (insert_dynamic(&plugin_array, (gptr)&tmp))
+      {
+        if (report & REPORT_TO_USER)
+          my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_int));
+        if (report & REPORT_TO_LOG)
+          sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_int));
         break;
+      }
       DBUG_RETURN(FALSE);
     }
   }
+  if (report & REPORT_TO_USER)
+    my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), name->str);
+  if (report & REPORT_TO_LOG)
+    sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
   plugin_dl_del(dl);
   DBUG_RETURN(TRUE);
 }
 
 
-static void plugin_del (LEX_STRING *name)
+static void plugin_del(LEX_STRING *name)
 {
   uint i;
   DBUG_ENTER("plugin_del");
@@ -236,7 +291,7 @@
 }
 
 
-static void plugin_call_initializer (void)
+static void plugin_call_initializer(void)
 {
   uint i;
   DBUG_ENTER("plugin_call_initializer");
@@ -261,7 +316,7 @@
 }
 
 
-static void plugin_call_deinitializer (void)
+static void plugin_call_deinitializer(void)
 {
   uint i;
   DBUG_ENTER("plugin_call_deinitializer");
@@ -269,7 +324,7 @@
   {
     struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
                                                struct st_plugin_int *);
-    if (tmp->plugin->deinit)
+    if (tmp->plugin && tmp->plugin->deinit)
     {
       DBUG_PRINT("info", ("Deinitializing plugin: '%s'", tmp->name.str));
       if (tmp->plugin->deinit())
@@ -332,7 +387,7 @@
     name.length= strlen(name.str);
     dl.str= get_field(&mem, table->field[1]);
     dl.length= strlen(dl.str);
-    if (plugin_add(&name, &dl))
+    if (plugin_add(&name, &dl, REPORT_TO_LOG))
       DBUG_PRINT("warning", ("Couldn't load plugin named '%s' with soname '%s'.",
                              name.str, dl.str));
   }
@@ -361,8 +416,13 @@
   {
     struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
                                               struct st_plugin_dl *);
-    dlclose(tmp->handle);
-    my_free(tmp->dl.str, MYF(0));
+#ifdef HAVE_DLOPEN
+    if (tmp->handle)
+    {
+      dlclose(tmp->handle);
+      my_free(tmp->dl.str, MYF(0));
+    }
+#endif
   }
   delete_dynamic(&plugin_dl_array);
   if (initialized)
@@ -373,4 +433,50 @@
   DBUG_VOID_RETURN;
 }
 
-#endif /* HAVE_DLOPEN */
+
+my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
+{
+  TABLE_LIST tables;
+  TABLE *table;
+  int error;
+  struct st_plugin_int *tmp;
+  DBUG_ENTER("mysql_install_plugin");
+  rw_rdlock(&THR_LOCK_plugin);
+  if (plugin_add(name, dl, REPORT_TO_USER))
+    goto err;
+  bzero(&tables, sizeof(tables));
+  tables.db= (char *)"mysql";
+  tables.table_name= tables.alias= (char *)"plugin";
+  if (! (table = open_ltable(thd, &tables, TL_WRITE)))
+    goto err;
+  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->write_row(table->record[0]);
+  close_thread_tables(thd);
+  if (error)
+  {
+    my_error(ER_ERROR_ON_WRITE, MYF(0), "mysql.plugin", error);
+    goto err;
+  }
+  tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
+  if (tmp->plugin->init)
+  {
+    if (tmp->plugin->init())
+    {
+      my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str, ER(ER_UNKNOWN_ERROR));
+      goto err;
+    }
+  }
+  rw_unlock(&THR_LOCK_plugin);
+  DBUG_RETURN(FALSE);
+err:
+  plugin_del(name);
+  rw_unlock(&THR_LOCK_plugin);
+  DBUG_RETURN(TRUE);
+}
+
+
+my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name)
+{
+  return FALSE;
+}

--- 1.5/sql/sql_plugin.h	2005-09-02 01:45:36 +05:00
+++ 1.6/sql/sql_plugin.h	2005-09-20 23:46:30 +05:00
@@ -33,10 +33,10 @@
   struct st_plugin_dl *plugin_dl;
 };
 
-#ifdef HAVE_DLOPEN
 extern char *opt_plugin_dir;
 extern void plugin_init(void);
 extern void plugin_free(void);
 extern st_plugin_int *plugin_find(LEX_STRING *name, int type);
-#endif
+extern my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl);
+extern my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name);
 #endif
Thread
bk commit into 5.0 tree (svoj:1.1910)svoj20 Sep