List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:January 5 2006 9:15pm
Subject:bk commit into 5.1 tree (serg:1.2020)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of serg. When serg 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.2020 06/01/05 22:14:18 serg@stripped +12 -0
  WL#2935 - SHOW STATUS support in plugins
  
  The patch adds DYNAMIC_ARRAY all_status_vars, which is now the
  sole source of status information for SHOW STATUS.  Status
  variables can be added to and removed from the array dynamically.
  SHOW STATUS command uses this array instead of static array
  from mysqld.cc
  Compatibility with the old, global list of status variables is
  preserved in init_server_components(), where this global list is
  simply appended to all_status_vars.

  sql/structs.h
    1.58 06/01/05 22:13:46 serg@stripped +1 -22
    WL#2935 - SHOW STATUS support in plugins
    SHOW STATUS definitions moved to include/plugin.h and sql_plugin.h
    s/struct show_var_st/SHOW_VAR/

  sql/sql_show.cc
    1.296 06/01/05 22:13:45 serg@stripped +171 -14
    WL#2935 - SHOW STATUS support in plugins
    DYNAMIC_ARRAY all_status_vars, add_status_vars(), remove_status_vars()
    s/struct show_var_st/SHOW_VAR/

  sql/sql_plugin.h
    1.5 06/01/05 22:13:45 serg@stripped +11 -1
    WL#2935 - SHOW STATUS support in plugins

  sql/sql_plugin.cc
    1.9 06/01/05 22:13:45 serg@stripped +47 -33
    WL#2935 - SHOW STATUS support in plugins

  sql/sql_parse.cc
    1.504 06/01/05 22:13:43 serg@stripped +1 -1
    s/struct show_var_st/SHOW_VAR/

  sql/set_var.cc
    1.155 06/01/05 22:13:42 serg@stripped +2 -2
    s/struct show_var_st/SHOW_VAR/

  sql/mysqld.cc
    1.513 06/01/05 22:13:42 serg@stripped +70 -59
    bug: plugin_free must be called even with --skip-grants
    add_status_vars()/free_status_vars(), remove unused SHOW_xxx_CONST
    s/struct show_var_st/SHOW_VAR/

  sql/mysql_priv.h
    1.363 06/01/05 22:13:41 serg@stripped +9 -7
    WL#2935 - SHOW STATUS support in plugins
    add_status_vars(), remove_status_vars()

  sql/ha_innodb.h
    1.115 06/01/05 22:13:41 serg@stripped +1 -1
    s/struct show_var_st/SHOW_VAR/

  sql/ha_innodb.cc
    1.248 06/01/05 22:13:40 serg@stripped +1 -1
    s/struct show_var_st/SHOW_VAR/

  plugin/fulltext/plugin_example.c
    1.2 06/01/05 22:13:40 serg@stripped +17 -1
    WL#2935 - SHOW STATUS support in plugins
    example

  include/plugin.h
    1.7 06/01/05 22:13:39 serg@stripped +21 -1
    WL#2935 - SHOW STATUS support in plugins

# 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:	serg
# Host:	serg.mylan
# Root:	/usr/home/serg/Abk/mysql-5.1

--- 1.362/sql/mysql_priv.h	Sat Dec 31 09:23:08 2005
+++ 1.363/sql/mysql_priv.h	Thu Jan  5 22:13:41 2006
@@ -292,7 +292,7 @@ extern CHARSET_INFO *national_charset_in
 #define OPTION_SETUP_TABLES_DONE        (LL(1) << 30) // intern
 /* If not set then the thread will ignore all warnings with level notes. */
 #define OPTION_SQL_NOTES                (LL(1) << 31) // THD, user
-/* 
+/*
   Force the used temporary table to be a MyISAM table (because we will use
   fulltext functions when reading from it.
 */
@@ -322,7 +322,7 @@ extern CHARSET_INFO *national_charset_in
 #define MODE_DB2			2048
 #define MODE_MAXDB			4096
 #define MODE_NO_KEY_OPTIONS             8192
-#define MODE_NO_TABLE_OPTIONS           16384 
+#define MODE_NO_TABLE_OPTIONS           16384
 #define MODE_NO_FIELD_OPTIONS           32768
 #define MODE_MYSQL323                   65536
 #define MODE_MYSQL40                    (MODE_MYSQL323*2)
@@ -513,13 +513,11 @@ void free_items(Item *item);
 void cleanup_items(Item *item);
 class THD;
 void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
-bool check_one_table_access(THD *thd, ulong privilege,
-			   TABLE_LIST *tables);
+bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
 bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
 			  bool is_proc, bool no_errors);
 bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
-bool check_merge_table_access(THD *thd, char *db,
-			      TABLE_LIST *table_list);
+bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list);
 bool check_some_routine_access(THD *thd, const char *db, const char *name, bool is_proc);
 bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
 bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
@@ -884,6 +882,10 @@ void calc_sum_of_all_status(STATUS_VAR *
 void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
                     const LEX_STRING *definer_host);
 
+int add_status_vars(SHOW_VAR *list);
+void remove_status_vars(SHOW_VAR *list);
+void init_status_vars();
+void free_status_vars();
 
 /* information schema */
 extern LEX_STRING information_schema_name;
@@ -1269,7 +1271,7 @@ extern I_List<NAMED_LIST> key_caches;
 extern MY_BITMAP temp_pool;
 extern String my_empty_string;
 extern const String my_null_string;
-extern SHOW_VAR init_vars[],status_vars[], internal_vars[];
+extern SHOW_VAR init_vars[], status_vars[], internal_vars[];
 extern struct system_variables global_system_variables;
 extern struct system_variables max_system_variables;
 extern struct system_status_var global_status_var;

--- 1.512/sql/mysqld.cc	Mon Jan  2 15:40:59 2006
+++ 1.513/sql/mysqld.cc	Thu Jan  5 22:13:42 2006
@@ -348,7 +348,7 @@ my_bool opt_show_slave_auth_info, opt_sq
 my_bool opt_log_slave_updates= 0;
 my_bool	opt_innodb;
 #ifdef WITH_INNOBASE_STORAGE_ENGINE
-extern struct show_var_st innodb_status_variables[];
+extern SHOW_VAR innodb_status_variables[];
 extern uint innobase_init_flags, innobase_lock_type;
 extern uint innobase_flush_log_at_trx_commit;
 extern ulong innobase_cache_size, innobase_fast_shutdown;
@@ -417,7 +417,7 @@ ulong opt_ndb_cache_check_time;
 const char *opt_ndb_mgmd;
 ulong opt_ndb_nodeid;
 
-extern struct show_var_st ndb_status_variables[];
+extern SHOW_VAR ndb_status_variables[];
 extern const char *ndb_distribution_names[];
 extern TYPELIB ndb_distribution_typelib;
 extern const char *opt_ndb_distribution;
@@ -1154,18 +1154,19 @@ void clean_up(bool print_message)
   set_var_free();
   free_charsets();
   (void) ha_panic(HA_PANIC_CLOSE);	/* close all tables and logs */
+#ifdef HAVE_DLOPEN
   if (!opt_noacl)
   {
-#ifdef HAVE_DLOPEN
     udf_free();
-#endif
-    plugin_free();
   }
+#endif
+  plugin_free();
   if (tc_log)
     tc_log->close();
   xid_cache_free();
   delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache);
   multi_keycache_free();
+  free_status_vars();
   end_thr_alarm(1);			/* Free allocated memory */
 #ifdef USE_RAID
   end_raid();
@@ -2670,12 +2671,21 @@ static int init_common_variables(const c
   mysql_log.init_pthread_objects();
   mysql_slow_log.init_pthread_objects();
   mysql_bin_log.init_pthread_objects();
-  
+
   if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
     strmov(glob_hostname,"mysql");
   strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
   strmov(fn_ext(pidfile_name),".pid");		// Add proper extension
 
+  /*
+    Add server status variables to the dynamic list of
+    status variables that is shown by SHOW STATUS.
+    Later, in plugin_init, plugin_load, and mysql_install_plugin
+    new entries could be added to that list.
+  */
+  if (add_status_vars(status_vars))
+    return 1; // an error was already reported
+
   if (plugin_init())
   {
     sql_print_error("Failed to init plugins.");
@@ -3557,7 +3567,7 @@ we force server id to 2, but this MySQL 
 #ifndef __NETWARE__
     (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
 #endif /* __NETWARE__ */
-    
+
     if (!opt_bootstrap)
       (void) my_delete(pidfile_name,MYF(MY_WME));	// Not needed anymore
 
@@ -3575,6 +3585,7 @@ we force server id to 2, but this MySQL 
     udf_init();
 #endif
   }
+  init_status_vars();
   if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
     opt_skip_slave_start= 1;
   /*
@@ -6186,21 +6197,21 @@ The minimum value for this variable is 4
   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
-static int show_question(THD *thd, show_var_st *var, char *buff)
+static int show_question(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONGLONG;
   var->value= (char *)&thd->query_id;
   return 0;
 }
 
-static int show_net_compression(THD *thd, show_var_st *var, char *buff)
+static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_MY_BOOL;
   var->value= (char *)&thd->net.compress;
   return 0;
 }
 
-static int show_starttime(THD *thd, show_var_st *var, char *buff)
+static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6209,14 +6220,14 @@ static int show_starttime(THD *thd, show
 }
 
 #ifdef HAVE_REPLICATION
-static int show_rpl_status(THD *thd, show_var_st *var, char *buff)
+static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
   return 0;
 }
 
-static int show_slave_running(THD *thd, show_var_st *var, char *buff)
+static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   pthread_mutex_lock(&LOCK_active_mi);
@@ -6226,7 +6237,7 @@ static int show_slave_running(THD *thd, 
   return 0;
 }
 
-static int show_slave_retried_trans(THD *thd, show_var_st *var, char *buff)
+static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
 {
   /*
     TODO: with multimaster, have one such counter per line in
@@ -6248,7 +6259,7 @@ static int show_slave_retried_trans(THD 
 }
 #endif /* HAVE_REPLICATION */
 
-static int show_open_tables(THD *thd, show_var_st *var, char *buff)
+static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6256,7 +6267,7 @@ static int show_open_tables(THD *thd, sh
   return 0;
 }
 
-static int show_table_definitions(THD *thd, show_var_st *var, char *buff)
+static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6266,7 +6277,7 @@ static int show_table_definitions(THD *t
 
 #ifdef HAVE_OPENSSL
 /* Functions relying on CTX */
-static int show_ssl_ctx_sess_accept(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6275,7 +6286,7 @@ static int show_ssl_ctx_sess_accept(THD 
   return 0;
 }
 
-static int show_ssl_ctx_sess_accept_good(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6284,7 +6295,7 @@ static int show_ssl_ctx_sess_accept_good
   return 0;
 }
 
-static int show_ssl_ctx_sess_connect_good(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6293,7 +6304,7 @@ static int show_ssl_ctx_sess_connect_goo
   return 0;
 }
 
-static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6302,7 +6313,7 @@ static int show_ssl_ctx_sess_accept_rene
   return 0;
 }
 
-static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6311,7 +6322,7 @@ static int show_ssl_ctx_sess_connect_ren
   return 0;
 }
 
-static int show_ssl_ctx_sess_cb_hits(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6320,7 +6331,7 @@ static int show_ssl_ctx_sess_cb_hits(THD
   return 0;
 }
 
-static int show_ssl_ctx_sess_hits(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6329,7 +6340,7 @@ static int show_ssl_ctx_sess_hits(THD *t
   return 0;
 }
 
-static int show_ssl_ctx_sess_cache_full(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6338,7 +6349,7 @@ static int show_ssl_ctx_sess_cache_full(
   return 0;
 }
 
-static int show_ssl_ctx_sess_misses(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6347,7 +6358,7 @@ static int show_ssl_ctx_sess_misses(THD 
   return 0;
 }
 
-static int show_ssl_ctx_sess_timeouts(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6356,7 +6367,7 @@ static int show_ssl_ctx_sess_timeouts(TH
   return 0;
 }
 
-static int show_ssl_ctx_sess_number(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6365,7 +6376,7 @@ static int show_ssl_ctx_sess_number(THD 
   return 0;
 }
 
-static int show_ssl_ctx_sess_connect(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6374,7 +6385,7 @@ static int show_ssl_ctx_sess_connect(THD
   return 0;
 }
 
-static int show_ssl_ctx_sess_get_cache_size(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6383,7 +6394,7 @@ static int show_ssl_ctx_sess_get_cache_s
   return 0;
 }
 
-static int show_ssl_ctx_get_verify_mode(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6392,7 +6403,7 @@ static int show_ssl_ctx_get_verify_mode(
   return 0;
 }
 
-static int show_ssl_ctx_get_verify_depth(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6401,7 +6412,7 @@ static int show_ssl_ctx_get_verify_depth
   return 0;
 }
 
-static int show_ssl_ctx_get_session_cache_mode(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   if (!ssl_acceptor_fd)
@@ -6428,7 +6439,7 @@ static int show_ssl_ctx_get_session_cach
 }
 
 /* Functions relying on SSL */
-static int show_ssl_get_version(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   var->value= const_cast<char*>(thd->net.vio->ssl_arg ?
@@ -6436,7 +6447,7 @@ static int show_ssl_get_version(THD *thd
   return 0;
 }
 
-static int show_ssl_session_reused(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6445,7 +6456,7 @@ static int show_ssl_session_reused(THD *
                          0;
 }
 
-static int show_ssl_get_default_timeout(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6455,7 +6466,7 @@ static int show_ssl_get_default_timeout(
   return 0;
 }
 
-static int show_ssl_get_verify_mode(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6465,7 +6476,7 @@ static int show_ssl_get_verify_mode(THD 
   return 0;
 }
 
-static int show_ssl_get_verify_depth(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_LONG;
   var->value= buff;
@@ -6475,7 +6486,7 @@ static int show_ssl_get_verify_depth(THD
   return 0;
 }
 
-static int show_ssl_get_cipher(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   var->value= const_cast<char*>(thd->net.vio->ssl_arg ?
@@ -6483,7 +6494,7 @@ static int show_ssl_get_cipher(THD *thd,
   return 0;
 }
 
-static int show_ssl_get_cipher_list(THD *thd, show_var_st *var, char *buff)
+static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   var->value= buff;
@@ -6507,7 +6518,7 @@ static int show_ssl_get_cipher_list(THD 
 
 #ifdef WITH_INNOBASE_STORAGE_ENGINE
 int innodb_export_status(void);
-static int show_innodb_vars(THD *thd, show_var_st *var, char *buff)
+static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
 {
   innodb_export_status();
   var->type= SHOW_ARRAY;
@@ -6516,7 +6527,7 @@ static int show_innodb_vars(THD *thd, sh
 }
 #endif
 
-struct show_var_st status_vars[]= {
+SHOW_VAR status_vars[]= {
   {"Aborted_clients",          (char*) &aborted_threads,        SHOW_LONG},
   {"Aborted_connects",         (char*) &aborted_connects,       SHOW_LONG},
   {"Binlog_cache_disk_use",    (char*) &binlog_cache_disk_use,  SHOW_LONG},
@@ -6547,7 +6558,7 @@ struct show_var_st status_vars[]= {
   {"Com_drop_index",	       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
   {"Com_drop_table",	       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
   {"Com_drop_user",	       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
-  {"Com_execute_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS}, 
+  {"Com_execute_sql",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
   {"Com_flush",		       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
   {"Com_grant",		       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
   {"Com_ha_close",	       (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
@@ -6626,14 +6637,14 @@ struct show_var_st status_vars[]= {
   {"Com_xa_rollback",          (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
   {"Com_xa_start",             (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
   {"Compression",              (char*) &show_net_compression, SHOW_FUNC},
-  {"Connections",              (char*) &thread_id,              SHOW_LONG_CONST},
+  {"Connections",              (char*) &thread_id,              SHOW_LONG_NOFLUSH},
   {"Created_tmp_disk_tables",  (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
   {"Created_tmp_files",	       (char*) &my_tmp_file_created,	SHOW_LONG},
   {"Created_tmp_tables",       (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
   {"Delayed_errors",           (char*) &delayed_insert_errors,  SHOW_LONG},
-  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_CONST},
+  {"Delayed_insert_threads",   (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
   {"Delayed_writes",           (char*) &delayed_insert_writes,  SHOW_LONG},
-  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_CONST},
+  {"Flush_commands",           (char*) &refresh_version,        SHOW_LONG_NOFLUSH},
   {"Handler_commit",           (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
   {"Handler_delete",           (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
   {"Handler_discover",         (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
@@ -6650,11 +6661,11 @@ struct show_var_st status_vars[]= {
   {"Handler_update",           (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
   {"Handler_write",            (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
 #ifdef WITH_INNOBASE_STORAGE_ENGINE
-  {"Innodb_",                  (char*) &show_innodb_vars, SHOW_FUNC},
+  {"Innodb",                   (char*) &show_innodb_vars, SHOW_FUNC},
 #endif /* WITH_INNOBASE_STORAGE_ENGINE */
   {"Key_blocks_not_flushed",   (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
-  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_CONST_LONG},
-  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_CONST_LONG},
+  {"Key_blocks_unused",        (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
+  {"Key_blocks_used",          (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
   {"Key_read_requests",        (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
   {"Key_reads",                (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
   {"Key_write_requests",       (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
@@ -6662,23 +6673,23 @@ struct show_var_st status_vars[]= {
   {"Last_query_cost",          (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
   {"Max_used_connections",     (char*) &max_used_connections,  SHOW_LONG},
 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-  {"Ndb_",                     (char*) &ndb_status_variables,   SHOW_ARRAY},
+  {"Ndb",                      (char*) &ndb_status_variables,   SHOW_ARRAY},
 #endif /* WITH_NDBCLUSTER_STORAGE_ENGINE */
-  {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,    SHOW_LONG_CONST},
-  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_CONST},
-  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_CONST},
+  {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use,    SHOW_LONG_NOFLUSH},
+  {"Open_files",               (char*) &my_file_opened,         SHOW_LONG_NOFLUSH},
+  {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_NOFLUSH},
   {"Open_table_definitions",   (char*) &show_table_definitions, SHOW_FUNC},
   {"Open_tables",              (char*) &show_open_tables,       SHOW_FUNC},
   {"Opened_tables",            (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
 #ifdef HAVE_QUERY_CACHE
-  {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks, SHOW_LONG_CONST},
-  {"Qcache_free_memory",       (char*) &query_cache.free_memory, SHOW_LONG_CONST},
+  {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
+  {"Qcache_free_memory",       (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
   {"Qcache_hits",              (char*) &query_cache.hits,       SHOW_LONG},
   {"Qcache_inserts",           (char*) &query_cache.inserts,    SHOW_LONG},
   {"Qcache_lowmem_prunes",     (char*) &query_cache.lowmem_prunes, SHOW_LONG},
   {"Qcache_not_cached",        (char*) &query_cache.refused,    SHOW_LONG},
-  {"Qcache_queries_in_cache",  (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
-  {"Qcache_total_blocks",      (char*) &query_cache.total_blocks, SHOW_LONG_CONST},
+  {"Qcache_queries_in_cache",  (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
+  {"Qcache_total_blocks",      (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
 #endif /*HAVE_QUERY_CACHE*/
   {"Questions",                (char*) &show_question,            SHOW_FUNC},
 #ifdef HAVE_REPLICATION
@@ -6732,10 +6743,10 @@ struct show_var_st status_vars[]= {
   {"Tc_log_page_size",         (char*) &tc_log_page_size,       SHOW_LONG},
   {"Tc_log_page_waits",        (char*) &tc_log_page_waits,      SHOW_LONG},
 #endif
-  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_CONST},
-  {"Threads_connected",        (char*) &thread_count,           SHOW_INT_CONST},
-  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_CONST},
-  {"Threads_running",          (char*) &thread_running,         SHOW_INT_CONST},
+  {"Threads_cached",           (char*) &cached_thread_count,    SHOW_LONG_NOFLUSH},
+  {"Threads_connected",        (char*) &thread_count,           SHOW_INT},
+  {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
+  {"Threads_running",          (char*) &thread_running,         SHOW_INT},
   {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
   {NullS, NullS, SHOW_LONG}
 };

--- 1.503/sql/sql_parse.cc	Wed Jan  4 10:36:34 2006
+++ 1.504/sql/sql_parse.cc	Thu Jan  5 22:13:43 2006
@@ -6641,7 +6641,7 @@ void kill_one_thread(THD *thd, ulong id,
 static void refresh_status(void)
 {
   pthread_mutex_lock(&LOCK_status);
-  for (struct show_var_st *ptr=status_vars; ptr->name; ptr++)
+  for (SHOW_VAR *ptr=status_vars; ptr->name; ptr++)
     if (ptr->type == SHOW_LONG) // note that SHOW_LONG_NOFLUSH variables are not reset
       *(ulong*) ptr->value= 0;
 

--- 1.295/sql/sql_show.cc	Mon Jan  2 15:41:00 2006
+++ 1.296/sql/sql_show.cc	Thu Jan  5 22:13:45 2006
@@ -1516,8 +1516,163 @@ void mysqld_list_processes(THD *thd,cons
   Status functions
 *****************************************************************************/
 
+static DYNAMIC_ARRAY all_status_vars;
+static bool status_vars_inited= 0;
+static int show_var_cmp(const void *var1, const void *var2)
+{
+  return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
+}
+
+/*
+  deletes all the SHOW_UNDEF elements from the array and calls
+  delete_dynamic() if it's completely empty.
+*/
+static void shrink_var_array(DYNAMIC_ARRAY *array)
+{
+  int a,b;
+  SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
+
+  for (a= b= 0; b < array->elements; b++)
+    if (all[b].type != SHOW_UNDEF)
+      all[a++]= all[b];
+  if (a)
+  {
+    bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
+    array->elements= a;
+  }
+  else // array is completely empty - delete it
+    delete_dynamic(array);
+}
+
+/*
+  Adds an array of SHOW_VAR entries to the output of SHOW STATUS
+
+  SYNOPSIS
+    add_status_vars(SHOW_VAR *list)
+    list - an array of SHOW_VAR entries to add to all_status_vars
+           the last entry must be {0,0,SHOW_UNDEF}
+
+  NOTE
+    The handling of all_status_vars[] is completely internal, it's allocated
+    automatically when something is added to it, and deleted completely when
+    the last entry is removed.
+
+    As a special optimization, if add_status_vars() is called before
+    init_status_vars(), it assumes "startup mode" - neither concurrent access
+    to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
+
+    The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
+*/
+int add_status_vars(SHOW_VAR *list)
+{
+  int res= 0;
+  if (status_vars_inited)
+    pthread_mutex_lock(&LOCK_status);
+  if (!all_status_vars.buffer && // array is not allocated yet - do it now
+      my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
+  {
+    res= 1;
+    goto err;
+  }
+  while (list->name)
+    res|= insert_dynamic(&all_status_vars, (gptr)list++);
+  res|= insert_dynamic(&all_status_vars, (gptr)list); // appending NULL-element
+  all_status_vars.elements--; // but next insert_dynamic should overwite it
+  if (status_vars_inited)
+    sort_dynamic(&all_status_vars, show_var_cmp);
+err:
+  if (status_vars_inited)
+    pthread_mutex_unlock(&LOCK_status);
+  return res;
+}
+
+/*
+  Make all_status_vars[] usable for SHOW STATUS
+
+  NOTE
+    See add_status_vars(). Before init_status_vars() call, add_status_vars()
+    works in a special fast "startup" mode. Thus init_status_vars()
+    should be called as late as possible but before enabling multi-threading.
+*/
+void init_status_vars()
+{
+  status_vars_inited=1;
+  sort_dynamic(&all_status_vars, show_var_cmp);
+}
+
+/*
+  catch-all cleanup function, cleans up everything no matter what
+
+  DESCRIPTION
+    This function is not strictly required if all add_to_status/
+    remove_status_vars are properly paired, but it's a safety measure that
+    deletes everything from the all_status_vars[] even if some
+    remove_status_vars were forgotten
+*/
+void free_status_vars()
+{
+  delete_dynamic(&all_status_vars);
+}
+
+/*
+  Removes an array of SHOW_VAR entries from the output of SHOW STATUS
+
+  SYNOPSIS
+    remove_status_vars(SHOW_VAR *list)
+    list - an array of SHOW_VAR entries to remove to all_status_vars
+           the last entry must be {0,0,SHOW_UNDEF}
+
+  NOTE
+    there's lots of room for optimizing this, especially in non-sorted mode,
+    but nobody cares - it may be called only in case of failed plugin
+    initialization in the mysqld startup.
+
+*/
+void remove_status_vars(SHOW_VAR *list)
+{
+  if (status_vars_inited)
+  {
+    pthread_mutex_lock(&LOCK_status);
+    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
+    int a= 0, b= all_status_vars.elements, c= (a+b)/2, res;
+
+    for (; list->name; list++)
+    {
+      for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
+      {
+        res= show_var_cmp(list, all+c);
+        if (res < 0)
+          b= c;
+        else if (res > 0)
+          a= c;
+        else break;
+      }
+      if (res == 0)
+        all[c].type= SHOW_UNDEF;
+    }
+    shrink_var_array(&all_status_vars);
+    pthread_mutex_unlock(&LOCK_status);
+  }
+  else
+  {
+    SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
+    int i;
+    for (; list->name; list++)
+    {
+      for (i= 0; i < all_status_vars.elements; i++)
+      {
+        if (show_var_cmp(list, all+i))
+          continue;
+        all[i].type= SHOW_UNDEF;
+        break;
+      }
+    }
+    shrink_var_array(&all_status_vars);
+  }
+}
+
 static bool show_status_array(THD *thd, const char *wild,
-                              show_var_st *variables,
+                              SHOW_VAR *variables,
                               enum enum_var_type value_type,
                               struct system_status_var *status_var,
                               const char *prefix, TABLE *table)
@@ -1527,13 +1682,15 @@ static bool show_status_array(THD *thd, 
   char name_buffer[80];
   int len;
   LEX_STRING null_lex_str;
-  struct show_var_st tmp, *var;
+  SHOW_VAR tmp, *var;
   DBUG_ENTER("show_status_array");
 
   null_lex_str.str= 0;				// For sys_var->value_ptr()
   null_lex_str.length= 0;
 
   prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
+  if (*prefix)
+    *prefix_end++='_';
   len=name_buffer + sizeof(name_buffer) - prefix_end;
 
   for (; variables->name; variables++)
@@ -1542,12 +1699,12 @@ static bool show_status_array(THD *thd, 
     name_buffer[sizeof(name_buffer)-1]=0;       /* Safety */
 
     for (var=variables; var->type == SHOW_FUNC; var= &tmp)
-      ((show_var_func)(var->value))(thd, &tmp, buff);
+      ((mysql_show_var_func)(var->value))(thd, &tmp, buff);
 
     SHOW_TYPE show_type=var->type;
     if (show_type == SHOW_ARRAY)
     {
-      show_status_array(thd, wild, (show_var_st *) var->value,
+      show_status_array(thd, wild, (SHOW_VAR *) var->value,
                         value_type, status_var, name_buffer, table);
     }
     else
@@ -1578,11 +1735,10 @@ static bool show_status_array(THD *thd, 
           break;
         }
         case SHOW_LONG_STATUS:
-        case SHOW_LONG_CONST_STATUS:
           value= ((char *) status_var + (ulong) value);
           /* fall through */
         case SHOW_LONG:
-        case SHOW_LONG_CONST:
+        case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
           end= int10_to_str(*(long*) value, buff, 10);
           break;
         case SHOW_LONGLONG:
@@ -1597,7 +1753,6 @@ static bool show_status_array(THD *thd, 
         case SHOW_MY_BOOL:
           end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
           break;
-        case SHOW_INT_CONST:
         case SHOW_INT:
           end= int10_to_str((long) *(uint32*) value, buff, 10);
           break;
@@ -1623,7 +1778,6 @@ static bool show_status_array(THD *thd, 
           break;
         }
         case SHOW_KEY_CACHE_LONG:
-        case SHOW_KEY_CACHE_CONST_LONG:
           value= (char*) dflt_key_cache + (ulong)value;
           end= int10_to_str(*(long*) value, buff, 10);
           break;
@@ -1632,9 +1786,10 @@ static bool show_status_array(THD *thd, 
 	  end= longlong10_to_str(*(longlong*) value, buff, 10);
 	  break;
         case SHOW_UNDEF:
-        case SHOW_SYS:
-          break;					// Return empty string
+          break;                                        // Return empty string
+        case SHOW_SYS:                                  // Cannot happen
         default:
+          DBUG_ASSERT(0);
           break;
         }
         restore_record(table, s->default_values);
@@ -3357,7 +3512,7 @@ int fill_variables(THD *thd, TABLE_LIST 
   LEX *lex= thd->lex;
   const char *wild= lex->wild ? lex->wild->ptr() : NullS;
   pthread_mutex_lock(&LOCK_global_system_variables);
-  res= show_status_array(thd, wild, init_vars, 
+  res= show_status_array(thd, wild, init_vars,
                          lex->option_type, 0, "", tables->table);
   pthread_mutex_unlock(&LOCK_global_system_variables);
   DBUG_RETURN(res);
@@ -3374,8 +3529,10 @@ int fill_status(THD *thd, TABLE_LIST *ta
   pthread_mutex_lock(&LOCK_status);
   if (lex->option_type == OPT_GLOBAL)
     calc_sum_of_all_status(&tmp);
-  res= show_status_array(thd, wild, status_vars, OPT_GLOBAL,
-                         (lex->option_type == OPT_GLOBAL ? 
+  res= show_status_array(thd, wild,
+                         (SHOW_VAR *)all_status_vars.buffer,
+                         OPT_GLOBAL,
+                         (lex->option_type == OPT_GLOBAL ?
                           &tmp: &thd->status_var), "",tables->table);
   pthread_mutex_unlock(&LOCK_status);
   DBUG_RETURN(res);
@@ -4146,7 +4303,7 @@ ST_FIELD_INFO plugin_fields_info[]=
   {"PLUGIN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
   {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
   {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status"},
-  {"PLUGIN_TYPE", 10, MYSQL_TYPE_STRING, 0, 0, "Type"},
+  {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type"},
   {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
   {"PLUGIN_LIBRARY", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"},
   {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0},

--- 1.57/sql/structs.h	Mon Jan  2 15:41:00 2006
+++ 1.58/sql/structs.h	Thu Jan  5 22:13:46 2006
@@ -169,32 +169,11 @@ typedef struct st_known_date_time_format
   const char *time_format;
 } KNOWN_DATE_TIME_FORMAT;
 
-
-enum SHOW_TYPE
-{
-  SHOW_UNDEF,
-  SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
-  SHOW_DOUBLE_STATUS, SHOW_BOOL, SHOW_MY_BOOL,
-  SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
-  SHOW_ARRAY, SHOW_FUNC,
-  SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG,
-  SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS
-};
-
 enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
 
 extern const char *show_comp_option_name[];
 
-typedef int *(*update_var)(THD *, struct show_var_st *);
-
-typedef struct show_var_st {
-  const char *name;
-  char *value;
-  SHOW_TYPE type;
-} SHOW_VAR;
-
-#define SHOW_VAR_FUNC_BUFF_SIZE 1024
-typedef int (*show_var_func)(THD *, struct show_var_st *, char *);
+typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
 
 typedef struct	st_lex_user {
   LEX_STRING user, host, password;

--- 1.247/sql/ha_innodb.cc	Sat Dec 31 05:53:45 2005
+++ 1.248/sql/ha_innodb.cc	Thu Jan  5 22:13:40 2006
@@ -253,7 +253,7 @@ innobase_commit_low(
 /*================*/
 	trx_t*	trx);	/* in: transaction handle */
 
-struct show_var_st innodb_status_variables[]= {
+SHOW_VAR innodb_status_variables[]= {
   {"buffer_pool_pages_data",
   (char*) &export_vars.innodb_buffer_pool_pages_data,     SHOW_LONG},
   {"buffer_pool_pages_dirty",

--- 1.114/sql/ha_innodb.h	Mon Jan  2 15:40:59 2006
+++ 1.115/sql/ha_innodb.h	Thu Jan  5 22:13:41 2006
@@ -212,7 +212,7 @@ class ha_innobase: public handler
 					uint table_changes);
 };
 
-extern struct show_var_st innodb_status_variables[];
+extern SHOW_VAR innodb_status_variables[];
 extern uint innobase_init_flags, innobase_lock_type;
 extern uint innobase_flush_log_at_trx_commit;
 extern ulong innobase_cache_size, innobase_fast_shutdown;

--- 1.154/sql/set_var.cc	Mon Jan  2 15:41:00 2006
+++ 1.155/sql/set_var.cc	Thu Jan  5 22:13:42 2006
@@ -624,7 +624,7 @@ sys_var_have_variable sys_have_row_based
 sys_var_const_str		sys_license("license", STRINGIFY_ARG(LICENSE));
 
 #ifdef HAVE_REPLICATION
-static int show_slave_skip_errors(THD *thd, show_var_st *var, char *buff)
+static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type=SHOW_CHAR;
   var->value= buff;
@@ -667,7 +667,7 @@ static int show_slave_skip_errors(THD *t
   Variables shown by SHOW variables in alphabetical order
 */
 
-struct show_var_st init_vars[]= {
+SHOW_VAR init_vars[]= {
   {"auto_increment_increment", (char*) &sys_auto_increment_increment, SHOW_SYS},
   {"auto_increment_offset",   (char*) &sys_auto_increment_offset, SHOW_SYS},
   {sys_automatic_sp_privileges.name,(char*) &sys_automatic_sp_privileges,       SHOW_SYS},

--- 1.6/include/plugin.h	Sun Jan  1 16:43:17 2006
+++ 1.7/include/plugin.h	Thu Jan  5 22:13:39 2006
@@ -41,7 +41,26 @@
 int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
 int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
 struct st_mysql_plugin _mysql_plugin_declarations_[]= {
-#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0}}
+#define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0}}
+
+/*
+  declarations for SHOW STATUS support in plugins
+*/
+enum enum_mysql_show_type
+{
+  SHOW_UNDEF, SHOW_BOOL, SHOW_MY_BOOL, SHOW_INT, SHOW_LONG,
+  SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
+  SHOW_ARRAY, SHOW_FUNC
+};
+
+struct st_mysql_show_var {
+  const char *name;
+  char *value;
+  enum enum_mysql_show_type type;
+};
+
+#define SHOW_VAR_FUNC_BUFF_SIZE 1024
+typedef int (*mysql_show_var_func)(void *, struct st_mysql_show_var*, char *);
 
 /*
   Plugin description structure.
@@ -57,6 +76,7 @@ struct st_mysql_plugin
   int (*init)(void);    /* the function to invoke when plugin is loaded */
   int (*deinit)(void);  /* the function to invoke when plugin is unloaded */
   uint version;         /* plugin version (for SHOW PLUGINS)            */
+  struct st_mysql_show_var *status_vars;
 };
 
 /*************************************************************************

--- 1.8/sql/sql_plugin.cc	Sun Jan  1 16:43:18 2006
+++ 1.9/sql/sql_plugin.cc	Thu Jan  5 22:13:45 2006
@@ -94,7 +94,8 @@ static st_plugin_dl *plugin_dl_insert_or
 
 static inline void free_plugin_mem(struct st_plugin_dl *p)
 {
-  dlclose(p->handle);
+  if (p->handle)
+    dlclose(p->handle);
   my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
   if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
     my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
@@ -196,8 +197,12 @@ static st_plugin_dl *plugin_dl_add(LEX_S
         sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), sizeof_st_plugin_sym);
       DBUG_RETURN(0);
 #else
+      /*
+        When the following assert starts failing, we'll have to switch
+        to the upper branch of the #ifdef
+      */
       DBUG_ASSERT(min_plugin_interface_version == 0);
-      sizeof_st_plugin=(int)offsetof(struct st_mysql_plugin, version);
+      sizeof_st_plugin= (int)offsetof(struct st_mysql_plugin, version);
 #endif
     }
 
@@ -226,7 +231,7 @@ static st_plugin_dl *plugin_dl_add(LEX_S
         /* fall through */
       case 0x0001:
         cur[i].version=old->version;
-        // cur[i].status_vars=old->status_vars;
+        cur[i].status_vars=old->status_vars;
         /* fall through */
       case 0x0000:
         cur[i].type=old->type;
@@ -320,7 +325,7 @@ static struct st_plugin_int *plugin_find
     {
       struct st_plugin_int *plugin= (st_plugin_int *)
         hash_search(&plugin_hash[i], (const byte *)name->str, name->length);
-      if (plugin) 
+      if (plugin)
         DBUG_RETURN(plugin);
     }
   }
@@ -382,7 +387,6 @@ static st_plugin_int *plugin_insert_or_r
                               struct st_plugin_int *));
 }
 
-
 static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
 {
   struct st_plugin_int tmp;
@@ -429,21 +433,20 @@ static my_bool plugin_add(LEX_STRING *na
       tmp.name.length= name_len;
       tmp.ref_count= 0;
       tmp.state= PLUGIN_IS_UNINITIALIZED;
-      if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
+      if (plugin->status_vars)
       {
-        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));
-        goto err;
+        SHOW_VAR array[2]={
+          {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY},
+          {0, 0, SHOW_UNDEF}
+        };
+        if (add_status_vars(array)) // add_status_vars makes a copy
+          goto err;
       }
+      if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
+        goto err;
       if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr))
       {
         tmp_plugin_ptr->state= PLUGIN_IS_FREED;
-        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));
         goto err;
       }
       DBUG_RETURN(FALSE);
@@ -454,6 +457,14 @@ static my_bool plugin_add(LEX_STRING *na
   if (report & REPORT_TO_LOG)
     sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name->str);
 err:
+  if (plugin->status_vars)
+  {
+    SHOW_VAR array[2]={
+      {plugin->name, (char*)plugin->status_vars, SHOW_ARRAY},
+      {0, 0, SHOW_UNDEF}
+    };
+    remove_status_vars(array);
+  }
   plugin_dl_del(dl);
   DBUG_RETURN(TRUE);
 }
@@ -466,6 +477,14 @@ static void plugin_del(LEX_STRING *name)
   DBUG_ENTER("plugin_del");
   if ((plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
   {
+    if (plugin->plugin->status_vars)
+    {
+      SHOW_VAR array[2]={
+        {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
+        {0, 0, SHOW_UNDEF}
+      };
+      remove_status_vars(array);
+    }
     hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin);
     plugin_dl_del(&plugin->plugin_dl->dl);
     plugin->state= PLUGIN_IS_FREED;
@@ -494,7 +513,7 @@ void plugin_unlock(struct st_plugin_int 
 static int plugin_initialize(struct st_plugin_int *plugin)
 {
   DBUG_ENTER("plugin_initialize");
-  
+
   if (plugin->plugin->init)
   {
     if (plugin->plugin->init())
@@ -506,7 +525,7 @@ static int plugin_initialize(struct st_p
       goto err;
     }
   }
-  
+
   switch (plugin->plugin->type)
   {
   case MYSQL_STORAGE_ENGINE_PLUGIN:
@@ -605,11 +624,11 @@ int plugin_init(void)
                   get_hash_key, NULL, 0))
       goto err;
   }
-  
+
   initialized= 1;
 
   DBUG_RETURN(0);
-  
+
 err:
   DBUG_RETURN(1);
 }
@@ -651,9 +670,9 @@ void plugin_load(void)
   MEM_ROOT mem;
   THD *new_thd;
   DBUG_ENTER("plugin_load");
-  
+
   DBUG_ASSERT(initialized);
-  
+
   if (!(new_thd= new THD))
   {
     sql_print_error("Can't allocate memory for plugin structures");
@@ -716,12 +735,7 @@ void plugin_free(void)
   {
     struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
                                               struct st_plugin_dl *);
-#ifdef HAVE_DLOPEN
-    if (tmp->handle)
-    {
-      free_plugin_mem(tmp);
-    }
-#endif
+    free_plugin_mem(tmp);
   }
   delete_dynamic(&plugin_dl_array);
   if (initialized)
@@ -746,7 +760,7 @@ my_bool mysql_install_plugin(THD *thd, L
   tables.table_name= tables.alias= (char *)"plugin";
   if (check_table_access(thd, INSERT_ACL, &tables, 0))
     DBUG_RETURN(TRUE);
-    
+
   /* need to open before acquiring THR_LOCK_plugin or it will deadlock */
   if (! (table = open_ltable(thd, &tables, TL_WRITE)))
     DBUG_RETURN(TRUE);
@@ -755,7 +769,7 @@ my_bool mysql_install_plugin(THD *thd, L
   if (plugin_add(name, dl, REPORT_TO_USER))
     goto err;
   tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
-  
+
   if (plugin_initialize(tmp))
   {
     my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
@@ -774,7 +788,7 @@ my_bool mysql_install_plugin(THD *thd, L
     table->file->print_error(error, MYF(0));
     goto deinit;
   }
-  
+
   rw_unlock(&THR_LOCK_plugin);
   DBUG_RETURN(FALSE);
 deinit:
@@ -815,7 +829,7 @@ my_bool mysql_uninstall_plugin(THD *thd,
     my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
     goto err;
   }
-  
+
   if (plugin->ref_count)
   {
     plugin->state= PLUGIN_IS_DELETED;
@@ -858,13 +872,13 @@ my_bool plugin_foreach(THD *thd, plugin_
   struct st_plugin_int *plugin;
   DBUG_ENTER("mysql_uninstall_plugin");
   rw_rdlock(&THR_LOCK_plugin);
-  
+
   if (type == MYSQL_ANY_PLUGIN)
   {
     for (idx= 0; idx < plugin_array.elements; idx++)
     {
       plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
-      
+
       /* FREED records may have garbage pointers */
       if ((plugin->state != PLUGIN_IS_FREED) &&
           func(thd, plugin, arg))

--- 1.4/sql/sql_plugin.h	Thu Dec 29 21:24:07 2005
+++ 1.5/sql/sql_plugin.h	Thu Jan  5 22:13:45 2006
@@ -17,7 +17,17 @@
 #ifndef _sql_plugin_h
 #define _sql_plugin_h
 
+/*
+  the following #define adds server-only members to enum_mysql_show_type,
+  that is defined in plugin.h
+*/
+#define SHOW_FUNC    SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \
+                     SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE,   \
+                     SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH
 #include <plugin.h>
+#undef SHOW_FUNC
+typedef enum enum_mysql_show_type SHOW_TYPE;
+typedef struct st_mysql_show_var SHOW_VAR;
 
 #define MYSQL_ANY_PLUGIN         -1
 
@@ -65,7 +75,7 @@ extern my_bool mysql_uninstall_plugin(TH
 
 extern my_bool plugin_register_builtin(struct st_mysql_plugin *plugin);
 
-typedef my_bool (plugin_foreach_func)(THD *thd, 
+typedef my_bool (plugin_foreach_func)(THD *thd,
                                       st_plugin_int *plugin,
                                       void *arg);
 extern my_bool plugin_foreach(THD *thd, plugin_foreach_func *func,

--- 1.1/plugin/fulltext/plugin_example.c	Wed Dec 28 13:05:21 2005
+++ 1.2/plugin/fulltext/plugin_example.c	Thu Jan  5 22:13:40 2006
@@ -18,6 +18,8 @@
 #include <m_ctype.h>
 #include <plugin.h>
 
+long number_of_calls=0; /* for SHOW STATUS, see below */
+
 /*
   Simple full-text parser plugin that acts as a replacement for the
   built-in full-text parser:
@@ -167,6 +169,8 @@ int simple_parser_parse(MYSQL_FTPARSER_P
 {
   char *end, *start, *docend= param->doc + param->length;
 
+  number_of_calls++;
+
   for (end= start= param->doc;; end++)
   {
     if (end == docend)
@@ -198,6 +202,16 @@ static struct st_mysql_ftparser simple_p
   simple_parser_deinit              /* parser deinit function */
 };
 
+/*
+  Plugin status variables for SHOW STATUS
+*/
+
+struct st_mysql_show_var simple_status[]=
+{
+  {"static",     "just a static text",     SHOW_CHAR},
+  {"called",     (char *)&number_of_calls, SHOW_LONG},
+  {0,0,0}
+};
 
 /*
   Plugin library descriptor
@@ -211,6 +225,8 @@ mysql_declare_plugin
   "MySQL AB",                 /* author                          */
   "Simple Full-Text Parser",  /* description                     */
   simple_parser_plugin_init,  /* init function (when loaded)     */
-  simple_parser_plugin_deinit /* deinit function (when unloaded) */
+  simple_parser_plugin_deinit,/* deinit function (when unloaded) */
+  0x0001,                     /* version                         */
+  &simple_status              /* status variables                */
 }
 mysql_declare_plugin_end;
Thread
bk commit into 5.1 tree (serg:1.2020)Sergei Golubchik5 Jan