List:Commits« Previous MessageNext Message »
From:antony Date:December 5 2006 7:05pm
Subject:bk commit into 5.1 tree (antony:1.2372)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of antony. When antony 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@stripped, 2006-12-05 11:05:18-08:00, antony@stripped +19 -0
  WL#2936
    "Plugin server variables"
    Revised first cut, fixes a few bugs so that the std test suite runs ok.
    Some code cleanup has been performed.

  BitKeeper/deleted/.del-mysql_client_test.c.rej@stripped, 2006-12-04 16:20:38-08:00, antony@stripped +0 -0
    Rename: tests/mysql_client_test.c.rej -> BitKeeper/deleted/.del-mysql_client_test.c.rej

  BitKeeper/deleted/.del-mysqld.cc.rej@stripped, 2006-12-04 16:20:37-08:00, antony@stripped +0 -0
    Rename: sql/mysqld.cc.rej -> BitKeeper/deleted/.del-mysqld.cc.rej

  BitKeeper/deleted/.del-sql_parse.cc.rej@stripped, 2006-12-04 16:20:38-08:00, antony@stripped +0 -0
    Rename: sql/sql_parse.cc.rej -> BitKeeper/deleted/.del-sql_parse.cc.rej

  BitKeeper/deleted/.del-table.cc.rej@stripped, 2006-12-04 16:20:38-08:00, antony@stripped +0 -0
    Rename: sql/table.cc.rej -> BitKeeper/deleted/.del-table.cc.rej

  include/my_getopt.h@stripped, 2006-12-05 11:05:12-08:00, antony@stripped +2 -7
    revert some of the previous cset
    change app_type to a long (so we can safely store pointers)
    new variable: my_getopt_skip_unknown

  include/mysql/plugin.h@stripped, 2006-12-05 11:05:12-08:00, antony@stripped +190 -1
    declarations for plugin options.

  mysys/my_getopt.c@stripped, 2006-12-05 11:05:12-08:00, antony@stripped +12 -16
    revert some of previous cset
    allow getopt to safely skip over unknown options

  sql/mysql_priv.h@stripped, 2006-12-05 11:05:12-08:00, antony@stripped +1 -1
    remove some global declarations

  sql/mysqld.cc@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +31 -342
    remove all innodb code.
    change order of processing for handing --help --verbose
    add some forward declarations

  sql/set_var.cc@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +276 -505
    remove all innodb code
    new argument to sys_var classes so that new sys_var instances can be
    created at run time.

  sql/set_var.h@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +190 -116
    new struct sys_var_chain (replaces the sys_var::first static)
    all sys_var classes now have an extra constructor parameter.
    new class sys_var_pluginvar
    new funcs mysql_add_sys_var_chain / mysql_del_sys_var_chain

  sql/sql_class.cc@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +5 -0
    initialize dynamic system variables

  sql/sql_class.h@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +13 -2
    new elements in system_variables to handle plugin variables.

  sql/sql_parse.cc@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +0 -1
    remove innodb cruft

  sql/sql_plugin.cc@stripped, 2006-12-05 11:05:13-08:00, antony@stripped +1468 -100
    WL2936 
      first cut

  sql/sql_plugin.h@stripped, 2006-12-05 11:05:14-08:00, antony@stripped +14 -2
    WL2936 
      first cut

  sql/sql_show.cc@stripped, 2006-12-05 11:05:14-08:00, antony@stripped +3 -3
    WL2936 
      first cut

  storage/csv/ha_tina.cc@stripped, 2006-12-05 11:05:14-08:00, antony@stripped +3 -0
    reintroduce have_csv so that init scripts work ok

  storage/innobase/handler/ha_innodb.cc@stripped, 2006-12-05 11:05:14-08:00, antony@stripped +304 -7
    innodb now self-contained, no more cruft in sql/*

# 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:	antony
# Host:	ppcg5.local
# Root:	/Users/antony/Work/mysql-5.1-plugin.3

--- 1.463/sql/mysql_priv.h	2006-12-05 11:05:29 -08:00
+++ 1.464/sql/mysql_priv.h	2006-12-05 11:05:29 -08:00
@@ -1631,7 +1631,6 @@
 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 struct system_variables global_system_variables;
 extern struct system_variables max_system_variables;
 extern struct system_status_var global_status_var;
@@ -1661,6 +1660,7 @@
 extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 extern SHOW_COMP_OPTION have_crypt;
 extern SHOW_COMP_OPTION have_compress;
+extern SHOW_COMP_OPTION have_csv; /* FIXME: init scripts currently need this */
 
 #ifndef __WIN__
 extern pthread_t signal_thread;

--- 1.596/sql/mysqld.cc	2006-12-05 11:05:29 -08:00
+++ 1.597/sql/mysqld.cc	2006-12-05 11:05:29 -08:00
@@ -32,22 +32,13 @@
 #include "rpl_injector.h"
 #endif
 
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-#define OPT_INNODB_DEFAULT 1
-#else
-#define OPT_INNODB_DEFAULT 0
-#endif
-#define OPT_BDB_DEFAULT 0
 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-#define OPT_NDBCLUSTER_DEFAULT 0
 #if defined(NOT_ENOUGH_TESTED) \
   && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
 #define OPT_NDB_SHM_DEFAULT 1
 #else
 #define OPT_NDB_SHM_DEFAULT 0
 #endif
-#else
-#define OPT_NDBCLUSTER_DEFAULT 0
 #endif
 
 #include <thr_alarm.h>
@@ -366,42 +357,6 @@
 handlerton *myisam_hton= NULL;
 handlerton *partition_hton= NULL;
 
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-extern ulong innobase_fast_shutdown;
-extern ulong innobase_large_page_size;
-extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
-extern long innobase_lock_scan_time;
-extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
-extern longlong innobase_log_file_size;
-extern long innobase_log_buffer_size;
-extern longlong innobase_buffer_pool_size;
-extern long innobase_additional_mem_pool_size;
-extern long innobase_file_io_threads, innobase_lock_wait_timeout;
-extern long innobase_force_recovery;
-extern long innobase_open_files;
-extern char *innobase_data_home_dir, *innobase_data_file_path;
-extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-extern char *innobase_unix_file_flush_method;
-/* The following variables have to be my_bool for SHOW VARIABLES to work */
-extern my_bool innobase_log_archive,
-               innobase_use_doublewrite,
-               innobase_use_checksums,
-               innobase_use_large_pages,
-               innobase_use_native_aio,
-               innobase_file_per_table, innobase_locks_unsafe_for_binlog,
-               innobase_create_status_file;
-extern "C" {
-extern ulong srv_max_buf_pool_modified_pct;
-extern ulong srv_max_purge_lag;
-extern ulong srv_auto_extend_increment;
-extern ulong srv_n_spin_wait_rounds;
-extern ulong srv_n_free_tickets_to_enter;
-extern ulong srv_thread_sleep_delay;
-extern ulong srv_thread_concurrency;
-extern ulong srv_commit_concurrency;
-extern ulong srv_flush_log_at_trx_commit;
-}
-#endif
 
 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
 const char *opt_ndbcluster_connectstring= 0;
@@ -562,6 +517,7 @@
 SHOW_COMP_OPTION have_openssl, have_symlink, have_dlopen, have_query_cache;
 SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 SHOW_COMP_OPTION have_crypt, have_compress;
+SHOW_COMP_OPTION have_csv= SHOW_OPTION_NO;
 
 /* Thread specific variables */
 
@@ -700,6 +656,8 @@
 
 /* Function declarations */
 
+static void usage(void);
+static int setup_status_vars(void);
 static void start_signal_handler(void);
 pthread_handler_t signal_hand(void *arg);
 static void mysql_init_variables(void);
@@ -1142,6 +1100,8 @@
 extern "C" void unireg_abort(int exit_code)
 {
   DBUG_ENTER("unireg_abort");
+  if (opt_help)
+    usage();
   if (exit_code)
     sql_print_error("Aborting\n");
   clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */
@@ -2642,7 +2602,7 @@
     Later, in plugin_init, and mysql_install_plugin
     new entries could be added to that list.
   */
-  if (add_status_vars(status_vars))
+  if (setup_status_vars())
     return 1; // an error was already reported
 
   load_defaults(conf_file_name, groups, &argc, &argv);
@@ -2659,10 +2619,6 @@
   {
       my_use_large_pages= 1;
       my_large_page_size= opt_large_page_size;
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-      innobase_use_large_pages= 1;
-      innobase_large_page_size= opt_large_page_size;
-#endif
   }
 #endif /* HAVE_LARGE_PAGES */
 
@@ -2725,7 +2681,8 @@
   if (item_create_init())
     return 1;
   item_init();
-  set_var_init();
+  if (set_var_init())
+    return 1;
   mysys_uses_curses=0;
 #ifdef USE_REGEX
   my_regex_init(&my_charset_latin1);
@@ -3213,36 +3170,22 @@
     using_update_log=1;
   }
 
-  if (plugin_init(opt_bootstrap, defaults_argv))
+  if (plugin_init(defaults_argv, 
+                  (opt_bootstrap ? PLUGIN_INIT_SKIP_DYNAMIC_LOADING : 0) |
+                  (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
   {
     sql_print_error("Failed to init plugins.");
     return 1;
   }
 
-  /* we don't mind ignoring all the --skip-xyz options but
-     we do want to exit if there are any other unknown options */
-  if (defaults_argv && *defaults_argv)
-  {
-    int argc= 0;
-    char **argv= defaults_argv;
-   
-    my_option no_opts[]= {
-      { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
-    };
-
-    for (char** p=argv; *p; p++, argc++);
-
-    my_getopt_unknown_flags= MY_GETOPT_CONSUME_BOOL_FALSE;
-
-    if (handle_options(&argc, &argv, no_opts, get_one_option))
-      return 1;
+  if (opt_help)
+    unireg_abort(0);
 
-    if (argc > 0)
-    {
-      fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv);
-      /* FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code? */
-      return 1;
-    }
+  /* we do want to exit if there are any other unknown options */
+  if (defaults_argv && defaults_argv[1]) /* position 0 is the program name */
+  {
+    fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, defaults_argv[1]);
+    return 1;
   }
 
 
@@ -3274,7 +3217,7 @@
   else
   {
     /* fall back to the log files if tables are not present */
-    LEX_STRING csv_name={STRING_WITH_LEN("csv")};
+    LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
     if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
     {
       /* purecov: begin inspected */
@@ -4705,11 +4648,6 @@
   OPT_STORAGE_ENGINE,          OPT_INIT_FILE,
   OPT_DELAY_KEY_WRITE_ALL,     OPT_SLOW_QUERY_LOG,
   OPT_DELAY_KEY_WRITE,	       OPT_CHARSETS_DIR,
-  OPT_BDB_HOME,                OPT_BDB_LOG,
-  OPT_BDB_TMP,                 OPT_BDB_SYNC,
-  OPT_BDB_LOCK,                OPT_BDB,
-  OPT_BDB_NO_RECOVER,          OPT_BDB_SHARED,
-  OPT_BDB_DATA_DIRECT,         OPT_BDB_LOG_DIRECT,
   OPT_MASTER_HOST,             OPT_MASTER_USER,
   OPT_MASTER_PASSWORD,         OPT_MASTER_PORT,
   OPT_MASTER_INFO_FILE,        OPT_MASTER_CONNECT_RETRY,
@@ -4730,29 +4668,15 @@
   OPT_WANT_CORE,               OPT_CONCURRENT_INSERT,
   OPT_MEMLOCK,                 OPT_MYISAM_RECOVER,
   OPT_REPLICATE_REWRITE_DB,    OPT_SERVER_ID,
-  OPT_SKIP_SLAVE_START,        OPT_SKIP_INNOBASE,
+  OPT_SKIP_SLAVE_START,        OPT_SAFE_SHOW_DB, 
   OPT_SAFEMALLOC_MEM_LIMIT,    OPT_REPLICATE_DO_TABLE,
   OPT_REPLICATE_IGNORE_TABLE,  OPT_REPLICATE_WILD_DO_TABLE,
   OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
   OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
   OPT_ABORT_SLAVE_EVENT_COUNT,
-  OPT_INNODB_DATA_HOME_DIR,
-  OPT_INNODB_DATA_FILE_PATH,
-  OPT_INNODB_LOG_GROUP_HOME_DIR,
-  OPT_INNODB_LOG_ARCH_DIR,
-  OPT_INNODB_LOG_ARCHIVE,
-  OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
-  OPT_INNODB_FLUSH_METHOD,
-  OPT_INNODB_DOUBLEWRITE,
-  OPT_INNODB_CHECKSUMS,
-  OPT_INNODB_FAST_SHUTDOWN,
-  OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB,
-  OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
   OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
-  OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
-  OPT_INNODB, OPT_ISAM,
   OPT_ENGINE_CONDITION_PUSHDOWN,
-  OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT,
+  OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT,
   OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
   OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
   OPT_NDB_MGMD, OPT_NDB_NODEID,
@@ -4814,33 +4738,6 @@
   OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
   OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
   OPT_WAIT_TIMEOUT, OPT_MYISAM_REPAIR_THREADS,
-  OPT_INNODB_MIRRORED_LOG_GROUPS,
-  OPT_INNODB_LOG_FILES_IN_GROUP,
-  OPT_INNODB_LOG_FILE_SIZE,
-  OPT_INNODB_LOG_BUFFER_SIZE,
-  OPT_INNODB_BUFFER_POOL_SIZE,
-  OPT_INNODB_BUFFER_POOL_AWE_MEM_MB,
-  OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
-  OPT_INNODB_MAX_PURGE_LAG,
-  OPT_INNODB_FILE_IO_THREADS,
-  OPT_INNODB_LOCK_WAIT_TIMEOUT,
-  OPT_INNODB_THREAD_CONCURRENCY,
-  OPT_INNODB_COMMIT_CONCURRENCY,
-  OPT_INNODB_FORCE_RECOVERY,
-  OPT_INNODB_STATUS_FILE,
-  OPT_INNODB_MAX_DIRTY_PAGES_PCT,
-  OPT_INNODB_TABLE_LOCKS,
-  OPT_INNODB_SUPPORT_XA,
-  OPT_INNODB_OPEN_FILES,
-  OPT_INNODB_AUTOEXTEND_INCREMENT,
-  OPT_INNODB_SYNC_SPIN_LOOPS,
-  OPT_INNODB_CONCURRENCY_TICKETS,
-  OPT_INNODB_THREAD_SLEEP_DELAY,
-  OPT_BDB_CACHE_SIZE,
-  OPT_BDB_CACHE_PARTS,
-  OPT_BDB_LOG_BUFFER_SIZE,
-  OPT_BDB_MAX_LOCK,
-  OPT_BDB_REGION_SIZE,
   OPT_ERROR_LOG_FILE,
   OPT_DEFAULT_WEEK_FORMAT,
   OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
@@ -4850,7 +4747,6 @@
   OPT_SYNC_REPLICATION,
   OPT_SYNC_REPLICATION_SLAVE_ID,
   OPT_SYNC_REPLICATION_TIMEOUT,
-  OPT_BDB_NOSYNC,
   OPT_ENABLE_SHARED_MEMORY,
   OPT_SHARED_MEMORY_BASE_NAME,
   OPT_OLD_PASSWORDS,
@@ -4885,7 +4781,6 @@
   OPT_PORT_OPEN_TIMEOUT,
   OPT_GENERAL_LOG,
   OPT_SLOW_LOG,
-  OPT_MERGE
 };
 
 
@@ -5109,86 +5004,6 @@
   {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master",
    (gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \
-Disable with --skip-innodb-checksums.", (gptr*) &innobase_use_checksums,
-   (gptr*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-#endif
-  {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
-   "Path to individual files and their sizes.",
-   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR,
-   "The common part for InnoDB table spaces.", (gptr*) &innobase_data_home_dir,
-   (gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0,
-   0},
-  {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, "Enable InnoDB doublewrite buffer (enabled by default). \
-Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
-   (gptr*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-  {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN,
-   "Speeds up the shutdown process of the InnoDB storage engine. Possible "
-   "values are 0, 1 (faster)"
-   /*
-     NetWare can't close unclosed files, can't automatically kill remaining
-     threads, etc, so on this OS we disable the crash-like InnoDB shutdown.
-   */
-#ifndef __NETWARE__
-   " or 2 (fastest - crash-like)"
-#endif
-   ".",
-   (gptr*) &innobase_fast_shutdown,
-   (gptr*) &innobase_fast_shutdown, 0, GET_ULONG, OPT_ARG, 1, 0,
-   IF_NETWARE(1,2), 0, 0, 0},
-  {"innodb_file_per_table", OPT_INNODB_FILE_PER_TABLE,
-   "Stores each InnoDB table to an .ibd file in the database dir.",
-   (gptr*) &innobase_file_per_table,
-   (gptr*) &innobase_file_per_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
-   "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).",
-   (gptr*) &srv_flush_log_at_trx_commit,
-   (gptr*) &srv_flush_log_at_trx_commit,
-   0, GET_ULONG, OPT_ARG,  1, 0, 2, 0, 0, 0},
-  {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD,
-   "With which method to flush data.", (gptr*) &innobase_unix_file_flush_method,
-   (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
-   0, 0, 0},
-  {"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
-   "Force InnoDB to not use next-key locking, to use only row-level locking.",
-   (gptr*) &innobase_locks_unsafe_for_binlog,
-   (gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
-   "Where full logs should be archived.", (gptr*) &innobase_log_arch_dir,
-   (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-  {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE,
-   "Set to 1 if you want to have logs archived.", 0, 0, 0, GET_LONG, OPT_ARG,
-   0, 0, 0, 0, 0, 0},
-  {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR,
-   "Path to InnoDB log files.", (gptr*) &innobase_log_group_home_dir,
-   (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
-   0, 0},
-  {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT,
-   "Percentage of dirty pages allowed in bufferpool.", (gptr*) &srv_max_buf_pool_modified_pct,
-   (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0},
-  {"innodb_max_purge_lag", OPT_INNODB_MAX_PURGE_LAG,
-   "Desired maximum length of the purge queue (0 = no limit)",
-   (gptr*) &srv_max_purge_lag,
-   (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L,
-   0, 1L, 0},
-  {"innodb_status_file", OPT_INNODB_STATUS_FILE,
-   "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
-   (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file,
-   0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-  {"innodb_support_xa", OPT_INNODB_SUPPORT_XA,
-   "Enable InnoDB support for the XA two-phase commit",
-   (gptr*) &global_system_variables.innodb_support_xa,
-   (gptr*) &global_system_variables.innodb_support_xa,
-   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-  {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS,
-   "Enable InnoDB locking in LOCK TABLES",
-   (gptr*) &global_system_variables.innodb_table_locks,
-   (gptr*) &global_system_variables.innodb_table_locks,
-   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-#endif /* End WITH_INNOBASE_STORAGE_ENGINE */
    {"language", 'L',
    "Client error messages in given language. May be given as a full path.",
    (gptr*) &language_ptr, (gptr*) &language_ptr, 0, GET_STR, REQUIRED_ARG,
@@ -5803,84 +5618,6 @@
     (gptr*) &global_system_variables.group_concat_max_len,
     (gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
     REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0},
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
-   "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
-   (gptr*) &innobase_additional_mem_pool_size,
-   (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG,
-   1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0},
-  {"innodb_autoextend_increment", OPT_INNODB_AUTOEXTEND_INCREMENT,
-   "Data file autoextend increment in megabytes",
-   (gptr*) &srv_auto_extend_increment,
-   (gptr*) &srv_auto_extend_increment,
-   0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
-  {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
-   "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
-   (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
-   GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0,
-   1024*1024L, 0},
-  {"innodb_commit_concurrency", OPT_INNODB_COMMIT_CONCURRENCY,
-   "Helps in performance tuning in heavily concurrent environments.",
-   (gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency,
-   0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
-  {"innodb_concurrency_tickets", OPT_INNODB_CONCURRENCY_TICKETS,
-   "Number of times a thread is allowed to enter InnoDB within the same \
-    SQL query after it has once got the ticket",
-   (gptr*) &srv_n_free_tickets_to_enter,
-   (gptr*) &srv_n_free_tickets_to_enter,
-   0, GET_LONG, REQUIRED_ARG, 500L, 1L, ~0L, 0, 1L, 0},
-  {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS,
-   "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads,
-   (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0,
-   1, 0},
-  {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY,
-   "Helps to save your data in case the disk image of the database becomes corrupt.",
-   (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0,
-   GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0},
-  {"innodb_lock_wait_timeout", OPT_INNODB_LOCK_WAIT_TIMEOUT,
-   "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.",
-   (gptr*) &innobase_lock_wait_timeout, (gptr*) &innobase_lock_wait_timeout,
-   0, GET_LONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
-  {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE,
-   "The size of the buffer which InnoDB uses to write log to the log files on disk.",
-   (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0,
-   GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0},
-  {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE,
-   "Size of each log file in a log group.",
-   (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0,
-   GET_LL, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 0,
-   1024*1024L, 0},
-  {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP,
-   "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
-   (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group,
-   0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0},
-  {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS,
-   "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
-   (gptr*) &innobase_mirrored_log_groups,
-   (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10,
-   0, 1, 0},
-  {"innodb_open_files", OPT_INNODB_OPEN_FILES,
-   "How many files at the maximum InnoDB keeps open at the same time.",
-   (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0,
-   GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0},
-  {"innodb_sync_spin_loops", OPT_INNODB_SYNC_SPIN_LOOPS,
-   "Count of spin-loop rounds in InnoDB mutexes",
-   (gptr*) &srv_n_spin_wait_rounds,
-   (gptr*) &srv_n_spin_wait_rounds,
-   0, GET_LONG, REQUIRED_ARG, 20L, 0L, ~0L, 0, 1L, 0},
-  {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
-   "Helps in performance tuning in heavily concurrent environments. "
-   "Sets the maximum number of threads allowed inside InnoDB. Value 0"
-   " will disable the thread throttling.",
-   (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
-   0, GET_LONG, REQUIRED_ARG, 8, 0, 1000, 0, 1, 0},
-  {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
-   "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
-    " disable a sleep",
-   (gptr*) &srv_thread_sleep_delay,
-   (gptr*) &srv_thread_sleep_delay,
-   0, GET_LONG, REQUIRED_ARG, 10000L, 0L, ~0L, 0, 1L, 0},
-#endif /* WITH_INNOBASE_STORAGE_ENGINE */
   {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
    "The number of seconds the server waits for activity on an interactive connection before closing it.",
    (gptr*) &global_system_variables.net_interactive_timeout,
@@ -6892,8 +6629,7 @@
   fix_paths();
   set_ports();
 
-  my_print_help(my_long_options);
-  my_print_variables(my_long_options);
+  plugin_print_help(my_long_options, sizeof(my_long_options)/sizeof(my_option));
 
   puts("\n\
 To see what values a running MySQL server is using, type\n\
@@ -7526,10 +7262,6 @@
     global_system_variables.tx_isolation= (type-1);
     break;
   }
-  case OPT_MERGE:
-  case OPT_BDB:
-  case OPT_NDBCLUSTER:
-    break;
 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
   case OPT_NDB_MGMD:
   case OPT_NDB_NODEID:
@@ -7577,18 +7309,6 @@
       ndb_extra_logging= atoi(argument);
     break;
 #endif
-  case OPT_INNODB:
-    break;
-  case OPT_INNODB_DATA_FILE_PATH:
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-    innobase_data_file_path= argument;
-#endif
-    break;
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  case OPT_INNODB_LOG_ARCHIVE:
-    innobase_log_archive= argument ? test(atoi(argument)) : 1;
-    break;
-#endif /* WITH_INNOBASE_STORAGE_ENGINE */
   case OPT_MYISAM_RECOVER:
   {
     if (!argument || !argument[0])
@@ -7733,7 +7453,9 @@
   strmake(def_ft_boolean_syntax, ft_boolean_syntax,
 	  sizeof(ft_boolean_syntax)-1);
   my_getopt_error_reporter= option_error_reporter;
-  my_getopt_unknown_flags= MY_GETOPT_IGNORE_BOOL; /* ignore unknown bools */
+
+  /* Skip unknown options so that they may be processed later by plugins */
+  my_getopt_skip_unknown= TRUE;
 
   if ((ho_error= handle_options(&argc, &argv, my_long_options,
                                 get_one_option)))
@@ -7743,11 +7465,6 @@
       !opt_slow_log)
     sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
 
-  if (opt_help)
-  {
-    usage();
-    exit(0);
-  }
 #if defined(HAVE_BROKEN_REALPATH)
   my_use_symdir=0;
   my_disable_symlinks=1;
@@ -8040,6 +7757,11 @@
 }
 
 
+static int setup_status_vars(void)
+{
+  return add_status_vars(status_vars);
+}
+
 /* Clear most status variables */
 void refresh_status(THD *thd)
 {
@@ -8076,41 +7798,8 @@
 
 
 /*****************************************************************************
-  Instantiate have_xyx for missing storage engines
+  Instantiate variables for missing storage engines
 *****************************************************************************/
-
-#ifndef WITH_INNOBASE_STORAGE_ENGINE
-uint innobase_flush_log_at_trx_commit;
-ulong innobase_fast_shutdown;
-long innobase_mirrored_log_groups, innobase_log_files_in_group;
-longlong innobase_log_file_size;
-long innobase_log_buffer_size;
-longlong innobase_buffer_pool_size;
-long innobase_additional_mem_pool_size;
-long innobase_file_io_threads, innobase_lock_wait_timeout;
-long innobase_force_recovery;
-long innobase_open_files;
-char *innobase_data_home_dir, *innobase_data_file_path;
-char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-char *innobase_unix_file_flush_method;
-my_bool innobase_log_archive,
-        innobase_use_doublewrite,
-        innobase_use_checksums,
-        innobase_file_per_table,
-        innobase_locks_unsafe_for_binlog;
-
-extern "C" {
-ulong srv_max_buf_pool_modified_pct;
-ulong srv_max_purge_lag;
-ulong srv_auto_extend_increment;
-ulong srv_n_spin_wait_rounds;
-ulong srv_n_free_tickets_to_enter;
-ulong srv_thread_sleep_delay;
-ulong srv_thread_concurrency;
-ulong srv_commit_concurrency;
-}
-
-#endif
 
 #ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
 ulong ndb_cache_check_time;

--- 1.301/sql/sql_class.cc	2006-12-05 11:05:29 -08:00
+++ 1.302/sql/sql_class.cc	2006-12-05 11:05:29 -08:00
@@ -326,6 +326,10 @@
 {
   pthread_mutex_lock(&LOCK_global_system_variables);
   variables= global_system_variables;
+  /* we are going to allocate these lazily */
+  variables.dynamic_variables_version= 0;
+  variables.dynamic_variables_size= 0;
+  variables.dynamic_variables_ptr= 0;
   variables.time_format= date_time_format_copy((THD*) 0,
 					       variables.time_format);
   variables.date_format= date_time_format_copy((THD*) 0,
@@ -475,6 +479,7 @@
     cleanup();
 
   ha_close_connection(this);
+  mysql_pluginvar_cleanup(this);
 
   DBUG_PRINT("info", ("freeing security context"));
   main_security_ctx.destroy();

--- 1.331/sql/sql_class.h	2006-12-05 11:05:29 -08:00
+++ 1.332/sql/sql_class.h	2006-12-05 11:05:29 -08:00
@@ -181,6 +181,19 @@
 
 struct system_variables
 {
+  /*
+    How dynamically allocated system variables are handled:
+    
+    The global_system_variables and max_system_variables are "authoritive"
+    They both should have the same 'version' and 'size'.
+    When attempting to access a dynamic variable, if the session version
+    is out of date, then the session version is updated and realloced if
+    neccessary and bytes copied from global to make up for missing data.
+  */ 
+  ulong dynamic_variables_version;
+  char* dynamic_variables_ptr;
+  uint dynamic_variables_size;
+  
   ulonglong myisam_max_extra_sort_file_size;
   ulonglong myisam_max_sort_file_size;
   ulonglong max_heap_table_size;
@@ -242,8 +255,6 @@
   my_bool new_mode;
   my_bool query_cache_wlock_invalidate;
   my_bool engine_condition_pushdown;
-  my_bool innodb_table_locks;
-  my_bool innodb_support_xa;
   my_bool ndb_force_send;
   my_bool ndb_use_copying_alter_table;
   my_bool ndb_use_exact_count;

--- 1.602/sql/sql_parse.cc	2006-12-05 11:05:29 -08:00
+++ 1.603/sql/sql_parse.cc	2006-12-05 11:05:29 -08:00
@@ -1909,7 +1909,6 @@
     TABLE_LIST table_list;
     LEX_STRING conv_name;
     /* Saved variable value */
-    my_bool old_innodb_table_locks=  thd->variables.innodb_table_locks;
     uint dummy;
 
     /* used as fields initializator */

--- 1.378/sql/sql_show.cc	2006-12-05 11:05:29 -08:00
+++ 1.379/sql/sql_show.cc	2006-12-05 11:05:29 -08:00
@@ -4409,7 +4409,7 @@
   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, enumerate_sys_vars(thd),
                          lex->option_type, 0, "", tables->table, 0);
   pthread_mutex_unlock(&LOCK_global_system_variables);
   DBUG_RETURN(res);
@@ -5180,7 +5180,7 @@
   DBUG_ENTER("fill_schema_global_variables");
   
   pthread_mutex_lock(&LOCK_global_system_variables);
-  res= show_status_array(thd, "", init_vars, OPT_GLOBAL,
+  res= show_status_array(thd, "", enumerate_sys_vars(thd), OPT_GLOBAL,
                          NULL, "", tables->table, 1);
   pthread_mutex_unlock(&LOCK_global_system_variables);
   
@@ -5193,7 +5193,7 @@
   DBUG_ENTER("fill_schema_session_variables");
   
   pthread_mutex_lock(&LOCK_global_system_variables);
-  res= show_status_array(thd, "", init_vars, OPT_SESSION,
+  res= show_status_array(thd, "", enumerate_sys_vars(thd), OPT_SESSION,
                          NULL, "", tables->table, 1);
   pthread_mutex_unlock(&LOCK_global_system_variables);
   

--- 1.71/storage/csv/ha_tina.cc	2006-12-05 11:05:29 -08:00
+++ 1.72/storage/csv/ha_tina.cc	2006-12-05 11:05:29 -08:00
@@ -52,6 +52,8 @@
 
 #include <mysql/plugin.h>
 
+extern SHOW_COMP_OPTION have_csv; /* FIXME: init scripts currently need this */
+
 /*
   uchar + uchar + ulonglong + ulonglong + ulonglong + ulonglong + uchar
 */
@@ -162,6 +164,7 @@
   tina_hton->create= tina_create_handler;
   tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | 
                      HTON_NO_PARTITION);
+  have_csv= SHOW_OPTION_YES;
   return 0;
 }
 

--- 1.18/include/my_getopt.h	2006-12-05 11:05:29 -08:00
+++ 1.19/include/my_getopt.h	2006-12-05 11:05:29 -08:00
@@ -34,11 +34,6 @@
 #define GET_ASK_ADDR	 128
 #define GET_TYPE_MASK	 127
 
-#define MY_GETOPT_IGNORE_BOOL_FALSE	1
-#define MY_GETOPT_IGNORE_BOOL_TRUE	2
-#define MY_GETOPT_IGNORE_BOOL		3
-#define MY_GETOPT_CONSUME_BOOL_FALSE	4
-
 
 enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
 
@@ -57,7 +52,7 @@
   longlong   max_value;                 /* Max allowed value */
   longlong   sub_size;                  /* Subtract this from given value */
   long       block_size;                /* Value should be a mult. of this */
-  int        app_type;                  /* To be used by an application */
+  long       app_type;                  /* To be used by an application */
 };
 
 typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
@@ -65,7 +60,7 @@
 
 extern char *disabled_my_option;
 extern my_bool my_getopt_print_errors;
-extern int my_getopt_unknown_flags;
+extern my_bool my_getopt_skip_unknown;
 extern my_error_reporter my_getopt_error_reporter;
 
 extern int handle_options (int *argc, char ***argv, 

--- 1.58/mysys/my_getopt.c	2006-12-05 11:05:29 -08:00
+++ 1.59/mysys/my_getopt.c	2006-12-05 11:05:29 -08:00
@@ -60,13 +60,11 @@
 my_bool my_getopt_print_errors= 1;
 
 /* 
-   This is a flag that can be set in client programs.
-   MY_GETOPT_IGNORE_BOOL_FALSE means that my_getopt will ignore unknown 
-   boolean options which evaluate to FALSE and MY_GETOPT_IGNORE_BOOL_TRUE
-   signals the same for TRUE.
+   This is a flag that can be set in client programs. 1 neabs rgar
+   my_getopt will skip over options it does not know how to handle.
 */
 
-int my_getopt_unknown_flags= 0;
+my_bool my_getopt_skip_unknown= 0;
 
 static void default_reporter(enum loglevel level __attribute__((unused)),
                              const char *format, ...)
@@ -115,6 +113,7 @@
 
   for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
   {
+    char **first= pos;
     char *cur_arg= *pos;
     if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
     {
@@ -266,6 +265,14 @@
 	  }
 	  if (!opt_found)
 	  {
+	    if (my_getopt_skip_unknown)
+	    {
+	      /* preserve all the components of this unknown option */
+	      do {
+	        (*argv)[argvpos++]= *first++;
+	      } while (first <= pos);
+	      continue;
+	    }
 	    if (must_be_var)
 	    {
 	      if (my_getopt_print_errors)
@@ -278,17 +285,6 @@
 	    }
 	    else
 	    {
-	      if (option_is_bool && optend == disabled_my_option &&
-	          (my_getopt_unknown_flags & MY_GETOPT_CONSUME_BOOL_FALSE))
-		continue;
-	      if (option_is_bool && 
-	          (my_getopt_unknown_flags & MY_GETOPT_IGNORE_BOOL) &&
-		  ((optend == disabled_my_option) || 
-		   (my_getopt_unknown_flags & MY_GETOPT_IGNORE_BOOL_TRUE)))
-	      {
-                (*argv)[argvpos++]= cur_arg - 2;
-	        continue;
-	      }
 	      if (my_getopt_print_errors)
                 my_getopt_error_reporter(option_is_loose ? 
                                            WARNING_LEVEL : ERROR_LEVEL,

--- 1.314/storage/innobase/handler/ha_innodb.cc	2006-12-05 11:05:29 -08:00
+++ 1.315/storage/innobase/handler/ha_innodb.cc	2006-12-05 11:05:29 -08:00
@@ -217,6 +217,20 @@
 
 static const char innobase_hton_name[]= "InnoDB";
 
+
+static struct st_mysql_thd_var_bool sys_var_support_xa= {
+  MYSQL_THD_VAR_BOOL, PLUGIN_VAR_OPTARG,
+  "support_xa", "Enable InnoDB support for the XA two-phase commit",
+  NULL /* notify func */, 0, TRUE
+};
+
+static struct st_mysql_thd_var_bool sys_var_table_locks= {
+  MYSQL_THD_VAR_BOOL, PLUGIN_VAR_OPTARG,
+  "table_locks", "Enable InnoDB locking in LOCK TABLES",
+  NULL /* notify func */, 0, TRUE
+};
+
+
 static handler *innobase_create_handler(handlerton *hton,
                                         TABLE_SHARE *table, 
                                         MEM_ROOT *mem_root)
@@ -870,7 +884,7 @@
 
 		/* Update the info whether we should skip XA steps that eat
 		CPU time */
-		trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
+		trx->support_xa = THDVAR(thd, sys_var_support_xa, my_bool);
 
 		thd->ha_data[hton->slot] = trx;
 	} else {
@@ -1379,6 +1393,14 @@
         innobase_hton->flags=HTON_NO_FLAGS;
         innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
 
+#ifdef HAVE_LARGE_PAGES
+	if (my_use_large_pages)
+	{
+		innobase_use_large_pages= 1;
+		innobase_large_page_size= opt_large_page_size;
+	}
+#endif
+
 	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
 
 #ifdef UNIV_DEBUG
@@ -1758,7 +1780,7 @@
 	trx = check_trx_exists(hton, thd);
 
 	/* Update the info whether we should skip XA steps that eat CPU time */
-	trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
+	trx->support_xa = THDVAR(thd, sys_var_support_xa, my_bool);
 
 	/* Release a possible FIFO ticket and search latch. Since we will
 	reserve the kernel mutex, we have to release the search system latch
@@ -1991,7 +2013,7 @@
 	trx = check_trx_exists(hton, thd);
 
 	/* Update the info whether we should skip XA steps that eat CPU time */
-	trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
+	trx->support_xa = THDVAR(thd, sys_var_support_xa, my_bool);
 
 	/* Release a possible FIFO ticket and search latch. Since we will
 	reserve the kernel mutex, we have to release the search system latch
@@ -6328,7 +6350,7 @@
 
 			if (thd->in_lock_tables &&
 				thd->lex->sql_command == SQLCOM_LOCK_TABLES &&
-				thd->variables.innodb_table_locks &&
+				THDVAR(thd, sys_var_table_locks, my_bool) &&
 				(thd->options & OPTION_NOT_AUTOCOMMIT)) {
 
 				ulint	error = row_lock_table_for_mysql(
@@ -6453,7 +6475,7 @@
 		trx->active_trans = 1;
 	}
 
-	if (thd->in_lock_tables && thd->variables.innodb_table_locks) {
+	if (thd->in_lock_tables && THDVAR(thd, sys_var_table_locks, my_bool)) {
 		ulint	error = DB_SUCCESS;
 
 		error = row_lock_table_for_mysql(prebuilt, NULL, 0);
@@ -7416,7 +7438,7 @@
 		trx->active_trans = 2;
 	}
 
-	if (!thd->variables.innodb_support_xa) {
+	if (!THDVAR(thd, sys_var_support_xa, my_bool)) {
 
 		return(0);
 	}
@@ -7626,6 +7648,281 @@
 struct st_mysql_storage_engine innobase_storage_engine=
 { MYSQL_HANDLERTON_INTERFACE_VERSION };
 
+static struct st_mysql_sys_var_bool sys_var_checksums= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_NOARG | PLUGIN_VAR_READONLY,
+  "checksums", "Enable InnoDB checksums validation (enabled by default). \
+Disable with --skip-innodb-checksums.",
+  NULL /* notify func */, &innobase_use_checksums, TRUE
+};
+
+static struct st_mysql_sys_var_str sys_var_data_home_dir= {
+  MYSQL_SYS_VAR_STR, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "data_home_dir", "The common part for InnoDB table spaces.",
+  NULL /* notify func */, NULL /* update func */, 
+  &innobase_data_home_dir, 0
+};
+
+static struct st_mysql_sys_var_bool sys_var_doublewrite= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_NOARG | PLUGIN_VAR_READONLY,
+  "doublewrite", "Enable InnoDB doublewrite buffer (enabled by default). \
+Disable with --skip-innodb-doublewrite.",
+  NULL /* notify func */, &innobase_use_doublewrite, TRUE
+};
+
+static struct st_mysql_sys_var_long sys_var_fast_shutdown= {
+  MYSQL_SYS_VAR_UINT, PLUGIN_VAR_OPTARG,
+  "fast_shutdown", 
+  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
+  "values are 0, 1 (faster)"
+  /*
+    NetWare can't close unclosed files, can't automatically kill remaining
+    threads, etc, so on this OS we disable the crash-like InnoDB shutdown.
+  */
+#ifndef __NETWARE__
+  " or 2 (fastest - crash-like)"
+#endif
+  ".",
+  NULL /* notify func */, &innobase_fast_shutdown, 1,
+  0, IF_NETWARE(1,2), 0
+};
+
+static struct st_mysql_sys_var_bool sys_var_file_per_table= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_NOARG | PLUGIN_VAR_READONLY,
+  "file_per_table", "Stores each InnoDB table to an .ibd file in the database dir.",
+  NULL /* notify func */, &innobase_file_per_table, FALSE
+};
+
+static struct st_mysql_sys_var_long sys_var_flush_log_at_trx_commit= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_OPTARG,
+ "flush_log_at_trx_commit", "Set to 0 (write and flush once per second),\
+ 1 (write and flush at each commit) or 2 (write at commit, flush once per second).",
+  NULL /* notify func */, &srv_flush_log_at_trx_commit, 1,
+  0, 2, 0
+};
+
+static struct st_mysql_sys_var_str sys_var_flush_method= {
+  MYSQL_SYS_VAR_STR, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "flush_method", "With which method to flush data.",
+  NULL /* notify func */, NULL /* update func */, 
+  &innobase_unix_file_flush_method, NULL
+};
+
+static struct st_mysql_sys_var_bool sys_var_locks_unsafe_for_binlog= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_NOARG | PLUGIN_VAR_READONLY,
+  "locks_unsafe_for_binlog",
+  "Force InnoDB to not use next-key locking, to use only row-level locking.",
+  NULL /* notify func */, &innobase_locks_unsafe_for_binlog, FALSE
+};
+
+static struct st_mysql_sys_var_str sys_var_log_arch_dir= {
+  MYSQL_SYS_VAR_STR, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "log_arch_dir", "Where full logs should be archived.",
+  NULL /* notify func */, NULL /* update func */, 
+  &innobase_log_arch_dir, NULL
+};
+
+static struct st_mysql_sys_var_bool sys_var_log_archive= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_OPTARG | PLUGIN_VAR_READONLY,
+  "log_archive", "Set to 1 if you want to have logs archived.",
+  NULL /* notify func */, &innobase_log_archive, NULL
+};
+
+static struct st_mysql_sys_var_str sys_var_log_group_home_dir= {
+  MYSQL_SYS_VAR_STR, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "log_group_home_dir", "Path to InnoDB log files.", 
+  NULL /* notify func */, NULL /* update func */, 
+  &innobase_log_group_home_dir, NULL
+};
+
+static struct st_mysql_sys_var_long sys_var_max_dirty_pages= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG,
+  "max_dirty_pages_pct", "Percentage of dirty pages allowed in bufferpool.",
+  NULL /* notify func */, &srv_max_buf_pool_modified_pct, 90,
+  0, 100, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_max_purge_lag= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG,
+  "max_purge_lag", "Desired maximum length of the purge queue (0 = no limit)",
+  NULL /* notify func */, &srv_max_purge_lag, 0,
+  0, ~0L, 0
+};
+
+static struct st_mysql_sys_var_bool sys_var_status_file= {
+  MYSQL_SYS_VAR_BOOL, PLUGIN_VAR_OPTARG | PLUGIN_VAR_NOSYSVAR,
+  "status_file", "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
+  NULL /* notify func */, &innobase_create_status_file, FALSE
+};
+
+static struct st_mysql_sys_var_long sys_var_additional_mem_pool_size= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "additional_mem_pool_size", "Size of a memory pool InnoDB uses to store \
+data dictionary information and other internal data structures.",
+  NULL, (ulong*) &innobase_additional_mem_pool_size, 1*1024*1024L,
+  512*1024L, ~0L, 1024
+};
+
+static struct st_mysql_sys_var_long sys_var_autoextend_increment= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG,
+  "autoextend_increment", "Data file autoextend increment in megabytes",
+  NULL /* notify func */, &srv_auto_extend_increment, 8L,
+  1L, 1000L, 0
+};
+
+static struct st_mysql_sys_var_longlong sys_var_buffer_pool_size= {
+  MYSQL_SYS_VAR_LONGLONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "buffer_pool_size", "The size of the memory buffer InnoDB uses to \
+cache data and indexes of its tables.",
+  NULL, (ulonglong*) &innobase_buffer_pool_size, 8*1024*1024L, 
+  1024*1024L, LONGLONG_MAX, 1024*1024L
+};
+
+static struct st_mysql_sys_var_long sys_var_commit_concurrency= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG,
+  "commit_concurrency",
+  "Helps in performance tuning in heavily concurrent environments.",
+  NULL /* notify func */, &srv_commit_concurrency, 0,
+  0, 1000, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_concurrency_tickets= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG,
+  "concurrency_tickets", "Number of times a thread is allowed to enter \
+InnoDB within the same SQL query after it has once got the ticket",
+  NULL /* notify func */, &srv_n_free_tickets_to_enter, 500L,
+  1L, ~0L, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_file_io_threads= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "file_io_threads", "Number of file I/O threads in InnoDB.",
+  NULL /* notify func */, (ulong*) &innobase_file_io_threads, 4,
+  4, 64, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_force_recovery= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "force_recovery", "Helps to save your data in case the disk \
+image of the database becomes corrupt.",
+  NULL /* notify func */, (ulong*) &innobase_force_recovery, 0,
+  0, 6, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_lock_wait_timeout= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "lock_wait_timeout", "Timeout in seconds an InnoDB transaction may \
+wait for a lock before being rolled back.",
+  NULL /* notify func */, (ulong*) &innobase_lock_wait_timeout, 50,
+  1, 1024 * 1024 * 1024, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_log_buffer_size= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "log_buffer_size", "The size of the buffer which InnoDB uses to write \
+log to the log files on disk.",
+  NULL /* notify func */, (ulong*) &innobase_log_buffer_size, 1024*1024L,
+  256*1024L, ~0L, 1024
+};
+
+static struct st_mysql_sys_var_longlong sys_var_log_file_size= {
+  MYSQL_SYS_VAR_LONGLONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "log_file_size", "Size of each log file in a log group.",
+  NULL /* notify func */, (ulonglong*) &innobase_log_file_size, 5*1024*1024L,
+  1*1024*1024L, LONGLONG_MAX, 1024*1024L
+};
+
+static struct st_mysql_sys_var_long sys_var_log_files_in_group= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "log_files_in_group", "Number of log files in the log group. InnoDB \
+writes to the files in a circular fashion. Value 3 is recommended here.",
+  NULL /* notify func */, (ulong*) &innobase_log_files_in_group, 2,
+  2, 100, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_mirrored_log_groups= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "mirrored_log_groups", "Number of identical copies of log groups we \
+keep for the database. Currently this should be set to 1.",
+  NULL /* notify func */, (ulong*) &innobase_mirrored_log_groups, 1,
+  1, 10, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_open_files= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "open_files",
+  "How many files at the maximum InnoDB keeps open at the same time.",
+  NULL /* notify func */, (ulong*) &innobase_open_files, 300L,
+  10L, ~0L, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_sync_spin_loops= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG,
+  "sync_spin_loops", "Count of spin-loop rounds in InnoDB mutexes",
+  NULL /* notify func */, &srv_n_spin_wait_rounds, 20L,
+  0L, ~0L, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_thread_concurrency= {
+  MYSQL_SYS_VAR_LONG, PLUGIN_VAR_REQARG,
+  "thread_concurrency", "Helps in performance tuning in heavily \
+concurrent environments. Sets the maximum number of threads allowed \
+inside InnoDB. Value 0 will disable the thread throttling.",
+  NULL /* notify func */, &srv_thread_concurrency, 8,
+  0, 1000, 0
+};
+
+static struct st_mysql_sys_var_long sys_var_thread_sleep_delay= {
+  MYSQL_SYS_VAR_ULONG, PLUGIN_VAR_REQARG,
+  "thread_sleep_delay", "Time of innodb thread sleeping before joining \
+InnoDB queue (usec). Value 0 disable a sleep",
+  NULL /* notify func */, &srv_thread_sleep_delay, 10000L,
+  0L, ~0L, 0
+};
+
+static struct st_mysql_sys_var_str sys_var_data_file_path= {
+  MYSQL_SYS_VAR_STR, PLUGIN_VAR_REQARG | PLUGIN_VAR_READONLY,
+  "data_file_path", "Path to individual files and their sizes.",
+  NULL /* notify func */, NULL /* update func */, 
+  &innobase_data_file_path, NULL
+};
+
+static struct st_mysql_sys_var* innobase_system_variables[]= {
+  (struct st_mysql_sys_var *) &sys_var_checksums,
+  (struct st_mysql_sys_var *) &sys_var_data_home_dir,
+  (struct st_mysql_sys_var *) &sys_var_doublewrite,
+  (struct st_mysql_sys_var *) &sys_var_fast_shutdown,
+  (struct st_mysql_sys_var *) &sys_var_file_per_table,
+  (struct st_mysql_sys_var *) &sys_var_flush_log_at_trx_commit,
+  (struct st_mysql_sys_var *) &sys_var_flush_method,
+  (struct st_mysql_sys_var *) &sys_var_locks_unsafe_for_binlog,
+  (struct st_mysql_sys_var *) &sys_var_log_arch_dir,
+  (struct st_mysql_sys_var *) &sys_var_log_archive,
+  (struct st_mysql_sys_var *) &sys_var_log_group_home_dir,
+  (struct st_mysql_sys_var *) &sys_var_max_dirty_pages,
+  (struct st_mysql_sys_var *) &sys_var_max_purge_lag,
+  (struct st_mysql_sys_var *) &sys_var_status_file,
+  (struct st_mysql_sys_var *) &sys_var_support_xa,
+  (struct st_mysql_sys_var *) &sys_var_table_locks,
+  (struct st_mysql_sys_var *) &sys_var_additional_mem_pool_size,
+  (struct st_mysql_sys_var *) &sys_var_autoextend_increment,
+  (struct st_mysql_sys_var *) &sys_var_buffer_pool_size,
+  (struct st_mysql_sys_var *) &sys_var_commit_concurrency,
+  (struct st_mysql_sys_var *) &sys_var_concurrency_tickets,
+  (struct st_mysql_sys_var *) &sys_var_file_io_threads,
+  (struct st_mysql_sys_var *) &sys_var_force_recovery,
+  (struct st_mysql_sys_var *) &sys_var_lock_wait_timeout,
+  (struct st_mysql_sys_var *) &sys_var_log_buffer_size,
+  (struct st_mysql_sys_var *) &sys_var_log_file_size,
+  (struct st_mysql_sys_var *) &sys_var_log_files_in_group,
+  (struct st_mysql_sys_var *) &sys_var_mirrored_log_groups,
+  (struct st_mysql_sys_var *) &sys_var_open_files,
+  (struct st_mysql_sys_var *) &sys_var_sync_spin_loops,
+  (struct st_mysql_sys_var *) &sys_var_thread_concurrency,
+  (struct st_mysql_sys_var *) &sys_var_thread_sleep_delay,
+  (struct st_mysql_sys_var *) &sys_var_data_file_path,
+  NULL
+};
+
 mysql_declare_plugin(innobase)
 {
   MYSQL_STORAGE_ENGINE_PLUGIN,
@@ -7638,7 +7935,7 @@
   NULL, /* Plugin Deinit */
   0x0100 /* 1.0 */,
   innodb_status_variables_export,/* status variables             */
-  NULL,                       /* system variables                */
+  innobase_system_variables, /* system variables */
   NULL                        /* config options                  */
 }
 mysql_declare_plugin_end;

--- 1.206/sql/set_var.cc	2006-12-05 11:05:29 -08:00
+++ 1.207/sql/set_var.cc	2006-12-05 11:05:29 -08:00
@@ -59,38 +59,6 @@
 
 #include "events.h"
 
-/* WITH_INNOBASE_STORAGE_ENGINE */
-extern uint innobase_flush_log_at_trx_commit;
-extern ulong innobase_fast_shutdown;
-extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
-extern longlong innobase_log_file_size;
-extern long innobase_log_buffer_size;
-extern longlong innobase_buffer_pool_size;
-extern long innobase_additional_mem_pool_size;
-extern long innobase_file_io_threads, innobase_lock_wait_timeout;
-extern long innobase_force_recovery;
-extern long innobase_open_files;
-extern char *innobase_data_home_dir, *innobase_data_file_path;
-extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
-extern char *innobase_unix_file_flush_method;
-/* The following variables have to be my_bool for SHOW VARIABLES to work */
-extern my_bool innobase_log_archive,
-               innobase_use_doublewrite,
-               innobase_use_checksums,
-               innobase_file_per_table,
-               innobase_locks_unsafe_for_binlog;
-
-extern "C" {
-extern ulong srv_max_buf_pool_modified_pct;
-extern ulong srv_max_purge_lag;
-extern ulong srv_auto_extend_increment;
-extern ulong srv_n_spin_wait_rounds;
-extern ulong srv_n_free_tickets_to_enter;
-extern ulong srv_thread_sleep_delay;
-extern ulong srv_thread_concurrency;
-extern ulong srv_commit_concurrency;
-extern ulong srv_flush_log_at_trx_commit;
-}
 
 /* WITH_NDBCLUSTER_STORAGE_ENGINE */
 extern ulong ndb_cache_check_time;
@@ -100,8 +68,6 @@
 extern ulong ndb_report_thresh_binlog_mem_usage;
 #endif
 
-
-
 static HASH system_variable_hash;
 const char *bool_type_names[]= { "OFF", "ON", NullS };
 TYPELIB bool_typelib=
@@ -172,517 +138,491 @@
   it in the constructor (see sys_var class for details).
 */
 
-sys_var *sys_var::first= NULL;
-uint sys_var::sys_vars= 0;
+static sys_var_chain vars = { NULL, NULL };
 
-sys_var_thd_ulong	sys_auto_increment_increment("auto_increment_increment",
+sys_var_thd_ulong	sys_auto_increment_increment(vars, "auto_increment_increment",
                                                      &SV::auto_increment_increment);
-sys_var_thd_ulong	sys_auto_increment_offset("auto_increment_offset",
+sys_var_thd_ulong	sys_auto_increment_offset(vars, "auto_increment_offset",
                                                   &SV::auto_increment_offset);
 
-sys_var_bool_ptr	sys_automatic_sp_privileges("automatic_sp_privileges",
+sys_var_bool_ptr	sys_automatic_sp_privileges(vars, "automatic_sp_privileges",
 					      &sp_automatic_privileges);
 
-sys_var_const_str       sys_basedir("basedir", mysql_home);
-sys_var_long_ptr	sys_binlog_cache_size("binlog_cache_size",
+sys_var_const_str       sys_basedir(vars, "basedir", mysql_home);
+sys_var_long_ptr	sys_binlog_cache_size(vars, "binlog_cache_size",
 					      &binlog_cache_size);
-sys_var_thd_binlog_format sys_binlog_format("binlog_format",
+sys_var_thd_binlog_format sys_binlog_format(vars, "binlog_format",
                                             &SV::binlog_format);
-sys_var_thd_ulong	sys_bulk_insert_buff_size("bulk_insert_buffer_size",
+sys_var_thd_ulong	sys_bulk_insert_buff_size(vars, "bulk_insert_buffer_size",
 						  &SV::bulk_insert_buff_size);
-sys_var_character_set_server	sys_character_set_server("character_set_server");
-sys_var_const_str       sys_charset_system("character_set_system",
+sys_var_character_set_server	sys_character_set_server(vars, "character_set_server");
+sys_var_const_str       sys_charset_system(vars, "character_set_system",
                                            (char *)my_charset_utf8_general_ci.name);
-sys_var_character_set_database	sys_character_set_database("character_set_database");
-sys_var_character_set_client  sys_character_set_client("character_set_client");
-sys_var_character_set_connection  sys_character_set_connection("character_set_connection");
-sys_var_character_set_results sys_character_set_results("character_set_results");
-sys_var_character_set_filesystem  sys_character_set_filesystem("character_set_filesystem");
-sys_var_thd_ulong	sys_completion_type("completion_type",
+sys_var_character_set_database	sys_character_set_database(vars, "character_set_database");
+sys_var_character_set_client  sys_character_set_client(vars, "character_set_client");
+sys_var_character_set_connection  sys_character_set_connection(vars, "character_set_connection");
+sys_var_character_set_results sys_character_set_results(vars, "character_set_results");
+sys_var_character_set_filesystem  sys_character_set_filesystem(vars, "character_set_filesystem");
+sys_var_thd_ulong	sys_completion_type(vars, "completion_type",
 					 &SV::completion_type,
 					 check_completion_type,
 					 fix_completion_type);
-sys_var_collation_connection sys_collation_connection("collation_connection");
-sys_var_collation_database sys_collation_database("collation_database");
-sys_var_collation_server sys_collation_server("collation_server");
-sys_var_long_ptr	sys_concurrent_insert("concurrent_insert",
+sys_var_collation_connection sys_collation_connection(vars, "collation_connection");
+sys_var_collation_database sys_collation_database(vars, "collation_database");
+sys_var_collation_server sys_collation_server(vars, "collation_server");
+sys_var_long_ptr	sys_concurrent_insert(vars, "concurrent_insert",
                                               &myisam_concurrent_insert);
-sys_var_long_ptr	sys_connect_timeout("connect_timeout",
+sys_var_long_ptr	sys_connect_timeout(vars, "connect_timeout",
 					    &connect_timeout);
-sys_var_const_str       sys_datadir("datadir", mysql_real_data_home);
+sys_var_const_str       sys_datadir(vars, "datadir", mysql_real_data_home);
 #ifndef DBUG_OFF
-sys_var_thd_dbug        sys_dbug("debug");
+sys_var_thd_dbug        sys_dbug(vars, "debug");
 #endif
-sys_var_enum		sys_delay_key_write("delay_key_write",
+sys_var_enum		sys_delay_key_write(vars, "delay_key_write",
 					    &delay_key_write_options,
 					    &delay_key_write_typelib,
 					    fix_delay_key_write);
-sys_var_long_ptr	sys_delayed_insert_limit("delayed_insert_limit",
+sys_var_long_ptr	sys_delayed_insert_limit(vars, "delayed_insert_limit",
 						 &delayed_insert_limit);
-sys_var_long_ptr	sys_delayed_insert_timeout("delayed_insert_timeout",
+sys_var_long_ptr	sys_delayed_insert_timeout(vars, "delayed_insert_timeout",
 						   &delayed_insert_timeout);
-sys_var_long_ptr	sys_delayed_queue_size("delayed_queue_size",
+sys_var_long_ptr	sys_delayed_queue_size(vars, "delayed_queue_size",
 					       &delayed_queue_size);
 
-sys_var_event_scheduler sys_event_scheduler("event_scheduler");
-sys_var_long_ptr	sys_expire_logs_days("expire_logs_days",
+sys_var_event_scheduler sys_event_scheduler(vars, "event_scheduler");
+sys_var_long_ptr	sys_expire_logs_days(vars, "expire_logs_days",
 					     &expire_logs_days);
-sys_var_bool_ptr	sys_flush("flush", &myisam_flush);
-sys_var_long_ptr	sys_flush_time("flush_time", &flush_time);
-sys_var_str             sys_ft_boolean_syntax("ft_boolean_syntax",
+sys_var_bool_ptr	sys_flush(vars, "flush", &myisam_flush);
+sys_var_long_ptr	sys_flush_time(vars, "flush_time", &flush_time);
+sys_var_str             sys_ft_boolean_syntax(vars, "ft_boolean_syntax",
                                          sys_check_ftb_syntax,
                                          sys_update_ftb_syntax,
                                          sys_default_ftb_syntax,
                                          ft_boolean_syntax);
-sys_var_str             sys_init_connect("init_connect", 0,
+sys_var_str             sys_init_connect(vars, "init_connect", 0,
                                          sys_update_init_connect,
                                          sys_default_init_connect,0);
-sys_var_str             sys_init_slave("init_slave", 0,
+sys_var_str             sys_init_slave(vars, "init_slave", 0,
                                        sys_update_init_slave,
                                        sys_default_init_slave,0);
-sys_var_thd_ulong	sys_interactive_timeout("interactive_timeout",
+sys_var_thd_ulong	sys_interactive_timeout(vars, "interactive_timeout",
 						&SV::net_interactive_timeout);
-sys_var_thd_ulong	sys_join_buffer_size("join_buffer_size",
+sys_var_thd_ulong	sys_join_buffer_size(vars, "join_buffer_size",
 					     &SV::join_buff_size);
-sys_var_key_buffer_size	sys_key_buffer_size("key_buffer_size");
-sys_var_key_cache_long  sys_key_cache_block_size("key_cache_block_size",
+sys_var_key_buffer_size	sys_key_buffer_size(vars, "key_buffer_size");
+sys_var_key_cache_long  sys_key_cache_block_size(vars, "key_cache_block_size",
 						 offsetof(KEY_CACHE,
 							  param_block_size));
-sys_var_key_cache_long	sys_key_cache_division_limit("key_cache_division_limit",
+sys_var_key_cache_long	sys_key_cache_division_limit(vars, "key_cache_division_limit",
 						     offsetof(KEY_CACHE,
 							      param_division_limit));
-sys_var_key_cache_long  sys_key_cache_age_threshold("key_cache_age_threshold",
+sys_var_key_cache_long  sys_key_cache_age_threshold(vars, "key_cache_age_threshold",
 						     offsetof(KEY_CACHE,
 							      param_age_threshold));
-sys_var_bool_ptr	sys_local_infile("local_infile",
+sys_var_bool_ptr	sys_local_infile(vars, "local_infile",
 					 &opt_local_infile);
 sys_var_trust_routine_creators
-sys_trust_routine_creators("log_bin_trust_routine_creators",
+sys_trust_routine_creators(vars, "log_bin_trust_routine_creators",
                            &trust_function_creators);
 sys_var_bool_ptr       
-sys_trust_function_creators("log_bin_trust_function_creators",
+sys_trust_function_creators(vars, "log_bin_trust_function_creators",
                             &trust_function_creators);
 sys_var_bool_ptr
-  sys_log_queries_not_using_indexes("log_queries_not_using_indexes",
+  sys_log_queries_not_using_indexes(vars, "log_queries_not_using_indexes",
                                     &opt_log_queries_not_using_indexes);
-sys_var_thd_ulong	sys_log_warnings("log_warnings", &SV::log_warnings);
-sys_var_thd_ulong	sys_long_query_time("long_query_time",
+sys_var_thd_ulong	sys_log_warnings(vars, "log_warnings", &SV::log_warnings);
+sys_var_thd_ulong	sys_long_query_time(vars, "long_query_time",
 					     &SV::long_query_time);
-sys_var_thd_bool	sys_low_priority_updates("low_priority_updates",
+sys_var_thd_bool	sys_low_priority_updates(vars, "low_priority_updates",
 						 &SV::low_priority_updates,
 						 fix_low_priority_updates);
 #ifndef TO_BE_DELETED	/* Alias for the low_priority_updates */
-sys_var_thd_bool	sys_sql_low_priority_updates("sql_low_priority_updates",
+sys_var_thd_bool	sys_sql_low_priority_updates(vars, "sql_low_priority_updates",
 						     &SV::low_priority_updates,
 						     fix_low_priority_updates);
 #endif
-sys_var_thd_ulong	sys_max_allowed_packet("max_allowed_packet",
+sys_var_thd_ulong	sys_max_allowed_packet(vars, "max_allowed_packet",
 					       &SV::max_allowed_packet);
-sys_var_long_ptr	sys_max_binlog_cache_size("max_binlog_cache_size",
+sys_var_long_ptr	sys_max_binlog_cache_size(vars, "max_binlog_cache_size",
 						  &max_binlog_cache_size);
-sys_var_long_ptr	sys_max_binlog_size("max_binlog_size",
+sys_var_long_ptr	sys_max_binlog_size(vars, "max_binlog_size",
 					    &max_binlog_size,
                                             fix_max_binlog_size);
-sys_var_long_ptr	sys_max_connections("max_connections",
+sys_var_long_ptr	sys_max_connections(vars, "max_connections",
 					    &max_connections,
                                             fix_max_connections);
-sys_var_long_ptr	sys_max_connect_errors("max_connect_errors",
+sys_var_long_ptr	sys_max_connect_errors(vars, "max_connect_errors",
 					       &max_connect_errors);
-sys_var_thd_ulong       sys_max_insert_delayed_threads("max_insert_delayed_threads",
+sys_var_thd_ulong       sys_max_insert_delayed_threads(vars, "max_insert_delayed_threads",
 						       &SV::max_insert_delayed_threads,
                                                        check_max_delayed_threads,
                                                        fix_max_connections);
-sys_var_thd_ulong	sys_max_delayed_threads("max_delayed_threads",
+sys_var_thd_ulong	sys_max_delayed_threads(vars, "max_delayed_threads",
 						&SV::max_insert_delayed_threads,
                                                 check_max_delayed_threads,
                                                 fix_max_connections);
-sys_var_thd_ulong	sys_max_error_count("max_error_count",
+sys_var_thd_ulong	sys_max_error_count(vars, "max_error_count",
 					    &SV::max_error_count);
-sys_var_thd_ulonglong	sys_max_heap_table_size("max_heap_table_size",
+sys_var_thd_ulonglong	sys_max_heap_table_size(vars, "max_heap_table_size",
 						&SV::max_heap_table_size);
-sys_var_thd_ulong       sys_pseudo_thread_id("pseudo_thread_id",
+sys_var_thd_ulong       sys_pseudo_thread_id(vars, "pseudo_thread_id",
 					     &SV::pseudo_thread_id,
                                              check_pseudo_thread_id, 0);
-sys_var_thd_ha_rows	sys_max_join_size("max_join_size",
+sys_var_thd_ha_rows	sys_max_join_size(vars, "max_join_size",
 					  &SV::max_join_size,
 					  fix_max_join_size);
-sys_var_thd_ulong	sys_max_seeks_for_key("max_seeks_for_key",
+sys_var_thd_ulong	sys_max_seeks_for_key(vars, "max_seeks_for_key",
 					      &SV::max_seeks_for_key);
-sys_var_thd_ulong   sys_max_length_for_sort_data("max_length_for_sort_data",
+sys_var_thd_ulong   sys_max_length_for_sort_data(vars, "max_length_for_sort_data",
                                                  &SV::max_length_for_sort_data);
 #ifndef TO_BE_DELETED	/* Alias for max_join_size */
-sys_var_thd_ha_rows	sys_sql_max_join_size("sql_max_join_size",
+sys_var_thd_ha_rows	sys_sql_max_join_size(vars, "sql_max_join_size",
 					      &SV::max_join_size,
 					      fix_max_join_size);
 #endif
 static sys_var_long_ptr_global
-sys_max_prepared_stmt_count("max_prepared_stmt_count",
+sys_max_prepared_stmt_count(vars, "max_prepared_stmt_count",
                             &max_prepared_stmt_count,
                             &LOCK_prepared_stmt_count);
-sys_var_long_ptr	sys_max_relay_log_size("max_relay_log_size",
+sys_var_long_ptr	sys_max_relay_log_size(vars, "max_relay_log_size",
                                                &max_relay_log_size,
                                                fix_max_relay_log_size);
-sys_var_thd_ulong	sys_max_sort_length("max_sort_length",
+sys_var_thd_ulong	sys_max_sort_length(vars, "max_sort_length",
 					    &SV::max_sort_length);
-sys_var_thd_ulong	sys_max_sp_recursion_depth("max_sp_recursion_depth",
+sys_var_thd_ulong	sys_max_sp_recursion_depth(vars, "max_sp_recursion_depth",
                                                    &SV::max_sp_recursion_depth);
-sys_var_max_user_conn   sys_max_user_connections("max_user_connections");
-sys_var_thd_ulong	sys_max_tmp_tables("max_tmp_tables",
+sys_var_max_user_conn   sys_max_user_connections(vars, "max_user_connections");
+sys_var_thd_ulong	sys_max_tmp_tables(vars, "max_tmp_tables",
 					   &SV::max_tmp_tables);
-sys_var_long_ptr	sys_max_write_lock_count("max_write_lock_count",
+sys_var_long_ptr	sys_max_write_lock_count(vars, "max_write_lock_count",
 						 &max_write_lock_count);
-sys_var_thd_ulong       sys_multi_range_count("multi_range_count",
+sys_var_thd_ulong       sys_multi_range_count(vars, "multi_range_count",
                                               &SV::multi_range_count);
-sys_var_long_ptr	sys_myisam_data_pointer_size("myisam_data_pointer_size",
+sys_var_long_ptr	sys_myisam_data_pointer_size(vars, "myisam_data_pointer_size",
                                                     &myisam_data_pointer_size);
-sys_var_thd_ulonglong	sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
-sys_var_thd_ulong       sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
-sys_var_thd_ulong	sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
-sys_var_bool_ptr	sys_myisam_use_mmap("myisam_use_mmap", 
+sys_var_thd_ulonglong	sys_myisam_max_sort_file_size(vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
+sys_var_thd_ulong       sys_myisam_repair_threads(vars, "myisam_repair_threads", &SV::myisam_repair_threads);
+sys_var_thd_ulong	sys_myisam_sort_buffer_size(vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+sys_var_bool_ptr	sys_myisam_use_mmap(vars, "myisam_use_mmap", 
                                             &opt_myisam_use_mmap);
 
-sys_var_thd_enum        sys_myisam_stats_method("myisam_stats_method",
+sys_var_thd_enum        sys_myisam_stats_method(vars, "myisam_stats_method",
                                                 &SV::myisam_stats_method,
                                                 &myisam_stats_method_typelib,
                                                 NULL);
 
-sys_var_thd_ulong	sys_net_buffer_length("net_buffer_length",
+sys_var_thd_ulong	sys_net_buffer_length(vars, "net_buffer_length",
 					      &SV::net_buffer_length);
-sys_var_thd_ulong	sys_net_read_timeout("net_read_timeout",
+sys_var_thd_ulong	sys_net_read_timeout(vars, "net_read_timeout",
 					     &SV::net_read_timeout,
 					     0, fix_net_read_timeout);
-sys_var_thd_ulong	sys_net_write_timeout("net_write_timeout",
+sys_var_thd_ulong	sys_net_write_timeout(vars, "net_write_timeout",
 					      &SV::net_write_timeout,
 					      0, fix_net_write_timeout);
-sys_var_thd_ulong	sys_net_retry_count("net_retry_count",
+sys_var_thd_ulong	sys_net_retry_count(vars, "net_retry_count",
 					    &SV::net_retry_count,
 					    0, fix_net_retry_count);
-sys_var_thd_bool	sys_new_mode("new", &SV::new_mode);
-sys_var_thd_bool	sys_old_alter_table("old_alter_table",
+sys_var_thd_bool	sys_new_mode(vars, "new", &SV::new_mode);
+sys_var_thd_bool	sys_old_alter_table(vars, "old_alter_table",
 					    &SV::old_alter_table);
-sys_var_thd_bool	sys_old_passwords("old_passwords", &SV::old_passwords);
-sys_var_thd_ulong       sys_optimizer_prune_level("optimizer_prune_level",
+sys_var_thd_bool	sys_old_passwords(vars, "old_passwords", &SV::old_passwords);
+sys_var_thd_ulong       sys_optimizer_prune_level(vars, "optimizer_prune_level",
                                                   &SV::optimizer_prune_level);
-sys_var_thd_ulong       sys_optimizer_search_depth("optimizer_search_depth",
+sys_var_thd_ulong       sys_optimizer_search_depth(vars, "optimizer_search_depth",
                                                    &SV::optimizer_search_depth);
-sys_var_thd_ulong       sys_preload_buff_size("preload_buffer_size",
+sys_var_thd_ulong       sys_preload_buff_size(vars, "preload_buffer_size",
                                               &SV::preload_buff_size);
-sys_var_thd_ulong	sys_read_buff_size("read_buffer_size",
+sys_var_thd_ulong	sys_read_buff_size(vars, "read_buffer_size",
 					   &SV::read_buff_size);
-sys_var_bool_ptr	sys_readonly("read_only", &opt_readonly);
-sys_var_thd_ulong	sys_read_rnd_buff_size("read_rnd_buffer_size",
+sys_var_bool_ptr	sys_readonly(vars, "read_only", &opt_readonly);
+sys_var_thd_ulong	sys_read_rnd_buff_size(vars, "read_rnd_buffer_size",
 					       &SV::read_rnd_buff_size);
-sys_var_thd_ulong	sys_div_precincrement("div_precision_increment",
+sys_var_thd_ulong	sys_div_precincrement(vars, "div_precision_increment",
                                               &SV::div_precincrement);
 #ifdef HAVE_REPLICATION
-sys_var_bool_ptr	sys_relay_log_purge("relay_log_purge",
+sys_var_bool_ptr	sys_relay_log_purge(vars, "relay_log_purge",
                                             &relay_log_purge);
 #endif
-sys_var_long_ptr	sys_rpl_recovery_rank("rpl_recovery_rank",
+sys_var_long_ptr	sys_rpl_recovery_rank(vars, "rpl_recovery_rank",
 					      &rpl_recovery_rank);
-sys_var_long_ptr	sys_query_cache_size("query_cache_size",
+sys_var_long_ptr	sys_query_cache_size(vars, "query_cache_size",
 					     &query_cache_size,
 					     fix_query_cache_size);
 
-sys_var_thd_ulong	sys_range_alloc_block_size("range_alloc_block_size",
+sys_var_thd_ulong	sys_range_alloc_block_size(vars, "range_alloc_block_size",
 						   &SV::range_alloc_block_size);
-sys_var_thd_ulong	sys_query_alloc_block_size("query_alloc_block_size",
+sys_var_thd_ulong	sys_query_alloc_block_size(vars, "query_alloc_block_size",
 						   &SV::query_alloc_block_size,
 						   0, fix_thd_mem_root);
-sys_var_thd_ulong	sys_query_prealloc_size("query_prealloc_size",
+sys_var_thd_ulong	sys_query_prealloc_size(vars, "query_prealloc_size",
 						&SV::query_prealloc_size,
 						0, fix_thd_mem_root);
-sys_var_readonly        sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
-sys_var_thd_ulong	sys_trans_alloc_block_size("transaction_alloc_block_size",
+sys_var_readonly        sys_tmpdir(vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
+sys_var_thd_ulong	sys_trans_alloc_block_size(vars, "transaction_alloc_block_size",
 						   &SV::trans_alloc_block_size,
 						   0, fix_trans_mem_root);
-sys_var_thd_ulong	sys_trans_prealloc_size("transaction_prealloc_size",
+sys_var_thd_ulong	sys_trans_prealloc_size(vars, "transaction_prealloc_size",
 						&SV::trans_prealloc_size,
 						0, fix_trans_mem_root);
 
 #ifdef HAVE_QUERY_CACHE
-sys_var_long_ptr	sys_query_cache_limit("query_cache_limit",
+sys_var_long_ptr	sys_query_cache_limit(vars, "query_cache_limit",
 					      &query_cache.query_cache_limit);
-sys_var_long_ptr        sys_query_cache_min_res_unit("query_cache_min_res_unit",
+sys_var_long_ptr        sys_query_cache_min_res_unit(vars, "query_cache_min_res_unit",
 						     &query_cache_min_res_unit,
 						     fix_query_cache_min_res_unit);
-sys_var_thd_enum	sys_query_cache_type("query_cache_type",
+sys_var_thd_enum	sys_query_cache_type(vars, "query_cache_type",
 					     &SV::query_cache_type,
 					     &query_cache_type_typelib);
 sys_var_thd_bool
-sys_query_cache_wlock_invalidate("query_cache_wlock_invalidate",
+sys_query_cache_wlock_invalidate(vars, "query_cache_wlock_invalidate",
 				 &SV::query_cache_wlock_invalidate);
 #endif /* HAVE_QUERY_CACHE */
-sys_var_bool_ptr	sys_secure_auth("secure_auth", &opt_secure_auth);
-sys_var_long_ptr	sys_server_id("server_id", &server_id, fix_server_id);
-sys_var_bool_ptr	sys_slave_compressed_protocol("slave_compressed_protocol",
+sys_var_bool_ptr	sys_secure_auth(vars, "secure_auth", &opt_secure_auth);
+sys_var_long_ptr	sys_server_id(vars, "server_id", &server_id, fix_server_id);
+sys_var_bool_ptr	sys_slave_compressed_protocol(vars, "slave_compressed_protocol",
 						      &opt_slave_compressed_protocol);
 #ifdef HAVE_REPLICATION
-sys_var_long_ptr	sys_slave_net_timeout("slave_net_timeout",
+sys_var_long_ptr	sys_slave_net_timeout(vars, "slave_net_timeout",
 					      &slave_net_timeout);
-sys_var_long_ptr	sys_slave_trans_retries("slave_transaction_retries",
+sys_var_long_ptr	sys_slave_trans_retries(vars, "slave_transaction_retries",
                                                 &slave_trans_retries);
 #endif
-sys_var_long_ptr	sys_slow_launch_time("slow_launch_time",
+sys_var_long_ptr	sys_slow_launch_time(vars, "slow_launch_time",
 					     &slow_launch_time);
-sys_var_thd_ulong	sys_sort_buffer("sort_buffer_size",
+sys_var_thd_ulong	sys_sort_buffer(vars, "sort_buffer_size",
 					&SV::sortbuff_size);
-sys_var_thd_sql_mode    sys_sql_mode("sql_mode",
+sys_var_thd_sql_mode    sys_sql_mode(vars, "sql_mode",
                                      &SV::sql_mode);
 #ifdef HAVE_OPENSSL
 extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
             *opt_ssl_key;
-sys_var_const_str_ptr	sys_ssl_ca("ssl_ca", &opt_ssl_ca);
-sys_var_const_str_ptr	sys_ssl_capath("ssl_capath", &opt_ssl_capath);
-sys_var_const_str_ptr	sys_ssl_cert("ssl_cert", &opt_ssl_cert);
-sys_var_const_str_ptr	sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher);
-sys_var_const_str_ptr	sys_ssl_key("ssl_key", &opt_ssl_key);
+sys_var_const_str_ptr	sys_ssl_ca(vars, "ssl_ca", &opt_ssl_ca);
+sys_var_const_str_ptr	sys_ssl_capath(vars, "ssl_capath", &opt_ssl_capath);
+sys_var_const_str_ptr	sys_ssl_cert(vars, "ssl_cert", &opt_ssl_cert);
+sys_var_const_str_ptr	sys_ssl_cipher(vars, "ssl_cipher", &opt_ssl_cipher);
+sys_var_const_str_ptr	sys_ssl_key(vars, "ssl_key", &opt_ssl_key);
 #else
-sys_var_const_str	sys_ssl_ca("ssl_ca", NULL);
-sys_var_const_str	sys_ssl_capath("ssl_capath", NULL);
-sys_var_const_str	sys_ssl_cert("ssl_cert", NULL);
-sys_var_const_str	sys_ssl_cipher("ssl_cipher", NULL);
-sys_var_const_str	sys_ssl_key("ssl_key", NULL);
+sys_var_const_str	sys_ssl_ca(vars, "ssl_ca", NULL);
+sys_var_const_str	sys_ssl_capath(vars, "ssl_capath", NULL);
+sys_var_const_str	sys_ssl_cert(vars, "ssl_cert", NULL);
+sys_var_const_str	sys_ssl_cipher(vars, "ssl_cipher", NULL);
+sys_var_const_str	sys_ssl_key(vars, "ssl_key", NULL);
 #endif
 sys_var_thd_enum
-sys_updatable_views_with_limit("updatable_views_with_limit",
+sys_updatable_views_with_limit(vars, "updatable_views_with_limit",
                                &SV::updatable_views_with_limit,
                                &updatable_views_with_limit_typelib);
 
-sys_var_thd_table_type  sys_table_type("table_type",
+sys_var_thd_table_type  sys_table_type(vars, "table_type",
 				       &SV::table_type);
-sys_var_thd_storage_engine sys_storage_engine("storage_engine",
+sys_var_thd_storage_engine sys_storage_engine(vars, "storage_engine",
 				       &SV::table_type);
 #ifdef HAVE_REPLICATION
-sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period);
+sys_var_sync_binlog_period sys_sync_binlog_period(vars, "sync_binlog", &sync_binlog_period);
 #endif
-sys_var_bool_ptr	sys_sync_frm("sync_frm", &opt_sync_frm);
-sys_var_const_str	sys_system_time_zone("system_time_zone",
+sys_var_bool_ptr	sys_sync_frm(vars, "sync_frm", &opt_sync_frm);
+sys_var_const_str	sys_system_time_zone(vars, "system_time_zone",
                                              system_time_zone);
-sys_var_long_ptr	sys_table_def_size("table_definition_cache",
+sys_var_long_ptr	sys_table_def_size(vars, "table_definition_cache",
                                            &table_def_size);
-sys_var_long_ptr	sys_table_cache_size("table_open_cache",
+sys_var_long_ptr	sys_table_cache_size(vars, "table_open_cache",
 					     &table_cache_size);
-sys_var_long_ptr	sys_table_lock_wait_timeout("table_lock_wait_timeout",
+sys_var_long_ptr	sys_table_lock_wait_timeout(vars, "table_lock_wait_timeout",
                                                     &table_lock_wait_timeout);
-sys_var_long_ptr	sys_thread_cache_size("thread_cache_size",
+sys_var_long_ptr	sys_thread_cache_size(vars, "thread_cache_size",
 					      &thread_cache_size);
-sys_var_thd_enum	sys_tx_isolation("tx_isolation",
+sys_var_thd_enum	sys_tx_isolation(vars, "tx_isolation",
 					 &SV::tx_isolation,
 					 &tx_isolation_typelib,
 					 fix_tx_isolation,
 					 check_tx_isolation);
-sys_var_thd_ulonglong	sys_tmp_table_size("tmp_table_size",
+sys_var_thd_ulonglong	sys_tmp_table_size(vars, "tmp_table_size",
 					   &SV::tmp_table_size);
-sys_var_bool_ptr  sys_timed_mutexes("timed_mutexes",
+sys_var_bool_ptr  sys_timed_mutexes(vars, "timed_mutexes",
                                     &timed_mutexes);
-sys_var_const_str	sys_version("version", server_version);
-sys_var_const_str	sys_version_comment("version_comment",
+sys_var_const_str	sys_version(vars, "version", server_version);
+sys_var_const_str	sys_version_comment(vars, "version_comment",
                                             MYSQL_COMPILATION_COMMENT);
-sys_var_const_str	sys_version_compile_machine("version_compile_machine",
+sys_var_const_str	sys_version_compile_machine(vars, "version_compile_machine",
                                                     MACHINE_TYPE);
-sys_var_const_str	sys_version_compile_os("version_compile_os",
+sys_var_const_str	sys_version_compile_os(vars, "version_compile_os",
                                                SYSTEM_TYPE);
-sys_var_thd_ulong	sys_net_wait_timeout("wait_timeout",
+sys_var_thd_ulong	sys_net_wait_timeout(vars, "wait_timeout",
 					     &SV::net_wait_timeout);
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-sys_var_long_ptr	sys_innodb_fast_shutdown("innodb_fast_shutdown",
-						 &innobase_fast_shutdown);
-sys_var_long_ptr        sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct",
-                                                        &srv_max_buf_pool_modified_pct);
-sys_var_long_ptr	sys_innodb_max_purge_lag("innodb_max_purge_lag",
-							&srv_max_purge_lag);
-sys_var_thd_bool	sys_innodb_table_locks("innodb_table_locks",
-                                               &SV::innodb_table_locks);
-sys_var_thd_bool	sys_innodb_support_xa("innodb_support_xa",
-                                               &SV::innodb_support_xa);
-sys_var_long_ptr	sys_innodb_autoextend_increment("innodb_autoextend_increment",
-							&srv_auto_extend_increment);
-sys_var_long_ptr	sys_innodb_sync_spin_loops("innodb_sync_spin_loops",
-                                             &srv_n_spin_wait_rounds);
-sys_var_long_ptr  sys_innodb_concurrency_tickets("innodb_concurrency_tickets",
-                                             &srv_n_free_tickets_to_enter);
-sys_var_long_ptr  sys_innodb_thread_sleep_delay("innodb_thread_sleep_delay",
-                                                &srv_thread_sleep_delay);
-sys_var_long_ptr  sys_innodb_thread_concurrency("innodb_thread_concurrency",
-                                                &srv_thread_concurrency);
-sys_var_long_ptr  sys_innodb_commit_concurrency("innodb_commit_concurrency",
-                                                &srv_commit_concurrency);
-sys_var_long_ptr  sys_innodb_flush_log_at_trx_commit(
-                                        "innodb_flush_log_at_trx_commit",
-                                        &srv_flush_log_at_trx_commit);
-#endif
+
 /* Condition pushdown to storage engine */
 sys_var_thd_bool
-sys_engine_condition_pushdown("engine_condition_pushdown",
+sys_engine_condition_pushdown(vars, "engine_condition_pushdown",
 			      &SV::engine_condition_pushdown);
 
 /* ndb thread specific variable settings */
 sys_var_thd_ulong
-sys_ndb_autoincrement_prefetch_sz("ndb_autoincrement_prefetch_sz",
+sys_ndb_autoincrement_prefetch_sz(vars, "ndb_autoincrement_prefetch_sz",
 				  &SV::ndb_autoincrement_prefetch_sz);
 sys_var_thd_bool
-sys_ndb_force_send("ndb_force_send", &SV::ndb_force_send);
+sys_ndb_force_send(vars, "ndb_force_send", &SV::ndb_force_send);
 #ifdef HAVE_NDB_BINLOG
 sys_var_long_ptr
-sys_ndb_report_thresh_binlog_epoch_slip("ndb_report_thresh_binlog_epoch_slip",
+sys_ndb_report_thresh_binlog_epoch_slip(vars, "ndb_report_thresh_binlog_epoch_slip",
                                         &ndb_report_thresh_binlog_epoch_slip);
 sys_var_long_ptr
-sys_ndb_report_thresh_binlog_mem_usage("ndb_report_thresh_binlog_mem_usage",
+sys_ndb_report_thresh_binlog_mem_usage(vars, "ndb_report_thresh_binlog_mem_usage",
                                        &ndb_report_thresh_binlog_mem_usage);
 #endif
 sys_var_thd_bool
-sys_ndb_use_exact_count("ndb_use_exact_count", &SV::ndb_use_exact_count);
+sys_ndb_use_exact_count(vars, "ndb_use_exact_count", &SV::ndb_use_exact_count);
 sys_var_thd_bool
-sys_ndb_use_transactions("ndb_use_transactions", &SV::ndb_use_transactions);
+sys_ndb_use_transactions(vars, "ndb_use_transactions", &SV::ndb_use_transactions);
 sys_var_long_ptr
-sys_ndb_cache_check_time("ndb_cache_check_time", &ndb_cache_check_time);
+sys_ndb_cache_check_time(vars, "ndb_cache_check_time", &ndb_cache_check_time);
 sys_var_thd_bool
-sys_ndb_index_stat_enable("ndb_index_stat_enable",
+sys_ndb_index_stat_enable(vars, "ndb_index_stat_enable",
                           &SV::ndb_index_stat_enable);
 sys_var_thd_ulong
-sys_ndb_index_stat_cache_entries("ndb_index_stat_cache_entries",
+sys_ndb_index_stat_cache_entries(vars, "ndb_index_stat_cache_entries",
                                  &SV::ndb_index_stat_cache_entries);
 sys_var_thd_ulong
-sys_ndb_index_stat_update_freq("ndb_index_stat_update_freq",
+sys_ndb_index_stat_update_freq(vars, "ndb_index_stat_update_freq",
                                &SV::ndb_index_stat_update_freq);
 sys_var_long_ptr
-sys_ndb_extra_logging("ndb_extra_logging", &ndb_extra_logging);
+sys_ndb_extra_logging(vars, "ndb_extra_logging", &ndb_extra_logging);
 sys_var_thd_bool
-sys_ndb_use_copying_alter_table("ndb_use_copying_alter_table", &SV::ndb_use_copying_alter_table);
+sys_ndb_use_copying_alter_table(vars, "ndb_use_copying_alter_table", &SV::ndb_use_copying_alter_table);
 
 /* Time/date/datetime formats */
 
-sys_var_thd_date_time_format sys_time_format("time_format",
+sys_var_thd_date_time_format sys_time_format(vars, "time_format",
 					     &SV::time_format,
 					     MYSQL_TIMESTAMP_TIME);
-sys_var_thd_date_time_format sys_date_format("date_format",
+sys_var_thd_date_time_format sys_date_format(vars, "date_format",
 					     &SV::date_format,
 					     MYSQL_TIMESTAMP_DATE);
-sys_var_thd_date_time_format sys_datetime_format("datetime_format",
+sys_var_thd_date_time_format sys_datetime_format(vars, "datetime_format",
 						 &SV::datetime_format,
 						 MYSQL_TIMESTAMP_DATETIME);
 
 /* Variables that are bits in THD */
 
-sys_var_thd_bit sys_autocommit("autocommit", 0,
+sys_var_thd_bit sys_autocommit(vars, "autocommit", 0,
                                set_option_autocommit,
                                OPTION_NOT_AUTOCOMMIT,
                                1);
-static sys_var_thd_bit	sys_big_tables("big_tables", 0,
+static sys_var_thd_bit	sys_big_tables(vars, "big_tables", 0,
 				       set_option_bit,
 				       OPTION_BIG_TABLES);
 #ifndef TO_BE_DELETED	/* Alias for big_tables */
-static sys_var_thd_bit	sys_sql_big_tables("sql_big_tables", 0,
+static sys_var_thd_bit	sys_sql_big_tables(vars, "sql_big_tables", 0,
 					   set_option_bit,
 					   OPTION_BIG_TABLES);
 #endif
-static sys_var_thd_bit	sys_big_selects("sql_big_selects", 0,
+static sys_var_thd_bit	sys_big_selects(vars, "sql_big_selects", 0,
 					set_option_bit,
 					OPTION_BIG_SELECTS);
-static sys_var_thd_bit	sys_log_off("sql_log_off",
+static sys_var_thd_bit	sys_log_off(vars, "sql_log_off",
 				    check_log_update,
 				    set_option_bit,
 				    OPTION_LOG_OFF);
-static sys_var_thd_bit	sys_log_update("sql_log_update",
+static sys_var_thd_bit	sys_log_update(vars, "sql_log_update",
                                        check_log_update,
 				       set_log_update,
 				       OPTION_BIN_LOG);
-static sys_var_thd_bit	sys_log_binlog("sql_log_bin",
+static sys_var_thd_bit	sys_log_binlog(vars, "sql_log_bin",
                                        check_log_update,
 				       set_option_bit,
 				       OPTION_BIN_LOG);
-static sys_var_thd_bit	sys_sql_warnings("sql_warnings", 0,
+static sys_var_thd_bit	sys_sql_warnings(vars, "sql_warnings", 0,
 					 set_option_bit,
 					 OPTION_WARNINGS);
-static sys_var_thd_bit	sys_sql_notes("sql_notes", 0,
+static sys_var_thd_bit	sys_sql_notes(vars, "sql_notes", 0,
 					 set_option_bit,
 					 OPTION_SQL_NOTES);
-static sys_var_thd_bit	sys_auto_is_null("sql_auto_is_null", 0,
+static sys_var_thd_bit	sys_auto_is_null(vars, "sql_auto_is_null", 0,
 					 set_option_bit,
 					 OPTION_AUTO_IS_NULL);
-static sys_var_thd_bit	sys_safe_updates("sql_safe_updates", 0,
+static sys_var_thd_bit	sys_safe_updates(vars, "sql_safe_updates", 0,
 					 set_option_bit,
 					 OPTION_SAFE_UPDATES);
-static sys_var_thd_bit	sys_buffer_results("sql_buffer_result", 0,
+static sys_var_thd_bit	sys_buffer_results(vars, "sql_buffer_result", 0,
 					   set_option_bit,
 					   OPTION_BUFFER_RESULT);
-static sys_var_thd_bit	sys_quote_show_create("sql_quote_show_create", 0,
+static sys_var_thd_bit	sys_quote_show_create(vars, "sql_quote_show_create", 0,
 					      set_option_bit,
 					      OPTION_QUOTE_SHOW_CREATE);
-static sys_var_thd_bit	sys_foreign_key_checks("foreign_key_checks", 0,
+static sys_var_thd_bit	sys_foreign_key_checks(vars, "foreign_key_checks", 0,
 					       set_option_bit,
 					       OPTION_NO_FOREIGN_KEY_CHECKS,
 					       1);
-static sys_var_thd_bit	sys_unique_checks("unique_checks", 0,
+static sys_var_thd_bit	sys_unique_checks(vars, "unique_checks", 0,
 					  set_option_bit,
 					  OPTION_RELAXED_UNIQUE_CHECKS,
 					  1);
 
 /* Local state variables */
 
-static sys_var_thd_ha_rows	sys_select_limit("sql_select_limit",
+static sys_var_thd_ha_rows	sys_select_limit(vars, "sql_select_limit",
 						 &SV::select_limit);
-static sys_var_timestamp	sys_timestamp("timestamp");
-static sys_var_last_insert_id	sys_last_insert_id("last_insert_id");
-static sys_var_last_insert_id	sys_identity("identity");
+static sys_var_timestamp	sys_timestamp(vars, "timestamp");
+static sys_var_last_insert_id	sys_last_insert_id(vars, "last_insert_id");
+static sys_var_last_insert_id	sys_identity(vars, "identity");
 
-static sys_var_thd_lc_time_names       sys_lc_time_names("lc_time_names");
+static sys_var_thd_lc_time_names       sys_lc_time_names(vars, "lc_time_names");
 
-static sys_var_insert_id	sys_insert_id("insert_id");
-static sys_var_readonly		sys_error_count("error_count",
+static sys_var_insert_id	sys_insert_id(vars, "insert_id");
+static sys_var_readonly		sys_error_count(vars, "error_count",
 						OPT_SESSION,
 						SHOW_LONG,
 						get_error_count);
-static sys_var_readonly		sys_warning_count("warning_count",
+static sys_var_readonly		sys_warning_count(vars, "warning_count",
 						  OPT_SESSION,
 						  SHOW_LONG,
 						  get_warning_count);
 
 /* alias for last_insert_id() to be compatible with Sybase */
 #ifdef HAVE_REPLICATION
-static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
+static sys_var_slave_skip_counter sys_slave_skip_counter(vars, "sql_slave_skip_counter");
 #endif
-static sys_var_rand_seed1	sys_rand_seed1("rand_seed1");
-static sys_var_rand_seed2	sys_rand_seed2("rand_seed2");
+static sys_var_rand_seed1	sys_rand_seed1(vars, "rand_seed1");
+static sys_var_rand_seed2	sys_rand_seed2(vars, "rand_seed2");
 
-static sys_var_thd_ulong        sys_default_week_format("default_week_format",
+static sys_var_thd_ulong        sys_default_week_format(vars, "default_week_format",
 					                &SV::default_week_format);
 
-sys_var_thd_ulong               sys_group_concat_max_len("group_concat_max_len",
+sys_var_thd_ulong               sys_group_concat_max_len(vars, "group_concat_max_len",
                                                          &SV::group_concat_max_len);
 
-sys_var_thd_time_zone            sys_time_zone("time_zone");
+sys_var_thd_time_zone            sys_time_zone(vars, "time_zone");
 
 /* Read only variables */
 
-sys_var_have_variable sys_have_compress("have_compress", &have_compress);
-sys_var_have_variable sys_have_crypt("have_crypt", &have_crypt);
-sys_var_have_variable sys_have_dlopen("have_dynamic_loading", &have_dlopen);
-sys_var_have_variable sys_have_geometry("have_geometry", &have_geometry);
-sys_var_have_variable sys_have_openssl("have_openssl", &have_openssl);
-sys_var_have_variable sys_have_query_cache("have_query_cache",
+sys_var_have_variable sys_have_compress(vars, "have_compress", &have_compress);
+sys_var_have_variable sys_have_crypt(vars, "have_crypt", &have_crypt);
+sys_var_have_variable sys_have_csv(vars, "have_csv", &have_csv); /* FIXME: init scripts currently need this */
+sys_var_have_variable sys_have_dlopen(vars, "have_dynamic_loading", &have_dlopen);
+sys_var_have_variable sys_have_geometry(vars, "have_geometry", &have_geometry);
+sys_var_have_variable sys_have_openssl(vars, "have_openssl", &have_openssl);
+sys_var_have_variable sys_have_query_cache(vars, "have_query_cache",
                                            &have_query_cache);
-sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys);
-sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink);
-sys_var_have_variable sys_have_row_based_replication("have_row_based_replication",&have_row_based_replication);
+sys_var_have_variable sys_have_rtree_keys(vars, "have_rtree_keys", &have_rtree_keys);
+sys_var_have_variable sys_have_symlink(vars, "have_symlink", &have_symlink);
+sys_var_have_variable sys_have_row_based_replication(vars, "have_row_based_replication",&have_row_based_replication);
 /* Global read-only variable describing server license */
-sys_var_const_str		sys_license("license", STRINGIFY_ARG(LICENSE));
+sys_var_const_str		sys_license(vars, "license", STRINGIFY_ARG(LICENSE));
 
 /* Global variables which enable|disable logging */
-sys_var_log_state sys_var_general_log("general_log", &opt_log,
+sys_var_log_state sys_var_general_log(vars, "general_log", &opt_log,
                                       QUERY_LOG_GENERAL);
-sys_var_log_state sys_var_slow_query_log("slow_query_log", &opt_slow_log,
+sys_var_log_state sys_var_slow_query_log(vars, "slow_query_log", &opt_slow_log,
                                          QUERY_LOG_SLOW);
-sys_var_str sys_var_general_log_path("general_log_file", sys_check_log_path,
+sys_var_str sys_var_general_log_path(vars, "general_log_file", sys_check_log_path,
 				     sys_update_general_log_path,
 				     sys_default_general_log_path,
 				     opt_logname);
-sys_var_str sys_var_slow_log_path("slow_query_log_file", sys_check_log_path,
+sys_var_str sys_var_slow_log_path(vars, "slow_query_log_file", sys_check_log_path,
 				  sys_update_slow_log_path, 
 				  sys_default_slow_log_path,
 				  opt_slow_logname);
-sys_var_log_output sys_var_log_output_state("log_output", &log_output_options,
+sys_var_log_output sys_var_log_output_state(vars, "log_output", &log_output_options,
 					    &log_output_typelib, 0);
 
 #ifdef HAVE_REPLICATION
@@ -725,302 +665,71 @@
 #endif /* HAVE_REPLICATION */
 
 /*
-  Variables shown by SHOW VARIABLES in alphabetical order
+  Additional variables shown by SHOW VARIABLES
+  order is unimportant as it will be sorted.
 */
 
-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},
+static SHOW_VAR fixed_vars[]= {
   {"back_log",                (char*) &back_log,                    SHOW_LONG},
-  {sys_basedir.name,          (char*) &sys_basedir,                 SHOW_SYS},
-  {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size,	    SHOW_SYS},
-  {sys_binlog_format.name,    (char*) &sys_binlog_format,	    SHOW_SYS},
-  {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
-  {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
-  {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
-  {sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS},
-  {sys_character_set_filesystem.name,(char*) &sys_character_set_filesystem, SHOW_SYS},
-  {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS},
-  {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS},
-  {sys_charset_system.name,   (char*) &sys_charset_system,          SHOW_SYS},
   {"character_sets_dir",      mysql_charsets_dir,                   SHOW_CHAR},
-  {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS},
-  {sys_collation_database.name,(char*) &sys_collation_database,     SHOW_SYS},
-  {sys_collation_server.name,(char*) &sys_collation_server,         SHOW_SYS},
-  {sys_completion_type.name,  (char*) &sys_completion_type,	    SHOW_SYS},
-  {sys_concurrent_insert.name,(char*) &sys_concurrent_insert,       SHOW_SYS},
-  {sys_connect_timeout.name,  (char*) &sys_connect_timeout,         SHOW_SYS},
-  {sys_datadir.name,          (char*) &sys_datadir,                 SHOW_SYS},
-  {sys_date_format.name,      (char*) &sys_date_format,		    SHOW_SYS},
-  {sys_datetime_format.name,  (char*) &sys_datetime_format,	    SHOW_SYS},
-#ifndef DBUG_OFF
-  {sys_dbug.name,             (char*) &sys_dbug,                    SHOW_SYS},
-#endif
-  {sys_default_week_format.name, (char*) &sys_default_week_format,  SHOW_SYS},
-  {sys_delay_key_write.name,  (char*) &sys_delay_key_write,         SHOW_SYS},
-  {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
-  {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
-  {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size,     SHOW_SYS},
-  {sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
-  {sys_engine_condition_pushdown.name,
-   (char*) &sys_engine_condition_pushdown,                          SHOW_SYS},
-  {sys_event_scheduler.name,  (char*) &sys_event_scheduler,         SHOW_SYS},
-  {sys_expire_logs_days.name, (char*) &sys_expire_logs_days,        SHOW_SYS},
-  {sys_flush.name,             (char*) &sys_flush,                  SHOW_SYS},
-  {sys_flush_time.name,        (char*) &sys_flush_time,             SHOW_SYS},
-  {sys_ft_boolean_syntax.name,(char*) &ft_boolean_syntax,	    SHOW_CHAR},
   {"ft_max_word_len",         (char*) &ft_max_word_len,             SHOW_LONG},
   {"ft_min_word_len",         (char*) &ft_min_word_len,             SHOW_LONG},
   {"ft_query_expansion_limit",(char*) &ft_query_expansion_limit,    SHOW_LONG},
   {"ft_stopword_file",        (char*) &ft_stopword_file,            SHOW_CHAR_PTR},
-  {sys_var_general_log.name, (char*) &opt_log,                      SHOW_MY_BOOL},
-  {sys_var_general_log_path.name, (char*) &sys_var_general_log_path,  SHOW_SYS},
-  {sys_group_concat_max_len.name, (char*) &sys_group_concat_max_len,  SHOW_SYS},
-  {sys_have_compress.name,    (char*) &have_compress,               SHOW_HAVE},
-  {sys_have_crypt.name,       (char*) &have_crypt,                  SHOW_HAVE},
-  {sys_have_dlopen.name,      (char*) &have_dlopen,                 SHOW_HAVE},
-  {sys_have_geometry.name,    (char*) &have_geometry,               SHOW_HAVE},
-  {sys_have_openssl.name,     (char*) &have_openssl,                SHOW_HAVE},
-  {sys_have_query_cache.name, (char*) &have_query_cache,            SHOW_HAVE},
-  {sys_have_row_based_replication.name, (char*) &have_row_based_replication, SHOW_HAVE},
-  {sys_have_rtree_keys.name,  (char*) &have_rtree_keys,             SHOW_HAVE},
-  {sys_have_symlink.name,     (char*) &have_symlink,                SHOW_HAVE},
-  {"init_connect",            (char*) &sys_init_connect,            SHOW_SYS},
   {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
-  {"init_slave",              (char*) &sys_init_slave,              SHOW_SYS},
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-  {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
-  {sys_innodb_autoextend_increment.name, (char*) &sys_innodb_autoextend_increment, SHOW_SYS},
-  {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONGLONG },
-  {"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL},
-  {sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS},
-  {sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS},
-  {"innodb_data_file_path", (char*) &innobase_data_file_path,	    SHOW_CHAR_PTR},
-  {"innodb_data_home_dir",  (char*) &innobase_data_home_dir,	    SHOW_CHAR_PTR},
-  {"innodb_doublewrite", (char*) &innobase_use_doublewrite, SHOW_MY_BOOL},
-  {sys_innodb_fast_shutdown.name,(char*) &sys_innodb_fast_shutdown, SHOW_SYS},
-  {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
-  {"innodb_file_per_table", (char*) &innobase_file_per_table, SHOW_MY_BOOL},
-  {"innodb_flush_method",    (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
-  {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
-  {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
-  {"innodb_locks_unsafe_for_binlog", (char*) &innobase_locks_unsafe_for_binlog, SHOW_MY_BOOL},
-  {"innodb_log_arch_dir",   (char*) &innobase_log_arch_dir, 	    SHOW_CHAR_PTR},
-  {"innodb_log_archive",    (char*) &innobase_log_archive, 	    SHOW_MY_BOOL},
-  {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
-  {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONGLONG},
-  {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group,	SHOW_LONG},
-  {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
-  {sys_innodb_max_dirty_pages_pct.name, (char*) &sys_innodb_max_dirty_pages_pct, SHOW_SYS},
-  {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS},
-  {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
-  {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG },
-  {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS},
-  {sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS},
-  {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
-  {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
-  {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
-  {sys_innodb_flush_log_at_trx_commit.name, (char*) &sys_innodb_flush_log_at_trx_commit, SHOW_SYS},
-#endif
-  {sys_interactive_timeout.name,(char*) &sys_interactive_timeout,   SHOW_SYS},
-  {sys_join_buffer_size.name,   (char*) &sys_join_buffer_size,	    SHOW_SYS},
-  {sys_key_buffer_size.name,	(char*) &sys_key_buffer_size,	    SHOW_SYS},
-  {sys_key_cache_age_threshold.name,   (char*) &sys_key_cache_age_threshold,
-                                                                    SHOW_SYS},
-  {sys_key_cache_block_size.name,   (char*) &sys_key_cache_block_size,
-                                                                    SHOW_SYS},
-  {sys_key_cache_division_limit.name,   (char*) &sys_key_cache_division_limit,
-                                                                    SHOW_SYS},
   {"language",                language,                             SHOW_CHAR},
   {"large_files_support",     (char*) &opt_large_files,             SHOW_BOOL},
   {"large_page_size",         (char*) &opt_large_page_size,         SHOW_INT},
   {"large_pages",             (char*) &opt_large_pages,             SHOW_MY_BOOL},
-  {sys_lc_time_names.name,    (char*) &sys_lc_time_names,           SHOW_SYS},
-  {sys_license.name,	      (char*) &sys_license,                 SHOW_SYS},
-  {sys_local_infile.name,     (char*) &sys_local_infile,	    SHOW_SYS},
 #ifdef HAVE_MLOCKALL
   {"locked_in_memory",	      (char*) &locked_in_memory,	    SHOW_BOOL},
 #endif
   {"log",                     (char*) &opt_log,                     SHOW_BOOL},
   {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
-  {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
   {"log_error",               (char*) log_error_file,               SHOW_CHAR},
-  {sys_var_log_output_state.name, (char*) &sys_var_log_output_state, SHOW_SYS},
-  {sys_log_queries_not_using_indexes.name,
-    (char*) &sys_log_queries_not_using_indexes, SHOW_SYS},
 #ifdef HAVE_REPLICATION
   {"log_slave_updates",       (char*) &opt_log_slave_updates,       SHOW_MY_BOOL},
 #endif
   {"log_slow_queries",        (char*) &opt_slow_log,                SHOW_BOOL},
-  {sys_log_warnings.name,     (char*) &sys_log_warnings,	    SHOW_SYS},
-  {sys_long_query_time.name,  (char*) &sys_long_query_time, 	    SHOW_SYS},
-  {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
   {"lower_case_file_system",  (char*) &lower_case_file_system,      SHOW_MY_BOOL},
   {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_INT},
-  {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet,	    SHOW_SYS},
-  {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
-  {sys_max_binlog_size.name,    (char*) &sys_max_binlog_size,	    SHOW_SYS},
-  {sys_max_connect_errors.name, (char*) &sys_max_connect_errors,    SHOW_SYS},
-  {sys_max_connections.name,    (char*) &sys_max_connections,	    SHOW_SYS},
-  {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads,   SHOW_SYS},
-  {sys_max_error_count.name,	(char*) &sys_max_error_count,	    SHOW_SYS},
-  {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size,   SHOW_SYS},
-  {sys_max_insert_delayed_threads.name,
-   (char*) &sys_max_insert_delayed_threads,   SHOW_SYS},
-  {sys_max_join_size.name,	(char*) &sys_max_join_size,	    SHOW_SYS},
-  {sys_max_length_for_sort_data.name, (char*) &sys_max_length_for_sort_data,
-   SHOW_SYS},
-  {sys_max_prepared_stmt_count.name, (char*) &sys_max_prepared_stmt_count,
-    SHOW_SYS},
-  {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size,    SHOW_SYS},
-  {sys_max_seeks_for_key.name,  (char*) &sys_max_seeks_for_key,	    SHOW_SYS},
-  {sys_max_sort_length.name,	(char*) &sys_max_sort_length,	    SHOW_SYS},
-  {sys_max_sp_recursion_depth.name,
-    (char*) &sys_max_sp_recursion_depth, SHOW_SYS},
-  {sys_max_tmp_tables.name,	(char*) &sys_max_tmp_tables,	    SHOW_SYS},
-  {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
-  {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
-  {sys_multi_range_count.name,  (char*) &sys_multi_range_count,     SHOW_SYS},
-  {sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS},
-  {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size,
-   SHOW_SYS},
   {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
-  {sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
-   SHOW_SYS},
-  {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
-  
-  {sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
-  {sys_myisam_use_mmap.name, (char*) &sys_myisam_use_mmap, SHOW_SYS},
-  
 #ifdef __NT__
   {"named_pipe",	      (char*) &opt_enable_named_pipe,       SHOW_MY_BOOL},
 #endif
-  {sys_ndb_autoincrement_prefetch_sz.name,
-   (char*) &sys_ndb_autoincrement_prefetch_sz,                      SHOW_SYS},
-  {sys_ndb_cache_check_time.name,(char*) &sys_ndb_cache_check_time, SHOW_SYS},
-  {sys_ndb_extra_logging.name,(char*) &sys_ndb_extra_logging,       SHOW_SYS},
-  {sys_ndb_force_send.name,   (char*) &sys_ndb_force_send,          SHOW_SYS},
-  {sys_ndb_index_stat_cache_entries.name, (char*) &sys_ndb_index_stat_cache_entries, SHOW_SYS},
-  {sys_ndb_index_stat_enable.name, (char*) &sys_ndb_index_stat_enable, SHOW_SYS},
-  {sys_ndb_index_stat_update_freq.name, (char*) &sys_ndb_index_stat_update_freq, SHOW_SYS},
-#ifdef HAVE_NDB_BINLOG
-  {sys_ndb_report_thresh_binlog_epoch_slip.name,
-   (char*) &sys_ndb_report_thresh_binlog_epoch_slip,                SHOW_SYS},
-  {sys_ndb_report_thresh_binlog_mem_usage.name,
-   (char*) &sys_ndb_report_thresh_binlog_mem_usage,                 SHOW_SYS},
-#endif
-  {sys_ndb_use_copying_alter_table.name,
-   (char*) &sys_ndb_use_copying_alter_table,                        SHOW_SYS},
-  {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count,   SHOW_SYS},
-  {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS},
-  {sys_net_buffer_length.name,(char*) &sys_net_buffer_length,       SHOW_SYS},
-  {sys_net_read_timeout.name, (char*) &sys_net_read_timeout,        SHOW_SYS},
-  {sys_net_retry_count.name,  (char*) &sys_net_retry_count,	    SHOW_SYS},
-  {sys_net_write_timeout.name,(char*) &sys_net_write_timeout,       SHOW_SYS},
-  {sys_new_mode.name,         (char*) &sys_new_mode,                SHOW_SYS},
-  {sys_old_alter_table.name,  (char*) &sys_old_alter_table,         SHOW_SYS},
-  {sys_old_passwords.name,    (char*) &sys_old_passwords,           SHOW_SYS},
   {"open_files_limit",	      (char*) &open_files_limit,	    SHOW_LONG},
-  {sys_optimizer_prune_level.name, (char*) &sys_optimizer_prune_level,
-   SHOW_SYS},
-  {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
-   SHOW_SYS},
   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
   {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
   {"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},
-  {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
-   SHOW_SYS},
-#ifdef HAVE_QUERY_CACHE
-  {sys_query_cache_limit.name,(char*) &sys_query_cache_limit,	    SHOW_SYS},
-  {sys_query_cache_min_res_unit.name, (char*) &sys_query_cache_min_res_unit,
-   SHOW_SYS},
-  {sys_query_cache_size.name, (char*) &sys_query_cache_size,	    SHOW_SYS},
-  {sys_query_cache_type.name, (char*) &sys_query_cache_type,        SHOW_SYS},
-  {sys_query_cache_wlock_invalidate.name,
-   (char *) &sys_query_cache_wlock_invalidate, SHOW_SYS},
-#endif /* HAVE_QUERY_CACHE */
-  {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size,  SHOW_SYS},
-  {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size,
-   SHOW_SYS},
-  {sys_read_buff_size.name,   (char*) &sys_read_buff_size,	    SHOW_SYS},
-  {sys_readonly.name,         (char*) &sys_readonly,                SHOW_SYS},
-  {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size,	    SHOW_SYS},
 #ifdef HAVE_REPLICATION
-  {sys_relay_log_purge.name,  (char*) &sys_relay_log_purge,         SHOW_SYS},
   {"relay_log_space_limit",  (char*) &relay_log_space_limit,        SHOW_LONGLONG},
 #endif
-  {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank,       SHOW_SYS},
-  {"secure_auth",             (char*) &sys_secure_auth,             SHOW_SYS},
 #ifdef HAVE_SMEM
   {"shared_memory",           (char*) &opt_enable_shared_memory,    SHOW_MY_BOOL},
   {"shared_memory_base_name", (char*) &shared_memory_base_name,     SHOW_CHAR_PTR},
 #endif
-  {sys_server_id.name,	      (char*) &sys_server_id,		    SHOW_SYS},
   {"skip_external_locking",   (char*) &my_disable_locking,          SHOW_MY_BOOL},
   {"skip_networking",         (char*) &opt_disable_networking,      SHOW_BOOL},
   {"skip_show_database",      (char*) &opt_skip_show_db,            SHOW_BOOL},
 #ifdef HAVE_REPLICATION
-  {sys_slave_compressed_protocol.name,
-    (char*) &sys_slave_compressed_protocol,           SHOW_SYS},
   {"slave_load_tmpdir",       (char*) &slave_load_tmpdir,           SHOW_CHAR_PTR},
-  {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout,	    SHOW_SYS},
   {"slave_skip_errors",       (char*) &show_slave_skip_errors,      SHOW_FUNC},
-  {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries,   SHOW_SYS},
 #endif
-  {sys_slow_launch_time.name, (char*) &sys_slow_launch_time,        SHOW_SYS},
-  {sys_var_slow_query_log.name, (char*) &opt_slow_log,              SHOW_MY_BOOL},
-  {sys_var_slow_log_path.name, (char*) &sys_var_slow_log_path,      SHOW_SYS},
 #ifdef HAVE_SYS_UN_H
   {"socket",                  (char*) &mysqld_unix_port,             SHOW_CHAR_PTR},
 #endif
-  {sys_sort_buffer.name,      (char*) &sys_sort_buffer,             SHOW_SYS},
-  {sys_big_selects.name,      (char*) &sys_big_selects,             SHOW_SYS},
-  {sys_sql_mode.name,         (char*) &sys_sql_mode,                SHOW_SYS},
-  {"sql_notes",               (char*) &sys_sql_notes,               SHOW_SYS},
-  {"sql_warnings",            (char*) &sys_sql_warnings,            SHOW_SYS},
-  {sys_ssl_ca.name,           (char*) &sys_ssl_ca,                  SHOW_SYS},
-  {sys_ssl_capath.name,       (char*) &sys_ssl_capath,              SHOW_SYS},
-  {sys_ssl_cert.name,         (char*) &sys_ssl_cert,                SHOW_SYS},
-  {sys_ssl_cipher.name,       (char*) &sys_ssl_cipher,              SHOW_SYS},
-  {sys_ssl_key.name,          (char*) &sys_ssl_key,                 SHOW_SYS},
-  {sys_storage_engine.name,   (char*) &sys_storage_engine,          SHOW_SYS},
-#ifdef HAVE_REPLICATION
-  {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period,     SHOW_SYS},
-#endif
-  {sys_sync_frm.name,         (char*) &sys_sync_frm,               SHOW_SYS},
 #ifdef HAVE_TZNAME
   {"system_time_zone",        system_time_zone,                     SHOW_CHAR},
 #endif
   {"table_definition_cache",  (char*) &table_def_size,              SHOW_LONG},
   {"table_lock_wait_timeout", (char*) &table_lock_wait_timeout,     SHOW_LONG },
   {"table_open_cache",        (char*) &table_cache_size,            SHOW_LONG},
-  {sys_table_type.name,	      (char*) &sys_table_type,	            SHOW_SYS},
-  {sys_thread_cache_size.name,(char*) &sys_thread_cache_size,       SHOW_SYS},
 #ifdef HAVE_THR_SETCONCURRENCY
   {"thread_concurrency",      (char*) &concurrency,                 SHOW_LONG},
 #endif
   {"thread_stack",            (char*) &thread_stack,                SHOW_LONG},
-  {sys_time_format.name,      (char*) &sys_time_format,		    SHOW_SYS},
-  {"time_zone",               (char*) &sys_time_zone,               SHOW_SYS},
-  {sys_timed_mutexes.name,    (char*) &sys_timed_mutexes,       SHOW_SYS},
-  {sys_tmp_table_size.name,   (char*) &sys_tmp_table_size,	    SHOW_SYS},
-  {sys_tmpdir.name,           (char*) &sys_tmpdir,	            SHOW_SYS},
-  {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size,
-   SHOW_SYS},
-  {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size,  SHOW_SYS},
-  {sys_tx_isolation.name,     (char*) &sys_tx_isolation,	    SHOW_SYS},
-  {sys_updatable_views_with_limit.name,
-                              (char*) &sys_updatable_views_with_limit,SHOW_SYS},
-  {sys_version.name,          (char*) &sys_version,                 SHOW_SYS},
-  {sys_version_comment.name,  (char*) &sys_version_comment,         SHOW_SYS},
-  {sys_version_compile_machine.name, (char*) &sys_version_compile_machine,
-   SHOW_SYS},
-  {sys_version_compile_os.name,	(char*) &sys_version_compile_os,    SHOW_SYS},
-  {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout,	    SHOW_SYS},
-  {NullS, NullS, SHOW_LONG}
+  /* no trailing {NullS, NullS, SHOW_LONG} */
 };
 
 
@@ -1319,7 +1028,7 @@
   /*
     Cluster does not support changing the binlog format on the fly yet.
   */
-  LEX_STRING ndb_name= {STRING_WITH_LEN("ndbcluster")};
+  LEX_STRING ndb_name= {(char*)STRING_WITH_LEN("ndbcluster")};
   if (opt_bin_log && plugin_is_ready(&ndb_name, MYSQL_STORAGE_ENGINE_PLUGIN))
   {
     my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0));
@@ -1414,9 +1123,9 @@
 
 
 sys_var_long_ptr::
-sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+sys_var_long_ptr(sys_var_chain &chain, const char *name_arg, ulong *value_ptr,
                  sys_after_update_func after_update_arg)
-  :sys_var_long_ptr_global(name_arg, value_ptr,
+  :sys_var_long_ptr_global(chain, name_arg, value_ptr,
                            &LOCK_global_system_variables, after_update_arg)
 {}
 
@@ -3206,18 +2915,79 @@
   Initialises sys variables and put them in system_variable_hash
 */
 
+int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
+{
+  for (sys_var *var= first; var; var= var->next)
+  {
+    var->name_length= strlen(var->name);
+    /* check if conflicting variable already exists */
+    if (hash_search(&system_variable_hash, var->name, var->name_length))
+      return mysql_del_sys_var_chain(first);
+    var->option_limits= find_option(long_options, var->name);
+    if (my_hash_insert(&system_variable_hash, (byte*) var))
+      return mysql_del_sys_var_chain(first);
+  }
+  return 0;
+}
+
+int mysql_del_sys_var_chain(sys_var *first)
+{
+  for (sys_var *var= first; var; var= var->next)
+    if (hash_delete(&system_variable_hash, (byte*) var))
+      break;
+  return 1;
+}
+
+static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
+{
+  return strcmp(a->name, b->name);
+}
 
-void set_var_init()
+SHOW_VAR* enumerate_sys_vars(THD *thd)
+{
+  int count= system_variable_hash.records;
+  int fixed_count= sizeof(fixed_vars) / sizeof(SHOW_VAR);
+  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
+  SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size);
+  if (result)
+  {
+    SHOW_VAR *show= result + fixed_count;
+    memcpy(result, fixed_vars, sizeof(fixed_vars));
+    for (int i= 0; i < count; i++)
+    {
+      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
+      show->name= var->name;
+      show->value= (char*) var;
+      show->type= SHOW_SYS;
+      show++;
+    }
+    /* sort into order */
+    qsort(result, count + fixed_count, sizeof(SHOW_VAR), (qsort_cmp)show_cmp);
+    
+    /* make last element empty */
+    bzero(show, sizeof(SHOW_VAR));
+  }
+  return result;
+}
+
+
+int set_var_init()
 {
   sys_var *var;
+  uint count= 0;
+  DBUG_ENTER("set_var_init");
+  
+  for (sys_var *var=vars.first; var; var= var->next, count++);
 
-  hash_init(&system_variable_hash, system_charset_info, sys_var::sys_vars, 0,
+  hash_init(&system_variable_hash, system_charset_info, count, 0,
 	    0, (hash_get_key) get_sys_var_length, 0, 0);
-  for (var= sys_var::first; var; var= var->next)
+
+  vars.last->next= NULL;
+  if (mysql_add_sys_var_chain(vars.first, my_long_options))
   {
-    var->name_length= strlen(var->name);
-    var->option_limits= find_option(my_long_options, var->name);
-    my_hash_insert(&system_variable_hash, (byte*) var);
+    /* should not happen */
+    fprintf(stderr, "failed to initialize system variables");
+    unireg_abort(1);
   }
   /*
     Special cases
@@ -3226,6 +2996,7 @@
     As these variables are deprecated, this code will disappear soon...
   */
   sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
+  DBUG_RETURN(0);
 }
 
 

--- 1.93/sql/set_var.h	2006-12-05 11:05:29 -08:00
+++ 1.94/sql/set_var.h	2006-12-05 11:05:29 -08:00
@@ -27,6 +27,7 @@
 
 class sys_var;
 class set_var;
+class sys_var_pluginvar; /* opaque */
 typedef struct system_variables SV;
 typedef struct my_locale_st MY_LOCALE;
 
@@ -38,11 +39,16 @@
 typedef void (*sys_set_default_func)(THD *, enum_var_type);
 typedef byte *(*sys_value_ptr_func)(THD *thd);
 
+class sys_var;
+struct sys_var_chain
+{
+  sys_var *first;
+  sys_var *last;
+};
+
 class sys_var
 {
 public:
-  static sys_var *first;
-  static uint sys_vars;
   sys_var *next;
   struct my_option *option_limits;	/* Updated by by set_var_init() */
   uint name_length;			/* Updated by by set_var_init() */
@@ -50,17 +56,17 @@
 
   sys_after_update_func after_update;
   bool no_support_one_shot;
-  sys_var(const char *name_arg,sys_after_update_func func= NULL)
+  sys_var(sys_var_chain &chain, const char *name_arg,sys_after_update_func func= NULL)
     :name(name_arg), after_update(func)
     , no_support_one_shot(1)
-  { add_sys_var(); }
-  virtual ~sys_var() {}
-  void add_sys_var()
   {
-    next= first;
-    first= this;
-    sys_vars++;
+    if (chain.last)
+      chain.last->next= this;
+    else
+      chain.first= this;
+    chain.last= this;
   }
+  virtual ~sys_var() {}
   virtual bool check(THD *thd, set_var *var);
   bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
   bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
@@ -78,6 +84,7 @@
   Item *item(THD *thd, enum_var_type type, LEX_STRING *base);
   virtual bool is_struct() { return 0; }
   virtual bool is_readonly() const { return 0; }
+  virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
 };
 
 
@@ -91,9 +98,10 @@
 protected:
   pthread_mutex_t *guard;
 public:
-  sys_var_global(const char *name_arg, sys_after_update_func after_update_arg,
+  sys_var_global(sys_var_chain &chain, const char *name_arg,
+                 sys_after_update_func after_update_arg,
                  pthread_mutex_t *guard_arg)
-    :sys_var(name_arg, after_update_arg), guard(guard_arg) {}
+    :sys_var(chain, name_arg, after_update_arg), guard(guard_arg) {}
 };
 
 
@@ -106,10 +114,11 @@
 {
 public:
   ulong *value;
-  sys_var_long_ptr_global(const char *name_arg, ulong *value_ptr,
+  sys_var_long_ptr_global(sys_var_chain &chain, const char *name_arg, ulong *value_ptr,
                         pthread_mutex_t *guard_arg,
                         sys_after_update_func after_update_arg= NULL)
-    :sys_var_global(name_arg, after_update_arg, guard_arg), value(value_ptr) {}
+    :sys_var_global(chain, name_arg, after_update_arg, guard_arg), 
+     value(value_ptr) {}
   bool check(THD *thd, set_var *var);
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
@@ -126,7 +135,7 @@
 class sys_var_long_ptr :public sys_var_long_ptr_global
 {
 public:
-  sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+  sys_var_long_ptr(sys_var_chain &chain, const char *name_arg, ulong *value_ptr,
                    sys_after_update_func after_update_arg= NULL);
 };
 
@@ -135,11 +144,13 @@
 {
 public:
   ulonglong *value;
-  sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr)
-    :sys_var(name_arg),value(value_ptr) {}
-  sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr,
+  sys_var_ulonglong_ptr(sys_var_chain &chain, const char *name_arg, 
+                        ulonglong *value_ptr)
+    :sys_var(chain, name_arg),value(value_ptr) {}
+  sys_var_ulonglong_ptr(sys_var_chain &chain, const char *name_arg, 
+                       ulonglong *value_ptr,
 		       sys_after_update_func func)
-    :sys_var(name_arg,func), value(value_ptr) {}
+    :sys_var(chain, name_arg,func), value(value_ptr) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
   SHOW_TYPE type() { return SHOW_LONGLONG; }
@@ -152,8 +163,8 @@
 {
 public:
   my_bool *value;
-  sys_var_bool_ptr(const char *name_arg, my_bool *value_arg)
-    :sys_var(name_arg),value(value_arg)
+  sys_var_bool_ptr(sys_var_chain &chain, const char *name_arg, my_bool *value_arg)
+    :sys_var(chain, name_arg),value(value_arg)
   {}
   bool check(THD *thd, set_var *var)
   {
@@ -176,12 +187,12 @@
   sys_check_func check_func;
   sys_update_func update_func;
   sys_set_default_func set_default_func;
-  sys_var_str(const char *name_arg,
+  sys_var_str(sys_var_chain &chain, const char *name_arg,
 	      sys_check_func check_func_arg,
 	      sys_update_func update_func_arg,
 	      sys_set_default_func set_default_func_arg,
               char *value_arg)
-    :sys_var(name_arg), value(value_arg), check_func(check_func_arg),
+    :sys_var(chain, name_arg), value(value_arg), check_func(check_func_arg),
     update_func(update_func_arg),set_default_func(set_default_func_arg)
   {}
   bool check(THD *thd, set_var *var);
@@ -204,12 +215,47 @@
 };
 
 
+class sys_var_str_ptr :public sys_var
+{
+public:
+  char **value;					// Pointer to allocated string
+  sys_check_func check_func;
+  sys_update_func update_func;
+  sys_set_default_func set_default_func;
+  sys_var_str_ptr(sys_var_chain &chain, const char *name_arg,
+	      sys_check_func check_func_arg,
+	      sys_update_func update_func_arg,
+	      sys_set_default_func set_default_func_arg,
+              char **value_arg)
+    :sys_var(chain, name_arg), value(value_arg), check_func(check_func_arg),
+    update_func(update_func_arg),set_default_func(set_default_func_arg)
+  {}
+  bool check(THD *thd, set_var *var);
+  bool update(THD *thd, set_var *var)
+  {
+    return (*update_func)(thd, var);
+  }
+  void set_default(THD *thd, enum_var_type type)
+  {
+    (*set_default_func)(thd, type);
+  }
+  SHOW_TYPE type() { return SHOW_CHAR_PTR; }
+  byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
+  { return (byte*) value; }
+  bool check_update_type(Item_result type)
+  {
+    return type != STRING_RESULT;		/* Only accept strings */
+  }
+  bool check_default(enum_var_type type) { return 0; }
+};
+
+
 class sys_var_const_str :public sys_var
 {
 public:
   char *value;					// Pointer to const value
-  sys_var_const_str(const char *name_arg, const char *value_arg)
-    :sys_var(name_arg),value((char*) value_arg)
+  sys_var_const_str(sys_var_chain &chain, const char *name_arg, const char *value_arg)
+    :sys_var(chain, name_arg),value((char*) value_arg)
   {}
   bool check(THD *thd, set_var *var)
   {
@@ -237,8 +283,8 @@
 {
 public:
   char **value;					// Pointer to const value
-  sys_var_const_str_ptr(const char *name_arg, char **value_arg)
-    :sys_var(name_arg),value(value_arg)
+  sys_var_const_str_ptr(sys_var_chain &chain, const char *name_arg, char **value_arg)
+    :sys_var(chain, name_arg),value(value_arg)
   {}
   bool check(THD *thd, set_var *var)
   {
@@ -267,9 +313,9 @@
   uint *value;
   TYPELIB *enum_names;
 public:
-  sys_var_enum(const char *name_arg, uint *value_arg,
+  sys_var_enum(sys_var_chain &chain, const char *name_arg, uint *value_arg,
 	       TYPELIB *typelib, sys_after_update_func func)
-    :sys_var(name_arg,func), value(value_arg), enum_names(typelib)
+    :sys_var(chain, name_arg,func), value(value_arg), enum_names(typelib)
   {}
   bool check(THD *thd, set_var *var)
   {
@@ -285,8 +331,9 @@
 class sys_var_thd :public sys_var
 {
 public:
-  sys_var_thd(const char *name_arg, sys_after_update_func func= NULL)
-    :sys_var(name_arg,func)
+  sys_var_thd(sys_var_chain &chain, const char *name_arg, 
+              sys_after_update_func func= NULL)
+    :sys_var(chain, name_arg,func)
   {}
   bool check_type(enum_var_type type) { return 0; }
   bool check_default(enum_var_type type)
@@ -301,12 +348,12 @@
   sys_check_func check_func;
 public:
   ulong SV::*offset;
-  sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg)
-    :sys_var_thd(name_arg), check_func(0), offset(offset_arg)
+  sys_var_thd_ulong(sys_var_chain &chain, const char *name_arg, ulong SV::*offset_arg)
+    :sys_var_thd(chain, name_arg), check_func(0), offset(offset_arg)
   {}
-  sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg,
+  sys_var_thd_ulong(sys_var_chain &chain, const char *name_arg, ulong SV::*offset_arg,
 		   sys_check_func c_func, sys_after_update_func au_func)
-    :sys_var_thd(name_arg,au_func), check_func(c_func), offset(offset_arg)
+    :sys_var_thd(chain, name_arg,au_func), check_func(c_func), offset(offset_arg)
   {}
   bool check(THD *thd, set_var *var);
   bool update(THD *thd, set_var *var);
@@ -320,12 +367,14 @@
 {
 public:
   ha_rows SV::*offset;
-  sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg)
-    :sys_var_thd(name_arg), offset(offset_arg)
+  sys_var_thd_ha_rows(sys_var_chain &chain, const char *name_arg, 
+                      ha_rows SV::*offset_arg)
+    :sys_var_thd(chain, name_arg), offset(offset_arg)
   {}
-  sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg,
+  sys_var_thd_ha_rows(sys_var_chain &chain, const char *name_arg, 
+                      ha_rows SV::*offset_arg,
 		      sys_after_update_func func)
-    :sys_var_thd(name_arg,func), offset(offset_arg)
+    :sys_var_thd(chain, name_arg,func), offset(offset_arg)
   {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
@@ -339,12 +388,14 @@
 public:
   ulonglong SV::*offset;
   bool only_global;
-  sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg)
-    :sys_var_thd(name_arg), offset(offset_arg)
+  sys_var_thd_ulonglong(sys_var_chain &chain, const char *name_arg, 
+                        ulonglong SV::*offset_arg)
+    :sys_var_thd(chain, name_arg), offset(offset_arg)
   {}
-  sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg,
+  sys_var_thd_ulonglong(sys_var_chain &chain, const char *name_arg, 
+                        ulonglong SV::*offset_arg,
 			sys_after_update_func func, bool only_global_arg)
-    :sys_var_thd(name_arg, func), offset(offset_arg),
+    :sys_var_thd(chain, name_arg, func), offset(offset_arg),
     only_global(only_global_arg)
   {}
   bool update(THD *thd, set_var *var);
@@ -366,12 +417,12 @@
 {
 public:
   my_bool SV::*offset;
-  sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg)
-    :sys_var_thd(name_arg), offset(offset_arg)
+  sys_var_thd_bool(sys_var_chain &chain, const char *name_arg, my_bool SV::*offset_arg)
+    :sys_var_thd(chain, name_arg), offset(offset_arg)
   {}
-  sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg,
+  sys_var_thd_bool(sys_var_chain &chain, const char *name_arg, my_bool SV::*offset_arg,
 		   sys_after_update_func func)
-    :sys_var_thd(name_arg,func), offset(offset_arg)
+    :sys_var_thd(chain, name_arg,func), offset(offset_arg)
   {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
@@ -392,21 +443,21 @@
   TYPELIB *enum_names;
   sys_check_func check_func;
 public:
-  sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+  sys_var_thd_enum(sys_var_chain &chain, const char *name_arg, ulong SV::*offset_arg,
 		   TYPELIB *typelib)
-    :sys_var_thd(name_arg), offset(offset_arg), enum_names(typelib),
+    :sys_var_thd(chain, name_arg), offset(offset_arg), enum_names(typelib),
     check_func(0)
   {}
-  sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+  sys_var_thd_enum(sys_var_chain &chain, const char *name_arg, ulong SV::*offset_arg,
 		   TYPELIB *typelib,
 		   sys_after_update_func func)
-    :sys_var_thd(name_arg,func), offset(offset_arg), enum_names(typelib),
+    :sys_var_thd(chain, name_arg,func), offset(offset_arg), enum_names(typelib),
     check_func(0)
   {}
-  sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+  sys_var_thd_enum(sys_var_chain &chain, const char *name_arg, ulong SV::*offset_arg,
 		   TYPELIB *typelib, sys_after_update_func func,
                    sys_check_func check)
-    :sys_var_thd(name_arg,func), offset(offset_arg), enum_names(typelib),
+    :sys_var_thd(chain, name_arg,func), offset(offset_arg), enum_names(typelib),
     check_func(check)
   {}
   bool check(THD *thd, set_var *var)
@@ -429,8 +480,9 @@
 class sys_var_thd_sql_mode :public sys_var_thd_enum
 {
 public:
-  sys_var_thd_sql_mode(const char *name_arg, ulong SV::*offset_arg)
-    :sys_var_thd_enum(name_arg, offset_arg, &sql_mode_typelib,
+  sys_var_thd_sql_mode(sys_var_chain &chain, const char *name_arg, 
+                       ulong SV::*offset_arg)
+    :sys_var_thd_enum(chain, name_arg, offset_arg, &sql_mode_typelib,
 		      fix_sql_mode_var)
   {}
   bool check(THD *thd, set_var *var)
@@ -449,8 +501,9 @@
 protected:
   handlerton *SV::*offset;
 public:
-  sys_var_thd_storage_engine(const char *name_arg, handlerton *SV::*offset_arg)
-    :sys_var_thd(name_arg), offset(offset_arg)
+  sys_var_thd_storage_engine(sys_var_chain &chain, const char *name_arg, 
+                             handlerton *SV::*offset_arg)
+    :sys_var_thd(chain, name_arg), offset(offset_arg)
   {}
   bool check(THD *thd, set_var *var);
 SHOW_TYPE type() { return SHOW_CHAR; }
@@ -466,8 +519,9 @@
 class sys_var_thd_table_type :public sys_var_thd_storage_engine
 {
 public:
-  sys_var_thd_table_type(const char *name_arg, handlerton *SV::*offset_arg)
-    :sys_var_thd_storage_engine(name_arg, offset_arg)
+  sys_var_thd_table_type(sys_var_chain &chain, const char *name_arg, 
+                         handlerton *SV::*offset_arg)
+    :sys_var_thd_storage_engine(chain, name_arg, offset_arg)
   {}
   void warn_deprecated(THD *thd);
   void set_default(THD *thd, enum_var_type type);
@@ -481,10 +535,10 @@
 public:
   ulong bit_flag;
   bool reverse;
-  sys_var_thd_bit(const char *name_arg,
+  sys_var_thd_bit(sys_var_chain &chain, const char *name_arg,
                   sys_check_func c_func, sys_update_func u_func,
                   ulong bit, bool reverse_arg=0)
-    :sys_var_thd(name_arg), check_func(c_func), update_func(u_func),
+    :sys_var_thd(chain, name_arg), check_func(c_func), update_func(u_func),
     bit_flag(bit), reverse(reverse_arg)
   {}
   bool check(THD *thd, set_var *var);
@@ -498,7 +552,8 @@
 class sys_var_thd_dbug :public sys_var_thd
 {
 public:
-  sys_var_thd_dbug(const char *name_arg) :sys_var_thd(name_arg) {}
+  sys_var_thd_dbug(sys_var_chain &chain, const char *name_arg)
+    :sys_var_thd(chain, name_arg) {}
   bool check_update_type(Item_result type) { return type != STRING_RESULT; }
   bool check(THD *thd, set_var *var);
   SHOW_TYPE type() { return SHOW_CHAR; }
@@ -514,7 +569,8 @@
 class sys_var_timestamp :public sys_var
 {
 public:
-  sys_var_timestamp(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_timestamp(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
   bool check_type(enum_var_type type)    { return type == OPT_GLOBAL; }
@@ -527,7 +583,8 @@
 class sys_var_last_insert_id :public sys_var
 {
 public:
-  sys_var_last_insert_id(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_last_insert_id(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
   SHOW_TYPE type() { return SHOW_LONGLONG; }
@@ -538,7 +595,8 @@
 class sys_var_insert_id :public sys_var
 {
 public:
-  sys_var_insert_id(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_insert_id(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
   SHOW_TYPE type() { return SHOW_LONGLONG; }
@@ -550,7 +608,8 @@
 class sys_var_slave_skip_counter :public sys_var
 {
 public:
-  sys_var_slave_skip_counter(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_slave_skip_counter(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool check(THD *thd, set_var *var);
   bool update(THD *thd, set_var *var);
   bool check_type(enum_var_type type) { return type != OPT_GLOBAL; }
@@ -563,8 +622,9 @@
 class sys_var_sync_binlog_period :public sys_var_long_ptr
 {
 public:
-  sys_var_sync_binlog_period(const char *name_arg, ulong *value_ptr)
-    :sys_var_long_ptr(name_arg,value_ptr) {}
+  sys_var_sync_binlog_period(sys_var_chain &chain, const char *name_arg, 
+                             ulong *value_ptr)
+    :sys_var_long_ptr(chain, name_arg,value_ptr) {}
   bool update(THD *thd, set_var *var);
 };
 #endif
@@ -572,7 +632,8 @@
 class sys_var_rand_seed1 :public sys_var
 {
 public:
-  sys_var_rand_seed1(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_rand_seed1(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
 };
@@ -580,7 +641,8 @@
 class sys_var_rand_seed2 :public sys_var
 {
 public:
-  sys_var_rand_seed2(const char *name_arg) :sys_var(name_arg) {}
+  sys_var_rand_seed2(sys_var_chain &chain, const char *name_arg)
+    :sys_var(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
 };
@@ -589,7 +651,8 @@
 class sys_var_collation :public sys_var_thd
 {
 public:
-  sys_var_collation(const char *name_arg) :sys_var_thd(name_arg)
+  sys_var_collation(sys_var_chain &chain, const char *name_arg)
+    :sys_var_thd(chain, name_arg)
     {
     no_support_one_shot= 0;
     }
@@ -607,8 +670,8 @@
 {
 public:
   bool nullable;
-  sys_var_character_set(const char *name_arg) :
-    sys_var_thd(name_arg)
+  sys_var_character_set(sys_var_chain &chain, const char *name_arg) :
+    sys_var_thd(chain, name_arg)
   {
     nullable= 0;
     /*
@@ -633,8 +696,8 @@
 class sys_var_character_set_filesystem :public sys_var_character_set
 {
 public:
-  sys_var_character_set_filesystem(const char *name_arg) :
-    sys_var_character_set(name_arg) {}
+  sys_var_character_set_filesystem(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
 };
@@ -642,8 +705,8 @@
 class sys_var_character_set_client :public sys_var_character_set
 {
 public:
-  sys_var_character_set_client(const char *name_arg) :
-    sys_var_character_set(name_arg) {}
+  sys_var_character_set_client(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
 };
@@ -651,8 +714,8 @@
 class sys_var_character_set_results :public sys_var_character_set
 {
 public:
-  sys_var_character_set_results(const char *name_arg) :
-    sys_var_character_set(name_arg) 
+  sys_var_character_set_results(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) 
     { nullable= 1; }
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
@@ -661,8 +724,8 @@
 class sys_var_character_set_server :public sys_var_character_set
 {
 public:
-  sys_var_character_set_server(const char *name_arg) :
-    sys_var_character_set(name_arg) {}
+  sys_var_character_set_server(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
 };
@@ -670,8 +733,8 @@
 class sys_var_character_set_database :public sys_var_character_set
 {
 public:
-  sys_var_character_set_database(const char *name_arg) :
-    sys_var_character_set(name_arg) {}
+  sys_var_character_set_database(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
 };
@@ -679,8 +742,8 @@
 class sys_var_character_set_connection :public sys_var_character_set
 {
 public:
-  sys_var_character_set_connection(const char *name_arg) :
-    sys_var_character_set(name_arg) {}
+  sys_var_character_set_connection(sys_var_chain &chain, const char *name_arg) :
+    sys_var_character_set(chain, name_arg) {}
   void set_default(THD *thd, enum_var_type type);
   CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
 };
@@ -688,7 +751,8 @@
 class sys_var_collation_connection :public sys_var_collation
 {
 public:
-  sys_var_collation_connection(const char *name_arg) :sys_var_collation(name_arg) {}
+  sys_var_collation_connection(sys_var_chain &chain, const char *name_arg)
+    :sys_var_collation(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
@@ -697,7 +761,8 @@
 class sys_var_collation_server :public sys_var_collation
 {
 public:
-  sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
+  sys_var_collation_server(sys_var_chain &chain, const char *name_arg)
+    :sys_var_collation(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
@@ -706,7 +771,8 @@
 class sys_var_collation_database :public sys_var_collation
 {
 public:
-  sys_var_collation_database(const char *name_arg) :sys_var_collation(name_arg) {}
+  sys_var_collation_database(sys_var_chain &chain, const char *name_arg)
+    :sys_var_collation(chain, name_arg) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
@@ -718,8 +784,9 @@
 protected:
   size_t offset;
 public:
-  sys_var_key_cache_param(const char *name_arg, size_t offset_arg)
-    :sys_var(name_arg), offset(offset_arg)
+  sys_var_key_cache_param(sys_var_chain &chain, const char *name_arg, 
+                          size_t offset_arg)
+    :sys_var(chain, name_arg), offset(offset_arg)
   {}
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
   bool check_default(enum_var_type type) { return 1; }
@@ -730,8 +797,9 @@
 class sys_var_key_buffer_size :public sys_var_key_cache_param
 {
 public:
-  sys_var_key_buffer_size(const char *name_arg)
-    :sys_var_key_cache_param(name_arg, offsetof(KEY_CACHE, param_buff_size))
+  sys_var_key_buffer_size(sys_var_chain &chain, const char *name_arg)
+    :sys_var_key_cache_param(chain, name_arg,
+                             offsetof(KEY_CACHE, param_buff_size))
   {}
   bool update(THD *thd, set_var *var);
   SHOW_TYPE type() { return SHOW_LONGLONG; }
@@ -741,8 +809,8 @@
 class sys_var_key_cache_long :public sys_var_key_cache_param
 {
 public:
-  sys_var_key_cache_long(const char *name_arg, size_t offset_arg)
-    :sys_var_key_cache_param(name_arg, offset_arg)
+  sys_var_key_cache_long(sys_var_chain &chain, const char *name_arg, size_t offset_arg)
+    :sys_var_key_cache_param(chain, name_arg, offset_arg)
   {}
   bool update(THD *thd, set_var *var);
   SHOW_TYPE type() { return SHOW_LONG; }
@@ -754,10 +822,10 @@
   DATE_TIME_FORMAT *SV::*offset;
   timestamp_type date_time_type;
 public:
-  sys_var_thd_date_time_format(const char *name_arg,
+  sys_var_thd_date_time_format(sys_var_chain &chain, const char *name_arg,
 			       DATE_TIME_FORMAT *SV::*offset_arg,
 			       timestamp_type date_time_type_arg)
-    :sys_var_thd(name_arg), offset(offset_arg),
+    :sys_var_thd(chain, name_arg), offset(offset_arg),
     date_time_type(date_time_type_arg)
   {}
   SHOW_TYPE type() { return SHOW_CHAR; }
@@ -778,8 +846,9 @@
 {
   uint log_type;
 public:
-  sys_var_log_state(const char *name_arg, my_bool *value_arg, uint log_type_arg)
-    :sys_var_bool_ptr(name_arg, value_arg), log_type(log_type_arg) {}
+  sys_var_log_state(sys_var_chain &chain, const char *name_arg, my_bool *value_arg, 
+                    uint log_type_arg)
+    :sys_var_bool_ptr(chain, name_arg, value_arg), log_type(log_type_arg) {}
   bool update(THD *thd, set_var *var);
   void set_default(THD *thd, enum_var_type type);
 };
@@ -790,9 +859,9 @@
   ulong *value;
   TYPELIB *enum_names;
 public:
-  sys_var_log_output(const char *name_arg, ulong *value_arg,
+  sys_var_log_output(sys_var_chain &chain, const char *name_arg, ulong *value_arg,
                      TYPELIB *typelib, sys_after_update_func func)
-    :sys_var(name_arg,func), value(value_arg), enum_names(typelib)
+    :sys_var(chain, name_arg,func), value(value_arg), enum_names(typelib)
   {}
   bool check(THD *thd, set_var *var)
   {
@@ -814,10 +883,10 @@
   enum_var_type var_type;
   SHOW_TYPE show_type;
   sys_value_ptr_func value_ptr_func;
-  sys_var_readonly(const char *name_arg, enum_var_type type,
+  sys_var_readonly(sys_var_chain &chain, const char *name_arg, enum_var_type type,
 		   SHOW_TYPE show_type_arg,
 		   sys_value_ptr_func value_ptr_func_arg)
-    :sys_var(name_arg), var_type(type), 
+    :sys_var(chain, name_arg), var_type(type), 
        show_type(show_type_arg), value_ptr_func(value_ptr_func_arg)
   {}
   bool update(THD *thd, set_var *var) { return 1; }
@@ -838,9 +907,9 @@
   SHOW_COMP_OPTION *have_variable;
 
 public:
-  sys_var_have_variable(const char *variable_name,
+  sys_var_have_variable(sys_var_chain &chain, const char *variable_name,
                         SHOW_COMP_OPTION *have_variable_arg):
-    sys_var(variable_name),
+    sys_var(chain, variable_name),
     have_variable(have_variable_arg)
   { }
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
@@ -859,8 +928,8 @@
 class sys_var_thd_time_zone :public sys_var_thd
 {
 public:
-  sys_var_thd_time_zone(const char *name_arg):
-    sys_var_thd(name_arg) 
+  sys_var_thd_time_zone(sys_var_chain &chain, const char *name_arg):
+    sys_var_thd(chain, name_arg) 
   {
     no_support_one_shot= 0;
   }
@@ -880,8 +949,8 @@
 class sys_var_max_user_conn : public sys_var_thd
 {
 public:
-  sys_var_max_user_conn(const char *name_arg):
-    sys_var_thd(name_arg) {}
+  sys_var_max_user_conn(sys_var_chain &chain, const char *name_arg):
+    sys_var_thd(chain, name_arg) {}
   bool check(THD *thd, set_var *var);
   bool update(THD *thd, set_var *var);
   bool check_default(enum_var_type type)
@@ -897,8 +966,9 @@
 {
   /* We need a derived class only to have a warn_deprecated() */
 public:
-  sys_var_trust_routine_creators(const char *name_arg, my_bool *value_arg) :
-    sys_var_bool_ptr(name_arg, value_arg) {};
+  sys_var_trust_routine_creators(sys_var_chain &chain, const char *name_arg, 
+                                 my_bool *value_arg) :
+    sys_var_bool_ptr(chain, name_arg, value_arg) {};
   void warn_deprecated(THD *thd);
   void set_default(THD *thd, enum_var_type type);
   bool update(THD *thd, set_var *var);
@@ -908,8 +978,8 @@
 class sys_var_thd_lc_time_names :public sys_var_thd
 {
 public:
-  sys_var_thd_lc_time_names(const char *name_arg):
-    sys_var_thd(name_arg)
+  sys_var_thd_lc_time_names(sys_var_chain &chain, const char *name_arg):
+    sys_var_thd(chain, name_arg)
   {}
   bool check(THD *thd, set_var *var);
   SHOW_TYPE type() { return SHOW_CHAR; }
@@ -928,8 +998,8 @@
 {
   /* We need a derived class only to have a warn_deprecated() */
 public:
-  sys_var_event_scheduler(const char *name_arg) :
-    sys_var_long_ptr(name_arg, NULL, NULL) {};
+  sys_var_event_scheduler(sys_var_chain &chain, const char *name_arg) :
+    sys_var_long_ptr(chain, name_arg, NULL, NULL) {};
   bool update(THD *thd, set_var *var);
   byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
   SHOW_TYPE type() { return SHOW_CHAR; }
@@ -947,8 +1017,9 @@
 class sys_var_thd_binlog_format :public sys_var_thd_enum
 {
 public:
-  sys_var_thd_binlog_format(const char *name_arg, ulong SV::*offset_arg)
-    :sys_var_thd_enum(name_arg, offset_arg,
+  sys_var_thd_binlog_format(sys_var_chain &chain, const char *name_arg, 
+                            ulong SV::*offset_arg)
+    :sys_var_thd_enum(chain, name_arg, offset_arg,
                       &binlog_format_typelib
 #ifdef HAVE_ROW_BASED_REPLICATION
                       , fix_binlog_format_after_update
@@ -1117,8 +1188,11 @@
   Prototypes for helper functions
 */
 
-void set_var_init();
+int set_var_init();
 void set_var_free();
+SHOW_VAR* enumerate_sys_vars(THD *thd);
+int mysql_add_sys_var_chain(sys_var *chain, struct my_option *long_options);
+int mysql_del_sys_var_chain(sys_var *chain);
 sys_var *find_sys_var(const char *str, uint length=0);
 int sql_set_variables(THD *thd, List<set_var_base> *var_list);
 bool not_all_support_one_shot(List<set_var_base> *var_list);

--- 1.23/include/mysql/plugin.h	2006-12-05 11:05:29 -08:00
+++ 1.24/include/mysql/plugin.h	2006-12-05 11:05:29 -08:00
@@ -68,6 +68,32 @@
 
 #define mysql_declare_plugin_end ,{0,0,0,0,0,0,0,0,0,0,0,0}}
 
+/* declare some types which can be used without including mysys headers */
+#ifndef _global_h
+#ifndef HAVE_UINT
+#define HAVE_UINT
+typedef unsigned int uint;
+typedef unsigned short ushort;
+#endif
+
+#ifndef HAVE_ULONG
+#define HAVE_ULONG
+typedef unsigned long ulong;
+#endif
+
+#ifndef longlong_defined
+#define longlong_defined
+#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8
+typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
+typedef long long int   longlong;
+#else
+typedef unsigned long   ulonglong;        /* ulong or unsigned long long */
+typedef long            longlong;
+#endif
+#endif
+#endif
+
+
 /*
   declarations for SHOW STATUS support in plugins
 */
@@ -87,6 +113,169 @@
 #define SHOW_VAR_FUNC_BUFF_SIZE 1024
 typedef int (*mysql_show_var_func)(void *, struct st_mysql_show_var*, char *);
 
+
+/*
+  declarations for server variables and command line options
+*/
+
+enum enum_mysql_sys_var {
+  MYSQL_SYS_VAR_UNKNOWN,
+
+  MYSQL_SYS_VAR_BOOL,
+  MYSQL_SYS_VAR_INT,
+  MYSQL_SYS_VAR_UINT,
+  MYSQL_SYS_VAR_LONG,
+  MYSQL_SYS_VAR_ULONG,
+  MYSQL_SYS_VAR_LONGLONG,
+  MYSQL_SYS_VAR_ULONGLONG,
+  MYSQL_SYS_VAR_STR,
+  MYSQL_SYS_VAR_ENUM,
+  MYSQL_SYS_VAR_SET,
+
+  MYSQL_THD_VAR_BOOL,
+  MYSQL_THD_VAR_INT,
+  MYSQL_THD_VAR_UINT,
+  MYSQL_THD_VAR_LONG,
+  MYSQL_THD_VAR_ULONG,
+  MYSQL_THD_VAR_LONGLONG,
+  MYSQL_THD_VAR_ULONGLONG,
+  MYSQL_THD_VAR_STR,
+  MYSQL_THD_VAR_ENUM,
+  MYSQL_THD_VAR_SET,
+};
+
+struct st_mysql_sys_var;
+typedef 
+void (*sys_var_notify_func)(void *thd, const struct st_mysql_sys_var *var);
+typedef 
+int  (*sys_var_update_func)(void *thd, const struct st_mysql_sys_var *var,
+                            const char *str, uint len);
+
+#define MYSQL_SYS_VAR_HEADER    \
+  enum enum_mysql_sys_var type; \
+  uint flags;                   \
+  const char *name;             \
+  const char *comment;          \
+  sys_var_notify_func notify_func;
+  
+#define PLUGIN_VAR_ARGMASK 3
+#define PLUGIN_VAR_NOARG 1
+#define PLUGIN_VAR_OPTARG 2
+#define PLUGIN_VAR_REQARG 3
+#define PLUGIN_VAR_CMDLINEMASK 12
+#define PLUGIN_VAR_NOCMDLINE 4
+#define PLUGIN_VAR_NOSYSVAR 8
+#define PLUGIN_VAR_READONLY 16
+#define PLUGIN_VAR_STRALLOC 32
+
+struct st_mysql_sys_var {
+  MYSQL_SYS_VAR_HEADER
+};
+
+void* mysql_sys_var_ptr(void* thd, int offset);
+
+typedef char* charp;
+#define THDVAR(thd,var,type) \
+(*(type*)mysql_sys_var_ptr((thd),(var).offset_ ## type))
+
+struct st_mysql_sys_var_int {
+  MYSQL_SYS_VAR_HEADER
+  uint *value;
+  ulong default_value, min_value, max_value, block_size;
+};
+
+struct st_mysql_sys_var_long {
+  MYSQL_SYS_VAR_HEADER
+  ulong *value;
+  ulong default_value, min_value, max_value, block_size;
+};
+
+struct st_mysql_sys_var_longlong {
+  MYSQL_SYS_VAR_HEADER
+  ulonglong *value;
+  ulonglong default_value, min_value, max_value, block_size;
+};
+
+struct st_mysql_sys_var_bool {
+  MYSQL_SYS_VAR_HEADER
+  char *value;
+  char default_value;
+};
+
+struct st_mysql_sys_var_str {
+  MYSQL_SYS_VAR_HEADER
+  sys_var_update_func update_func;
+  char **value;
+  char *default_value;
+};
+
+#ifdef _typelib_h
+struct st_mysql_sys_var_enum {
+  MYSQL_SYS_VAR_HEADER
+  ulong *value;
+  ulong default_value;
+  TYPELIB *enum_names;
+};
+
+struct st_mysql_sys_var_set {
+  MYSQL_SYS_VAR_HEADER
+  ulong *value;
+  ulong default_value;
+  TYPELIB *set_names;
+};
+#endif
+
+struct st_mysql_thd_var_int {
+  MYSQL_SYS_VAR_HEADER
+  int offset_uint;
+  uint default_value, min_value, max_value, block_size;
+};
+
+struct st_mysql_thd_var_long {
+  MYSQL_SYS_VAR_HEADER
+  int offset_ulong;
+  ulong default_value, min_value, max_value, block_size;
+};
+
+
+struct st_mysql_thd_var_longlong {
+  MYSQL_SYS_VAR_HEADER
+  int offset_ulonglong;
+  ulonglong default_value, min_value, max_value, block_size;
+};
+
+struct st_mysql_thd_var_bool {
+  MYSQL_SYS_VAR_HEADER
+  int offset_my_bool;
+  char default_value;
+};
+
+struct st_mysql_thd_var_str {
+  MYSQL_SYS_VAR_HEADER
+  sys_var_update_func update_func;
+  int offset_charp;
+  char *default_value;
+};
+
+#ifdef _typelib_h
+struct st_mysql_thd_var_enum {
+  MYSQL_SYS_VAR_HEADER
+  int offset_ulong;
+  ulong default_value;
+  TYPELIB *enum_names;
+};
+
+struct st_mysql_thd_var_set {
+  MYSQL_SYS_VAR_HEADER
+  int offset_ulong;
+  ulong default_value;
+  TYPELIB *set_names;
+};
+#endif
+
+
+
+
 /*
   Plugin description structure.
 */
@@ -103,7 +292,7 @@
   int (*deinit)(void *);/* the function to invoke when plugin is unloaded */
   unsigned int version; /* plugin version (for SHOW PLUGINS)            */
   struct st_mysql_show_var *status_vars;
-  void * __reserved1;   /* placeholder for system variables             */
+  struct st_mysql_sys_var **system_vars;
   void * __reserved2;   /* placeholder for config options               */
 };
 

--- 1.39/sql/sql_plugin.cc	2006-12-05 11:05:29 -08:00
+++ 1.40/sql/sql_plugin.cc	2006-12-05 11:05:29 -08:00
@@ -78,11 +78,1418 @@
 
 static int plugin_array_version=0;
 
+static MEM_ROOT plugin_mem_root;
+static HASH plugin_var_hash;
+
+struct st_plugin_var /* stored in plugin_var_hash */
+{
+  char *name;
+  uint name_len;
+  int offset;
+};
+
 /* prototypes */
 my_bool plugin_register_builtin(struct st_mysql_plugin *plugin);
-void plugin_load(void);
+static void plugin_load(char **);
+static int test_plugin_options(struct st_plugin_int &tmp,
+			       char **argv, my_bool default_enabled);
 static my_bool register_builtin(struct st_mysql_plugin *plugin, 
-				struct st_plugin_int **ptr);
+				struct st_plugin_int &tmp,
+				struct st_plugin_int *&ptr);
+static st_plugin_var *register_var(const char *plugin, const char *name,
+				   enum enum_mysql_sys_var type);
+static st_plugin_var *find_var(const char *plugin, const char *name,
+			       enum enum_mysql_sys_var type);
+
+
+
+/****************************************************************************
+  Help Verbose text with Plugin System Variables
+****************************************************************************/
+
+static int option_cmp(my_option *a, my_option *b)
+{
+  if (a->id < 256 && b->id >= 256)
+    return -1;
+  if (a->id >= 256 && b->id < 256)
+    return 1;
+  if (a->id < 256 && b->id < 256)
+    return a->id - b->id;
+  return my_strcasecmp(&my_charset_latin1, a->name, b->name);
+}
+
+
+void plugin_print_help(my_option *main_options, uint size)
+{
+  DYNAMIC_ARRAY all_options;
+  struct st_plugin_int *p;
+  my_option *opt;
+
+  my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
+  
+  for (uint idx= 0; initialized && idx < plugin_array.elements; idx++)
+  {
+    p= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+    if (!(opt= p->cmd_options))
+      continue;
+    
+    for (;opt->id; opt++)
+      if (opt->comment)
+        insert_dynamic(&all_options, (gptr) opt);
+  }
+  
+  for (;main_options->id; main_options++)
+    insert_dynamic(&all_options, (gptr) main_options);
+  
+  sort_dynamic(&all_options, (qsort_cmp)option_cmp);
+  insert_dynamic(&all_options, (gptr) main_options);
+  my_print_help((my_option*) all_options.buffer);
+  my_print_variables((my_option*) all_options.buffer);
+  delete_dynamic(&all_options);
+}
+
+/****************************************************************************
+  Plugin System Variables
+****************************************************************************/
+
+/* A helpful union for dealing with plugin system variables */
+union un_mysql_sys_var {
+  struct st_mysql_sys_var hdr;
+  struct st_mysql_sys_var_int si;
+  struct st_mysql_sys_var_long sl;
+  struct st_mysql_sys_var_longlong sll;
+  struct st_mysql_sys_var_bool sb;
+  struct st_mysql_sys_var_str ss;
+  struct st_mysql_sys_var_enum se;
+  struct st_mysql_sys_var_set st;
+  struct st_mysql_thd_var_int ti;
+  struct st_mysql_thd_var_long tl;
+  struct st_mysql_thd_var_longlong tll;
+  struct st_mysql_thd_var_bool tb;
+  struct st_mysql_thd_var_str ts;
+  struct st_mysql_thd_var_enum te;
+  struct st_mysql_thd_var_set tt;
+};
+
+class sys_var_pluginvar: public sys_var
+{
+public:
+  static void *operator new(size_t size, MEM_ROOT *mem_root)
+  { return (void*) alloc_root(mem_root, (uint) size); }
+  static void operator delete(void *ptr_arg,size_t size)
+  { TRASH(ptr_arg, size); }
+  
+  const st_mysql_sys_var *plugin_opt;
+  sys_var_pluginvar(sys_var_chain &chain, const char *name_arg,
+		   st_mysql_sys_var *plugin_opt_arg)
+    :sys_var(chain, name_arg), plugin_opt(plugin_opt_arg)
+  {}
+  bool update(THD *thd, set_var *var);
+  bool check(THD *thd, set_var *var);
+  bool check_type(enum_var_type type);
+  bool check_default(enum_var_type type)
+  { return is_readonly(); }
+  void set_default(THD *thd, enum_var_type type);
+  bool check_update_type(Item_result type);
+  byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+  SHOW_TYPE type();
+  bool is_readonly() const;
+  sys_var_pluginvar *cast_pluginvar() { return this; }
+};
+
+
+static st_plugin_var *register_var(const char *plugin, const char *name,
+				   enum enum_mysql_sys_var type)
+
+{
+  uint length= strlen(plugin) + strlen(name) + 3, size, offset;
+  st_plugin_var *result;
+  
+  switch (type) {
+  case MYSQL_SYS_VAR_BOOL:
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+  case MYSQL_SYS_VAR_STR:
+  case MYSQL_SYS_VAR_ENUM:
+  case MYSQL_SYS_VAR_SET:
+    size= 0;
+    break;
+  case MYSQL_THD_VAR_BOOL:
+    size= sizeof(my_bool);
+    break;
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+    size= sizeof(uint);
+    break;
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+  case MYSQL_THD_VAR_ENUM:
+  case MYSQL_THD_VAR_SET:
+    size= sizeof(ulong);
+    break;
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    size= sizeof(ulonglong);
+    break;
+  case MYSQL_THD_VAR_STR:
+    size= sizeof(char*);
+    break;
+  default:
+    return NULL;
+  };
+
+  char *varname= ((char*) my_alloca(length));
+  strxmov(varname + 1, plugin, "_", name, NullS);
+  for (char *p= varname + 1; *p; p++)
+    if (*p == '-')
+      *p= '_';
+
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  if (!(result= find_var(NULL, varname + 1, type)))
+  {
+    result= (st_plugin_var*) alloc_root(&plugin_mem_root, 
+    					sizeof(struct st_plugin_var) + length);
+    varname[0]= type;
+    result->name= (char *) memcpy(&result[1], varname, length);
+    result->name_len= length;
+    result->offset= -1;
+    if (size)
+    {
+      offset= global_system_variables.dynamic_variables_size;
+      offset= (offset + size - 1) & ~(size - 1);
+      result->offset= (int) offset;
+      uint new_size= (offset + size + 63) & ~63;
+
+      global_system_variables.dynamic_variables_ptr=
+	my_realloc(global_system_variables.dynamic_variables_ptr, new_size,
+		   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
+      max_system_variables.dynamic_variables_ptr=
+	my_realloc(max_system_variables.dynamic_variables_ptr, new_size,
+		   MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
+      global_system_variables.dynamic_variables_size= offset + size;
+      max_system_variables.dynamic_variables_size= offset + size;
+      global_system_variables.dynamic_variables_version++;
+      max_system_variables.dynamic_variables_version++;
+    }
+    my_hash_insert(&plugin_var_hash, (byte*) result);
+  }
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+  my_afree(varname);
+  return result;
+}
+
+static st_plugin_var *find_var(const char *plugin, const char *name,
+			       enum enum_mysql_sys_var type)
+{
+  st_plugin_var *result= NULL;
+  uint namelen= strlen(name), pluginlen= plugin ? strlen(plugin) + 1: 0;
+  uint length= namelen + pluginlen + 2;
+  char* varname= (char*) my_alloca(length);
+  if (plugin)
+    strxmov(varname + 1, plugin, "_", name, NullS);
+  else
+    memcpy(varname + 1, name, namelen + 1);
+
+  for (char* p= varname + 1; *p; p++)
+    if (*p == '-')
+      *p= '_';
+
+  varname[0]= (char) type;
+  
+  if (plugin)
+    pthread_mutex_lock(&LOCK_global_system_variables);
+  result= (st_plugin_var*) hash_search(&plugin_var_hash, 
+  				       (const byte*)varname, length);
+  if (plugin)
+    pthread_mutex_unlock(&LOCK_global_system_variables);
+
+  my_afree(varname);
+  return result;
+}
+
+void* mysql_sys_var_ptr(void* a_thd, int offset)
+{
+  THD *thd= (THD*) a_thd;
+  
+  DBUG_ASSERT(offset >= 0);
+  DBUG_ASSERT((uint)offset < global_system_variables.dynamic_variables_size);
+  
+  if ((uint)offset >= thd->variables.dynamic_variables_size ||
+      !thd->variables.dynamic_variables_ptr)
+  {
+    rw_wrlock(&THR_LOCK_plugin);
+    
+    thd->variables.dynamic_variables_ptr=
+      my_realloc(thd->variables.dynamic_variables_ptr,
+	         global_system_variables.dynamic_variables_size,
+		 MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
+
+    memcpy(thd->variables.dynamic_variables_ptr + 
+           thd->variables.dynamic_variables_size,
+	   global_system_variables.dynamic_variables_ptr +
+           thd->variables.dynamic_variables_size,
+	   global_system_variables.dynamic_variables_size -
+	   thd->variables.dynamic_variables_size);
+	   
+    /*
+      now we need to iterate through any newly copied 'defaults'
+      and if it is a string type with STRALLOC flag, we need to strdup
+    */
+    for (uint idx= 0; idx < plugin_var_hash.records; idx++)
+    {
+      st_plugin_var *v= (st_plugin_var*)hash_element(&plugin_var_hash,idx);
+      if (v->offset < (int) thd->variables.dynamic_variables_size)
+        continue;
+      sys_var *var= find_sys_var(v->name + 1, /*v->name_len - 1*/ 0);
+      sys_var_pluginvar *pivar;
+      if (!var || !(pivar= var->cast_pluginvar()) || 
+          v->name[0] != (char) pivar->plugin_opt->type)
+        continue;
+	
+      union un_mysql_sys_var &pi= *(union un_mysql_sys_var *) pivar->plugin_opt;
+
+      switch (pi.hdr.type) {
+      case MYSQL_THD_VAR_STR:
+        if (pi.hdr.flags & PLUGIN_VAR_STRALLOC)
+	{
+	  char** value=(char**) (thd->variables.dynamic_variables_ptr + 
+                                 pi.ts.offset_charp);
+	  if (*value)
+	    *value= my_strdup(*value, MYF(MY_WME|MY_FAE));
+	}
+	break;
+      default:
+        break;
+      }
+    }       
+
+    thd->variables.dynamic_variables_version= 
+	   global_system_variables.dynamic_variables_version;
+    thd->variables.dynamic_variables_size= 
+	   global_system_variables.dynamic_variables_size;
+	   
+    rw_unlock(&THR_LOCK_plugin);
+  }
+  return thd->variables.dynamic_variables_ptr + offset;
+}
+
+
+void mysql_pluginvar_cleanup(THD *thd)
+{
+  
+  for (uint idx= 0; idx < plugin_var_hash.records; idx++)
+  {
+    st_plugin_var *v= (st_plugin_var*)hash_element(&plugin_var_hash,idx);
+    if (v->offset < 0 || 
+        v->offset >= (int) thd->variables.dynamic_variables_size)
+      continue;
+    sys_var *var= find_sys_var(v->name + 1, /* v->name_len - 1 */ 0);
+    sys_var_pluginvar *pivar;
+    if (!var || !(pivar= var->cast_pluginvar()) || 
+        v->name[0] != (char) pivar->plugin_opt->type)
+      continue;
+
+    un_mysql_sys_var &pi= *(union un_mysql_sys_var *)pivar->plugin_opt;
+
+    switch (pi.hdr.type) {
+    case MYSQL_THD_VAR_STR:
+      if (pi.hdr.flags & PLUGIN_VAR_STRALLOC)
+      {
+	char** value=(char**) (thd->variables.dynamic_variables_ptr + 
+                               pi.ts.offset_charp);
+	my_free(*value, MYF(MY_WME|MY_FAE));
+      }
+      break;
+    default:
+      break;
+    }
+    DBUG_ASSERT(v);
+    DBUG_ASSERT(var);
+  }       
+  my_free(thd->variables.dynamic_variables_ptr, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+
+static void plugin_opt_set_limits(struct my_option *options,
+			   const struct st_mysql_sys_var *opt)
+{
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)opt;
+
+  switch (opt->type) {
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+    options->var_type= opt->type == MYSQL_SYS_VAR_INT ? GET_INT : GET_UINT;
+    options->arg_type= REQUIRED_ARG;
+    options->value= options->u_max_value= (gptr*) pi.si.value;
+    options->def_value= pi.si.default_value;
+    options->min_value= pi.si.min_value;
+    options->max_value= pi.si.max_value;
+    options->block_size= pi.si.block_size;
+    break;
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+    options->var_type= opt->type == MYSQL_SYS_VAR_LONG ? GET_LONG : GET_ULONG;
+    options->arg_type= REQUIRED_ARG;
+    options->value= options->u_max_value= (gptr*) pi.sl.value;
+    options->def_value= pi.sl.default_value;
+    options->min_value= pi.sl.min_value;
+    options->max_value= pi.sl.max_value;
+    options->block_size= pi.sl.block_size;
+    break;
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+    options->var_type= opt->type == MYSQL_SYS_VAR_LONGLONG ? GET_LL : GET_ULL;
+    options->arg_type= REQUIRED_ARG;
+    options->value= options->u_max_value= (gptr*) pi.sll.value;
+    options->def_value= pi.sll.default_value;
+    options->min_value= pi.sll.min_value;
+    options->max_value= pi.sll.max_value;
+    options->block_size= pi.sll.block_size;
+    break;
+  case MYSQL_SYS_VAR_BOOL:
+    options->var_type= GET_BOOL;
+    options->arg_type= REQUIRED_ARG;
+    options->value= options->u_max_value= (gptr*) pi.sb.value;
+    options->def_value= pi.sb.default_value ? 1 : 0;
+    break;
+  case MYSQL_SYS_VAR_STR:
+    options->var_type= (opt->flags & PLUGIN_VAR_STRALLOC) ?
+      		      GET_STR_ALLOC :GET_STR;
+    options->arg_type= REQUIRED_ARG;
+    options->value= options->u_max_value= (gptr*) pi.ss.value;
+    *pi.ss.value= pi.ss.default_value;
+    if (opt->flags & PLUGIN_VAR_STRALLOC && *pi.ss.value)
+      *pi.ss.value= my_strdup(*pi.ss.value, MYF(MY_WME|MY_FAE));
+    break;
+  case MYSQL_SYS_VAR_ENUM:
+  case MYSQL_SYS_VAR_SET:
+    options->var_type= GET_STR;
+    options->arg_type= REQUIRED_ARG;
+    break;
+
+
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+    options->var_type= opt->type == MYSQL_THD_VAR_INT ? GET_INT : GET_UINT;
+    options->arg_type= REQUIRED_ARG;
+    options->value= (gptr*)(global_system_variables.dynamic_variables_ptr + 
+                            pi.ti.offset_uint);
+    options->u_max_value= (gptr*)(max_system_variables.dynamic_variables_ptr + 
+                                  pi.ti.offset_uint);
+    options->def_value= pi.ti.default_value;
+    options->min_value= pi.ti.min_value;
+    options->max_value= pi.ti.max_value;
+    options->block_size= pi.ti.block_size;
+    break;
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+    options->var_type= opt->type == MYSQL_THD_VAR_LONG ? GET_LONG : GET_ULONG;
+    options->arg_type= REQUIRED_ARG;
+    options->value= (gptr*)(global_system_variables.dynamic_variables_ptr + 
+                            pi.tl.offset_ulong);
+    options->u_max_value= (gptr*)(max_system_variables.dynamic_variables_ptr + 
+                                  pi.tl.offset_ulong);
+    options->def_value= pi.tl.default_value;
+    options->min_value= pi.tl.min_value;
+    options->max_value= pi.tl.max_value;
+    options->block_size= pi.tl.block_size;
+    break;
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    options->var_type= opt->type == MYSQL_THD_VAR_LONGLONG ? GET_LL : GET_ULL;
+    options->arg_type= REQUIRED_ARG;
+    options->value= (gptr*)(global_system_variables.dynamic_variables_ptr + pi.tll.offset_ulonglong);
+    options->u_max_value= (gptr*)(max_system_variables.dynamic_variables_ptr + pi.tll.offset_ulonglong);
+    options->def_value= pi.tll.default_value;
+    options->min_value= pi.tll.min_value;
+    options->max_value= pi.tll.max_value;
+    options->block_size= pi.tll.block_size;
+    break;
+  case MYSQL_THD_VAR_BOOL:
+    options->var_type= GET_BOOL;
+    options->arg_type= REQUIRED_ARG;
+    options->value= (gptr*)(global_system_variables.dynamic_variables_ptr + pi.tb.offset_my_bool);
+    options->u_max_value= (gptr*)(max_system_variables.dynamic_variables_ptr + pi.tb.offset_my_bool);
+    options->def_value= pi.tb.default_value ? 1 : 0;
+    break;
+  case MYSQL_THD_VAR_STR:
+    options->var_type= (opt->flags & PLUGIN_VAR_STRALLOC) ?
+      		      GET_STR_ALLOC :GET_STR;
+    options->arg_type= REQUIRED_ARG;
+    options->value= 
+    options->u_max_value= (gptr*)(global_system_variables.dynamic_variables_ptr + 
+                                  pi.ts.offset_charp);
+    *(options->value)= (gptr) pi.ts.default_value;
+    if (opt->flags & PLUGIN_VAR_STRALLOC)
+      *(options->value)= my_strdup(*(options->value), MYF(MY_WME|MY_FAE));
+    break;
+  case MYSQL_THD_VAR_ENUM:
+    options->var_type= GET_STR;
+    options->arg_type= REQUIRED_ARG;
+    options->def_value= pi.te.default_value;
+    break;
+  case MYSQL_THD_VAR_SET:
+    options->var_type= GET_STR;
+    options->arg_type= REQUIRED_ARG;
+    options->def_value= pi.tt.default_value;
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+}
+
+
+bool sys_var_pluginvar::check_type(enum_var_type type)
+{
+  if (plugin_opt->type < MYSQL_SYS_VAR_BOOL ||
+      plugin_opt->type > MYSQL_THD_VAR_SET)
+    return 1;
+    
+  if (type == OPT_SESSION &&
+      plugin_opt->type >= MYSQL_THD_VAR_BOOL)
+    return 0;
+
+  return type != OPT_GLOBAL;
+}
+
+
+byte *sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
+{
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)plugin_opt;
+  
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+    return (byte*) pi.sb.value;
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+    return (byte*) pi.si.value;
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+    return (byte*) pi.sl.value;
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+    return (byte*) pi.sll.value;
+  case MYSQL_SYS_VAR_STR:
+    return (byte*) pi.ss.value;
+  case MYSQL_SYS_VAR_ENUM:
+    return (byte*)(*pi.se.value < pi.se.enum_names->count ? 
+    		   pi.se.enum_names->type_names[*pi.se.value] :
+		   "undefined");
+  case MYSQL_SYS_VAR_SET:
+  {
+    char buffer[1000];
+    String str(buffer, sizeof(buffer), system_charset_info);
+    ulonglong value= *pi.st.value;
+
+    str.length(0);
+    for (uint i= 0; i < pi.st.set_names->count; i++)
+    {
+      if (!(value & (((ulonglong)1) << i)))
+        continue;
+      str.append(pi.st.set_names->type_names[i], 
+                 pi.st.set_names->type_lengths[i]);
+      str.append(',');
+    }
+    if (str.length())
+      str.length(str.length()-1);
+    return thd->strmake(str.c_ptr_quick(), str.length());
+  }
+  case MYSQL_THD_VAR_BOOL:
+    if (type == OPT_GLOBAL)
+      return (byte*) global_system_variables.dynamic_variables_ptr + 
+      		     pi.tb.offset_my_bool;
+    return (byte*) &THDVAR(thd, pi.tb, my_bool);
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+    if (type == OPT_GLOBAL)
+      return (byte*) global_system_variables.dynamic_variables_ptr + 
+                     pi.ti.offset_uint;
+    return (byte*) &THDVAR(thd, pi.ti, uint);
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+    if (type == OPT_GLOBAL)
+      return (byte*) global_system_variables.dynamic_variables_ptr + 
+                     pi.tl.offset_ulong;
+    return (byte*) &THDVAR(thd, pi.tl, ulong);
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    if (type == OPT_GLOBAL)
+      return (byte*) global_system_variables.dynamic_variables_ptr + 
+                     pi.tll.offset_ulonglong;
+    return (byte*) &THDVAR(thd, pi.tll, ulonglong);
+  case MYSQL_THD_VAR_STR:
+    if (type == OPT_GLOBAL)
+      return (byte*) global_system_variables.dynamic_variables_ptr + 
+                     pi.ts.offset_charp;
+    return (byte*) &THDVAR(thd, pi.ts, charp);
+  case MYSQL_THD_VAR_ENUM:
+  {
+    ulong value;
+    if (type == OPT_GLOBAL)
+      value= *(uint*) (global_system_variables.dynamic_variables_ptr + 
+                       pi.te.offset_ulong);
+    else
+      value= THDVAR(thd, pi.te, ulong);
+    return (byte*) ((value > 0 && value <= pi.te.enum_names->count) ? 
+                    pi.te.enum_names->type_names[value] : "undefined");
+  }
+  case MYSQL_THD_VAR_SET:
+  {
+    char buffer[1000];
+    String str(buffer, sizeof(buffer), system_charset_info);
+    ulong value;
+
+    if (type == OPT_GLOBAL)
+      value= *(ulonglong*) (global_system_variables.dynamic_variables_ptr + 
+                            pi.tt.offset_ulong);
+    else
+      value= THDVAR(thd, pi.tt, ulong);
+
+    str.length(0);
+    for (uint i= 0; i < pi.tt.set_names->count; i++)
+    {
+      if (!(value & (((ulonglong)1) << i)))
+        continue;
+      str.append(pi.tt.set_names->type_names[i], 
+                 pi.tt.set_names->type_lengths[i]);
+      str.append(',');
+    }
+    if (str.length())
+      str.length(str.length()-1);
+    return thd->strmake(str.c_ptr_quick(), str.length());
+  }
+  default:
+    DBUG_ASSERT(0);
+    return NULL;
+  }  
+}
+
+
+bool sys_var_pluginvar::check_update_type(Item_result type)
+{
+  if (is_readonly())
+    return 1; 
+
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+  case MYSQL_THD_VAR_BOOL:
+  case MYSQL_SYS_VAR_ENUM:
+  case MYSQL_THD_VAR_ENUM:
+  case MYSQL_SYS_VAR_SET:
+  case MYSQL_THD_VAR_SET:
+    return 0;
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    return type != INT_RESULT;
+  case MYSQL_SYS_VAR_STR:
+  case MYSQL_THD_VAR_STR:
+    return type != STRING_RESULT;
+  default:
+    return 1;
+  }
+}
+
+SHOW_TYPE sys_var_pluginvar::type()
+{
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+  case MYSQL_THD_VAR_BOOL:
+    return SHOW_BOOL;
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+    return SHOW_INT;
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+    return SHOW_LONG;
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    return SHOW_LONGLONG;
+  case MYSQL_SYS_VAR_STR:
+  case MYSQL_THD_VAR_STR:
+    return SHOW_CHAR_PTR;
+  case MYSQL_SYS_VAR_ENUM:
+  case MYSQL_THD_VAR_ENUM:
+  case MYSQL_SYS_VAR_SET:
+  case MYSQL_THD_VAR_SET:
+    return SHOW_CHAR;
+  default:
+    return SHOW_UNDEF;    
+  }
+}
+
+bool sys_var_pluginvar::check(THD *thd, set_var *var)
+{
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)plugin_opt;
+
+  if (is_readonly())
+    return 1; 
+
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+  case MYSQL_THD_VAR_BOOL:
+    return check_enum(thd, var, &bool_typelib);
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    var->save_result.ulonglong_value= var->value->val_int();
+    return 0;
+  case MYSQL_SYS_VAR_STR:
+  case MYSQL_THD_VAR_STR:
+    /** XXX plugin may need string checking */
+    return 0;
+  case MYSQL_SYS_VAR_ENUM:
+    return check_enum(thd, var, 
+                      ((struct st_mysql_sys_var_enum *)plugin_opt)->enum_names);
+  case MYSQL_THD_VAR_ENUM:
+    return check_enum(thd, var, 
+                      ((struct st_mysql_thd_var_enum *)plugin_opt)->enum_names);
+  case MYSQL_SYS_VAR_SET:
+    return check_set(thd, var, 
+                     ((struct st_mysql_sys_var_set *)plugin_opt)->set_names);
+  case MYSQL_THD_VAR_SET:
+    return check_set(thd, var, 
+                     ((struct st_mysql_thd_var_set *)plugin_opt)->set_names);
+  default:
+    return 1;
+  }
+}
+
+bool sys_var_pluginvar::is_readonly() const
+{
+  return plugin_opt->flags & PLUGIN_VAR_READONLY;
+}
+
+void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
+{
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)plugin_opt;
+
+  rw_wrlock(&THR_LOCK_plugin);
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+    *pi.sb.value= pi.sb.default_value;
+    break;
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+    *pi.si.value= pi.si.default_value;
+    break;
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+    *pi.sl.value= pi.sl.default_value;
+    break;
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+    *pi.sll.value= pi.sll.default_value;
+    break;
+  case MYSQL_SYS_VAR_STR:
+  {
+    char* old_value= *pi.ss.value;
+    if (plugin_opt->flags & PLUGIN_VAR_STRALLOC)
+    {
+      if (pi.ss.default_value)
+        *pi.ss.value= my_strdup(pi.ss.default_value, MYF(MY_WME));
+      else
+        *pi.ss.value= 0;
+      my_free(old_value, MYF(MY_WME | MY_FAE));
+    }
+    else
+      *pi.ss.value= pi.ss.default_value;
+    break;
+  }    
+  case MYSQL_SYS_VAR_ENUM:
+    *pi.se.value= pi.se.default_value;
+    break;
+  case MYSQL_SYS_VAR_SET:
+    *pi.st.value= pi.st.default_value;
+    break;
+  case MYSQL_THD_VAR_BOOL:
+  {
+    my_bool *value= (my_bool*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(my_bool*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.tb.default_value;
+    break;
+  }
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+  {
+    uint *value= (uint*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(uint*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.ti.default_value;
+    break;
+  }
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+  {
+    ulong *value= (ulong*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(ulong*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.tl.default_value;
+    break;
+  }
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+  {
+    ulonglong *value= (ulonglong*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(ulonglong*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.tll.default_value;
+    break;
+  }
+  case MYSQL_THD_VAR_STR:
+  {
+    char **value= (char**) value_ptr(thd, type, NULL);
+    char *old_value= *value;
+    if (type != OPT_GLOBAL)
+      *value= *(char**) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.ss.default_value;
+    if (pi.ss.flags & PLUGIN_VAR_STRALLOC)
+    {
+      *value= my_strdup(*value, MYF(MY_WME | MY_FAE));
+      my_free(old_value, MYF(MY_WME | MY_FAE));
+    }  
+    break;
+  }
+  case MYSQL_THD_VAR_ENUM:
+  {
+    ulong *value= (ulong*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(ulong*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.te.default_value;
+    break;
+  }
+  case MYSQL_THD_VAR_SET:
+  {
+    ulong *value= (ulong*) value_ptr(thd, type, NULL);
+    if (type != OPT_GLOBAL)
+      *value= *(ulong*) value_ptr(thd, OPT_GLOBAL, NULL);
+    else
+      *value= pi.tt.default_value;
+    break;
+  }
+  default:
+    DBUG_ASSERT(0);
+  }
+  rw_unlock(&THR_LOCK_plugin);
+}
+
+bool sys_var_pluginvar::update(THD *thd, set_var *var)
+{
+  LEX_STRING null_lex_str= {NULL, 0};
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)plugin_opt;
+
+  if (is_readonly())
+    return 1; 
+
+  switch (plugin_opt->type) {
+  case MYSQL_SYS_VAR_BOOL:
+  case MYSQL_THD_VAR_BOOL:
+    rw_wrlock(&THR_LOCK_plugin);
+    *((my_bool*)value_ptr(thd, var->type, &null_lex_str))=
+      var->save_result.ulong_value ? 1 : 0;
+    rw_unlock(&THR_LOCK_plugin);
+    return 0;
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+  case MYSQL_THD_VAR_UINT:
+  {
+    uint *value= (uint*) value_ptr(thd, var->type, &null_lex_str);
+    ulonglong tmp= var->save_result.ulonglong_value;
+    rw_wrlock(&THR_LOCK_plugin);
+    if (option_limits)
+      *value= (uint) getopt_ull_limit_value(tmp, option_limits);
+    else
+    {
+      struct my_option limits;
+      plugin_opt_set_limits(&limits, plugin_opt);
+      *value= (uint) getopt_ull_limit_value(tmp, &limits);
+    }
+    rw_unlock(&THR_LOCK_plugin);
+    return 0;
+  }
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+  {
+    ulong *value= (ulong*) value_ptr(thd, var->type, &null_lex_str);
+    ulonglong tmp= var->save_result.ulonglong_value;
+    rw_wrlock(&THR_LOCK_plugin);
+    if (option_limits)
+      *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
+    else
+    {
+      struct my_option limits;
+      plugin_opt_set_limits(&limits, plugin_opt);
+      *value= (ulong) getopt_ull_limit_value(tmp, &limits);
+    }
+    rw_unlock(&THR_LOCK_plugin);
+    return 0;
+  }
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+  {
+    ulonglong *value= (ulonglong*) value_ptr(thd, var->type, &null_lex_str);
+    ulonglong tmp= var->save_result.ulonglong_value;
+    rw_wrlock(&THR_LOCK_plugin);
+    if (option_limits)
+      *value= getopt_ull_limit_value(tmp, option_limits);
+    else
+    {
+      struct my_option limits;
+      plugin_opt_set_limits(&limits, plugin_opt);
+      *value= getopt_ull_limit_value(tmp, &limits);
+    }
+    rw_unlock(&THR_LOCK_plugin);
+    return 0;
+  }
+  case MYSQL_SYS_VAR_STR:
+  case MYSQL_THD_VAR_STR:
+  {
+    char **value= (char**) value_ptr(thd, var->type, &null_lex_str);
+    sys_var_update_func update_func= plugin_opt->type == MYSQL_THD_VAR_STR ?
+                                     pi.ts.update_func : pi.ss.update_func;
+    char buff[STRING_BUFFER_USUAL_SIZE];
+    String str(buff, sizeof(buff), system_charset_info), *res;
+    bool result= 1;
+
+    if (!(res= var->value->val_str(&str)))
+      return 1;
+
+    rw_wrlock(&THR_LOCK_plugin);
+    if (plugin_opt->flags & PLUGIN_VAR_STRALLOC)
+    {
+      char *old_value= *value, *new_value= my_strndup(res->c_ptr_quick(),
+                                              res->length(), MYF(MY_WME));
+      if (new_value && 
+          (!update_func || 
+           !update_func(thd, plugin_opt, new_value, res->length())))
+      {
+        DBUG_ASSERT(old_value == *value || new_value == *value);
+        *value= new_value;
+        result= 0;
+      }
+    }
+    else
+    if (update_func &&
+        !update_func(thd, plugin_opt, res->c_ptr(), res->length()))
+      result= 0;
+    
+    rw_unlock(&THR_LOCK_plugin);
+    return result;
+  }
+  case MYSQL_SYS_VAR_ENUM:
+  case MYSQL_THD_VAR_ENUM:
+  {
+    ulong *value;
+    if (plugin_opt->type == MYSQL_THD_VAR_ENUM)
+    {
+      struct st_mysql_thd_var_enum &sv= *(struct st_mysql_thd_var_enum *)plugin_opt;
+      value= (ulong*) global_system_variables.dynamic_variables_ptr + sv.offset_ulong;
+      if (var->type != OPT_GLOBAL)
+        value= &THDVAR(thd, sv, ulong);
+    }
+    else
+      value= ((struct st_mysql_sys_var_enum *)plugin_opt)->value;
+    rw_wrlock(&THR_LOCK_plugin);
+    *value= var->save_result.ulong_value;
+    rw_unlock(&THR_LOCK_plugin);
+    break;
+  }   
+  case MYSQL_SYS_VAR_SET:
+  case MYSQL_THD_VAR_SET:
+  {
+    ulong *value;
+    if (plugin_opt->type == MYSQL_THD_VAR_SET)
+    {
+      struct st_mysql_thd_var_set &sv= *(struct st_mysql_thd_var_set *)plugin_opt;
+      value= (ulong*) global_system_variables.dynamic_variables_ptr + sv.offset_ulong;
+      if (var->type != OPT_GLOBAL)
+        value= &THDVAR(thd, sv, ulong);
+    }
+    else
+      value= ((struct st_mysql_sys_var_set *)plugin_opt)->value;
+    rw_wrlock(&THR_LOCK_plugin);
+    *value= var->save_result.ulong_value;
+    rw_unlock(&THR_LOCK_plugin);
+    break;
+  }   
+  default:
+    return 1;
+  }
+
+  /*
+    if there is a notify func, only call it when a plugin accessible
+    value has changed. ie, don't call when modifying a global thd sys_var
+  */
+  if (plugin_opt->notify_func &&
+      (var->type != OPT_GLOBAL || plugin_opt->type < MYSQL_THD_VAR_BOOL))
+    plugin_opt->notify_func(thd, plugin_opt);
+  
+  return 0;
+}
+
+static my_bool get_one_option(int optid __attribute__((unused)),
+			const struct my_option *opt,
+	       		char *argument)
+{
+  if (!opt->app_type)
+    return 0;
+  
+  union un_mysql_sys_var &pi= *(union un_mysql_sys_var *)opt->app_type;
+  
+  switch (pi.hdr.type) {
+  case MYSQL_SYS_VAR_BOOL:
+    /* nothing to do */
+    break;
+
+  case MYSQL_SYS_VAR_INT:
+  case MYSQL_SYS_VAR_UINT:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      if (!argument)
+        (*pi.si.value)++;
+      else
+      if (argument == disabled_my_option)
+        *pi.si.value= 0;
+    }
+    break;
+    
+  case MYSQL_SYS_VAR_LONG:
+  case MYSQL_SYS_VAR_ULONG:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      if (!argument)
+        (*pi.sl.value)++;
+      else
+      if (argument == disabled_my_option)
+        *pi.sl.value= 0;
+    }
+    break;
+
+  case MYSQL_SYS_VAR_LONGLONG:
+  case MYSQL_SYS_VAR_ULONGLONG:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      if (!argument)
+        (*pi.sll.value)++;
+      else
+      if (argument == disabled_my_option)
+        *pi.sll.value= 0;
+    }
+    break;
+
+  case MYSQL_SYS_VAR_STR:
+    break;
+    
+  case MYSQL_SYS_VAR_ENUM:
+    {
+      int value= (int) pi.se.default_value;
+      if (argument == disabled_my_option)
+        value= 0;
+      else
+      if (argument && (value= find_type(argument, pi.se.enum_names, 2)) <= 0)
+        goto bad_opt;
+      *pi.se.value= value;
+    }
+    break;
+  
+  case MYSQL_SYS_VAR_SET:
+    {
+      ulong value= pi.st.default_value;
+      if (argument)
+      {
+        value= 0;
+	if (argument != disabled_my_option)
+	{
+	  char* error= 0;
+	  bool dummy;
+	  uint error_len= 0, arg_length= strlen(argument);
+	  value= (ulong) find_set(pi.st.set_names, argument, arg_length, NULL,
+	  			  &error, &error_len, &dummy);
+
+	  if (error_len)
+	    goto bad_opt;
+        }
+      }
+      *pi.st.value= value;
+    }
+
+  case MYSQL_THD_VAR_BOOL:
+    break;
+
+  case MYSQL_THD_VAR_INT:
+  case MYSQL_THD_VAR_UINT:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      uint *value= (uint*)
+        (global_system_variables.dynamic_variables_ptr + pi.ti.offset_uint);
+      if (!argument)
+        (*value)++;
+      else
+      if (argument == disabled_my_option)
+        *value= 0;
+    }
+    break;
+
+  case MYSQL_THD_VAR_LONG:
+  case MYSQL_THD_VAR_ULONG:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      ulong *value= (ulong*)
+        (global_system_variables.dynamic_variables_ptr + pi.tl.offset_ulong);
+      if (!argument)
+        (*value)++;
+      else
+      if (argument == disabled_my_option)
+        *value= 0;
+    }
+    break;
+
+  case MYSQL_THD_VAR_LONGLONG:
+  case MYSQL_THD_VAR_ULONGLONG:
+    if (pi.hdr.flags & PLUGIN_VAR_ARGMASK != PLUGIN_VAR_REQARG)
+    {
+      ulonglong *value= (ulonglong*)
+        (global_system_variables.dynamic_variables_ptr + pi.tll.offset_ulonglong);
+      if (!argument)
+        (*value)++;
+      else
+      if (argument == disabled_my_option)
+        *value= 0;
+    }
+    break;
+
+  case MYSQL_THD_VAR_STR:
+    break;
+   
+  case MYSQL_THD_VAR_ENUM:
+    {
+      int value= (int) pi.te.default_value;
+      if (argument == disabled_my_option)
+        value= 0;
+      else
+      if (argument && (value= find_type(argument, pi.te.enum_names, 2)-1) < 0)
+        goto bad_opt;
+      *(ulong*)(global_system_variables.dynamic_variables_ptr + 
+                pi.te.offset_ulong)= value;
+    }
+    break;
+
+  case MYSQL_THD_VAR_SET:
+    {
+      ulong value= pi.tt.default_value;
+      if (argument)
+      {
+        value= 0;
+	if (argument != disabled_my_option)
+	{
+	  char* error= 0;
+	  bool dummy;
+	  uint error_len= 0, arg_length= strlen(argument);
+	  value= (ulong) find_set(pi.tt.set_names, argument, arg_length, NULL,
+	  			  &error, &error_len, &dummy);
+
+	  if (error_len)
+	    goto bad_opt;
+        }
+      }
+      *(ulong*)(global_system_variables.dynamic_variables_ptr + 
+                pi.tt.offset_ulong)= value;
+    }
+  
+  default:
+    DBUG_ASSERT(0);
+    exit(1);
+  }
+  return 0;
+  
+bad_opt:
+  fprintf(stderr, "Unknown or bad option to %s: %s\n", opt->name, argument);
+  exit(1);
+}
+
+
+static int construct_options(MEM_ROOT *mem_root,
+			     struct st_plugin_int &tmp,
+			     my_option *options,
+			     my_bool **enabled, my_bool can_disable)
+{
+  const char *plugin_name= tmp.plugin->name;
+  uint namelen= strlen(plugin_name);
+  char *name= (char*) alloc_root(mem_root, namelen * 4 + (can_disable ? 75 : 10)) + 1;
+  int index= 0;
+  DBUG_ENTER("construct_options");
+    
+  /* support --skip-plugin-foo syntax */
+  memcpy(name, plugin_name, namelen + 1);
+  my_casedn_str(&my_charset_latin1, name);
+  strxmov(name + namelen + 1, "plugin-", name, NullS);
+  
+  for (char* p= name + namelen*2 + 8; p > name; p--)
+    if (*p == '_')
+      *p= '-';
+  
+  if (can_disable)
+  {
+    strxmov(name + namelen*2 + 10, "Enable ", plugin_name, " plugin. "
+            "Disable with --skip-plugin-", name," (will save memory).", NullS);
+
+    options[0].comment= name + namelen*2 + 10;
+  }
+
+  *((my_bool *)(name -1))= **enabled;
+  *enabled= (my_bool *)(name - 1);
+  
+  
+  options[1].name= (options[0].name= name) + namelen + 1;
+  options[0].id= options[1].id= 256;
+  options[0].var_type= options[1].var_type= GET_BOOL;
+  options[0].arg_type= options[1].arg_type= NO_ARG;
+  options[0].def_value= options[1].def_value= **enabled;
+  options[0].value= options[0].u_max_value=
+  options[1].value= options[1].u_max_value= (gptr*) (name - 1);
+  options+= 2;
+
+  for (st_mysql_sys_var **plugin_option= tmp.plugin->system_vars; 
+       plugin_option && *plugin_option; plugin_option++, index++)
+  {
+    st_mysql_sys_var *opt= *plugin_option;    
+    if ((opt->flags & PLUGIN_VAR_CMDLINEMASK) == PLUGIN_VAR_NOSYSVAR)
+      continue;
+    register_var(name, opt->name, opt->type);
+  }
+
+  for (st_mysql_sys_var **plugin_option= tmp.plugin->system_vars; 
+       plugin_option && *plugin_option; plugin_option++, index++)
+  {
+    st_mysql_sys_var *opt= *plugin_option;
+    st_plugin_var *v= NULL;
+    char *optname= NULL;
+    if (!opt->name)
+      DBUG_RETURN(-1);
+
+    if (!(v= find_var(name, opt->name, opt->type)))
+    {
+      if ((opt->flags & PLUGIN_VAR_CMDLINEMASK) != PLUGIN_VAR_NOCMDLINE)
+      {
+        uint optnamelen= strlen(opt->name);
+        optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
+        strxmov(optname, name, "-", opt->name, NullS);
+      }
+    }
+    else
+      optname= memdup_root(mem_root, v->name + 1, v->name_len - 1);
+
+    /* convert '_' to '-' */
+    for (char* p= optname; *p; p++)
+      if (*p == '_')
+	*p= '-';
+
+    options->name= optname;
+    options->comment= opt->comment;
+    options->app_type= (long) opt;
+    options->id= (options-1)->id + 1;
+
+    switch (opt->type) {
+    case MYSQL_THD_VAR_INT:
+    case MYSQL_THD_VAR_UINT:
+      ((st_mysql_thd_var_int *)opt)->offset_uint= v->offset;
+      break;
+    case MYSQL_THD_VAR_LONG:
+    case MYSQL_THD_VAR_ULONG:
+      ((st_mysql_thd_var_long *)opt)->offset_ulong= v->offset;
+      break;
+    case MYSQL_THD_VAR_LONGLONG:
+    case MYSQL_THD_VAR_ULONGLONG:
+      ((st_mysql_thd_var_longlong *)opt)->offset_ulonglong= v->offset;
+      break;
+    case MYSQL_THD_VAR_BOOL:
+      ((st_mysql_thd_var_bool *)opt)->offset_my_bool= v->offset;
+      break;
+    case MYSQL_THD_VAR_STR:
+      ((st_mysql_thd_var_str *)opt)->offset_charp= v->offset;
+      break;
+    case MYSQL_THD_VAR_ENUM:
+      ((st_mysql_thd_var_enum *)opt)->offset_ulong= v->offset;
+      break;
+    case MYSQL_THD_VAR_SET:
+      ((st_mysql_thd_var_set *)opt)->offset_ulong= v->offset;
+      break;
+    default:
+      break;
+    }
+
+    plugin_opt_set_limits(options, opt);
+
+    if ((opt->flags & PLUGIN_VAR_CMDLINEMASK) == PLUGIN_VAR_NOCMDLINE)
+      bzero(options, sizeof(*options));
+    else
+      options++;
+  }
+  DBUG_RETURN(0);
+}
+
+
+/*
+  SYNOPSIS
+    test_plugin_options()
+    plugin			internal plugin structure
+    argv			user supplied arguments
+    default_enabled		default plugin enable status
+  RETURNS:
+    0 SUCCESS - plugin should be enabled/loaded
+*/
+static int test_plugin_options(struct st_plugin_int &tmp,
+			       char **argv, my_bool default_enabled)
+{
+  my_bool enabled_saved= default_enabled, can_disable;
+  my_bool *enabled= &default_enabled;
+  MEM_ROOT *mem_root= alloc_root_inited(&tmp.mem_root) ? 
+  			&tmp.mem_root : &plugin_mem_root;
+  DBUG_ENTER("test_plugin_options");
+  DBUG_ASSERT(tmp.plugin && tmp.plugin->name);
+
+  uint count= 0;
+  for (st_mysql_sys_var **opt= tmp.plugin->system_vars; opt && *opt; 
+  	opt++, count++);
+
+  can_disable=
+      my_strcasecmp(&my_charset_latin1, tmp.plugin->name, "MyISAM") ||
+      my_strcasecmp(&my_charset_latin1, tmp.plugin->name, "MEMORY");
+  
+  if (count || (argv && *argv))
+  {  
+    my_option *opts;
+    if (!(opts= (my_option*) 
+          alloc_root(mem_root, sizeof(my_option) * (count + 3))))
+    {
+      sql_print_error("Out of memory for plugin '%s'.", tmp.plugin->name);
+      DBUG_RETURN(-1);
+    }
+    bzero(opts, sizeof(my_option) * (count + 3));
+    
+    if (construct_options(mem_root, tmp, opts, &enabled, can_disable))
+    {
+      sql_print_error("Bad options for plugin '%s'.", tmp.plugin->name);
+      DBUG_RETURN(-1);
+    }
+
+    int argc= 0;
+    for (char** p= argv; *p; p++, argc++);
+    
+    int ho_error= handle_options(&argc, &argv, opts, get_one_option);
+
+    my_afree(name1);
+
+    if (ho_error)
+    {
+       sql_print_error("Parsing options for plugin '%s' failed.", 
+       			tmp.plugin->name);
+       DBUG_RETURN(ho_error);
+    }
+    tmp.cmd_options= opts;
+  }
+
+  if (!*enabled && !can_disable)
+  {
+    sql_print_error("Plugin '%s' cannot be disabled", tmp.plugin->name);
+    *enabled= TRUE;
+  }
+
+  if (*enabled)
+  {
+    struct sys_var_chain chain= { NULL, NULL };
+    char buffer[1000];
+    
+    for (st_mysql_sys_var **opt= tmp.plugin->system_vars; opt && *opt; opt++)
+    {
+      st_mysql_sys_var *o= *opt;
+      sys_var *v;
+
+      if ((o->flags & PLUGIN_VAR_NOSYSVAR))
+        continue;
+      
+      struct st_plugin_var *var= find_var(tmp.plugin->name, o->name, o->type);
+      if (var)
+        v= new (mem_root) sys_var_pluginvar(chain, var->name + 1, o);
+      else
+      {
+        uint len= strlen(tmp.plugin->name) + strlen(o->name) + 2;
+	char *varname= (char*) alloc_root(mem_root, len);
+	strxmov(varname, tmp.plugin->name, "-", o->name, NullS);
+        my_casedn_str(&my_charset_latin1, varname);
+
+	for (char *p= varname; *p; p++)
+	  if (*p == '-')
+	    *p= '_';
+	
+        v= new (mem_root) sys_var_pluginvar(chain, varname, o);
+      }
+
+      DBUG_ASSERT(v);
+    }
+    if (chain.first)
+    {
+      chain.last->next = NULL;
+      if (mysql_add_sys_var_chain(chain.first, tmp.cmd_options))
+      {
+	sql_print_error("Plugin '%s' has conflicting system variables", tmp.plugin->name);
+	DBUG_RETURN(1);  
+      }
+      tmp.system_vars= chain.first;
+    }
+    DBUG_RETURN(0);
+  }
+
+  if (enabled_saved)
+    sql_print_information("Plugin '%s' disabled by command line option",
+    			  tmp.plugin->name);
+  DBUG_RETURN(1);
+}
+
+
+/****************************************************************************
+  Plugin support code
+****************************************************************************/
 
 static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
 {
@@ -417,7 +1824,8 @@
                               struct st_plugin_int *));
 }
 
-static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int report)
+static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, 
+                          char **argv, int report)
 {
   struct st_plugin_int tmp;
   struct st_mysql_plugin *plugin;
@@ -463,6 +1871,11 @@
       tmp.name.length= name_len;
       tmp.ref_count= 0;
       tmp.state= PLUGIN_IS_UNINITIALIZED;
+      if (test_plugin_options(tmp, argv, true))
+      {
+        plugin_dl_del(dl);
+        DBUG_RETURN(FALSE);
+      }
       if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
         goto err;
       plugin_array_version++;
@@ -471,6 +1884,7 @@
         tmp_plugin_ptr->state= PLUGIN_IS_FREED;
         goto err;
       }
+      init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
       DBUG_RETURN(FALSE);
     }
   }
@@ -535,6 +1949,8 @@
   plugin_dl_del(&plugin->plugin_dl->dl);
   plugin->state= PLUGIN_IS_FREED;
   plugin_array_version++;
+  mysql_del_sys_var_chain(plugin->system_vars);
+  free_root(&plugin->mem_root, MYF(0));
   DBUG_VOID_RETURN;
 }
 
@@ -563,71 +1979,6 @@
 }
 
 
-static my_bool get_one_option(int optid __attribute__((unused)),
-			const struct my_option *opt __attribute__((unused)),
-	       		char *argument __attribute__((unused)))
-{
-  return 0;
-}
-
-/*
-  RETURNS:
-    0 SUCCESS - plugin should be enabled/loaded
-*/
-static int test_plugin_enabled(const char *name, char **argv, bool def_enabled)
-{
-  my_bool enabled= def_enabled ? TRUE : FALSE;
-
-  if (argv && *argv)
-  {
-    int ho_error, argc= 0;
-    my_option options[3];
-    uint namelen= strlen(name);
-    char *name1= (char*) my_alloca(namelen * 2 + 10);
-    char *name2= name1 + namelen + 1;
-    
-    /* support --skip-plugin-foo syntax */
-    strxmov(name1, name, NullS);
-    my_casedn_str(&my_charset_latin1, name1);
-    strxmov(name2, "plugin-", name1, NullS);
-    
-    bzero(options, sizeof(options));
-    options[0].name= name1;
-    options[1].name= name2;
-    options[0].id= options[1].id= 1;
-    options[0].value= options[0].u_max_value=
-    options[1].value= options[1].u_max_value= (gptr*)&enabled;
-    options[0].var_type= options[1].var_type= GET_BOOL;
-    options[0].arg_type= options[1].arg_type= NO_ARG;
-    options[0].def_value= options[1].def_value= def_enabled ? 1 : 0;
-    
-    for (char** p= argv; *p; p++, argc++);
-    
-    ho_error= handle_options(&argc, &argv, options, get_one_option);
-
-    my_afree(name1);
-
-    if (ho_error)
-    {
-       sql_print_error("Parsing options for plugin '%s' failed.", name);
-       return ho_error;
-    }
-  }
-  
-  if (enabled)
-    return 0;
-
-  if (!my_strcasecmp(&my_charset_latin1, name, "MYISAM") ||
-      !my_strcasecmp(&my_charset_latin1, name, "MEMORY"))
-  {
-    sql_print_error("Plugin '%s' cannot be disabled", name);
-    return 0;
-  }
-
-  sql_print_information("Plugin '%s' disabled by command line option", name);
-  return 1;
-}
-
 static int plugin_initialize(struct st_plugin_int *plugin)
 {
   DBUG_ENTER("plugin_initialize");
@@ -688,6 +2039,14 @@
 }
 
 
+static byte *get_var_hash_key(const byte *buff, uint *length,
+                   my_bool not_used __attribute__((unused)))
+{
+  struct st_plugin_var *var= (st_plugin_var *)buff;
+  *length= var->name_len;
+  return (byte*) var->name;
+}
+
 /*
   The logic is that we first load and initialize all compiled in plugins.
   From there we load up the dynamic types (assuming we have not been told to
@@ -695,7 +2054,7 @@
 
   Finally we inializie everything, aka the dynamic that have yet to initialize.
 */
-int plugin_init(int skip_dynamic_loading, char **argv)
+int plugin_init(char **argv, int flags)
 {
   uint i;
   struct st_mysql_plugin **builtins;
@@ -705,6 +2064,12 @@
   if (initialized)
     DBUG_RETURN(0);
 
+  init_alloc_root(&plugin_mem_root, 4096, 4096);
+  if (hash_init(&plugin_var_hash, &my_charset_bin, 16, 0, 0,
+                  get_var_hash_key, NULL, 0))
+      goto err;
+  
+
   my_rwlock_init(&THR_LOCK_plugin, NULL);
 
   if (my_init_dynamic_array(&plugin_dl_array,
@@ -727,28 +2092,35 @@
   {
     for (plugin= *builtins; plugin->info; plugin++)
     {
-//      if (!(strcmp(plugin->name, "MyISAM")))
-      {
-        /* by default, ndbcluster is disabled */
-        bool def_enabled= 
-	  my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0;
-        if (test_plugin_enabled(plugin->name, argv, def_enabled))
-	  continue;
-	struct st_plugin_int *tmp;
-        if (register_builtin(plugin, &tmp))
-          goto err;
-        if (plugin_initialize(tmp))
-          goto err;
-      }
+      /* by default, only ndbcluster is disabled */
+      bool def_enabled= 
+	my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0;
+      struct st_plugin_int tmp, *plugin_ptr;
+      bzero(&tmp, sizeof(tmp));
+      tmp.plugin= plugin;
+      if (test_plugin_options(tmp, argv, def_enabled))
+	continue;
+      if (register_builtin(plugin, tmp, plugin_ptr))
+        goto err;
+
+      /* only initialize MyISAM, CSV and MEMORY at this stage */
+      if ((!my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM") /* ||
+           !my_strcasecmp(&my_charset_latin1, plugin->name, "MEMORY") ||
+	   !my_strcasecmp(&my_charset_latin1, plugin->name, "CSV") */ )&&
+          plugin_initialize(plugin_ptr))
+        goto err;
     }
   }
 
   /* Register all dynamic plugins */
-  if (!skip_dynamic_loading)
-    plugin_load();
+  if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
+    plugin_load(argv);
 
   initialized= 1;
 
+  if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
+    DBUG_RETURN(0);
+
   /*
     Now we initialize all remaining plugins
   */
@@ -758,12 +2130,6 @@
                                                struct st_plugin_int *);
     if (tmp->state == PLUGIN_IS_UNINITIALIZED)
     {
-      /* by default, all dynamically loaded plugins are enabled */
-      if (test_plugin_enabled(tmp->name.str, argv, true))
-      {
-        plugin_del(tmp);
-	continue;
-      }
       if (plugin_initialize(tmp))
       {
         plugin_deinitialize(tmp);
@@ -780,9 +2146,9 @@
 
 
 static my_bool register_builtin(struct st_mysql_plugin *plugin, 
-				struct st_plugin_int **ptr)
+				struct st_plugin_int &tmp,
+				struct st_plugin_int *&ptr)
 {
-  struct st_plugin_int tmp;
   DBUG_ENTER("plugin_register_builtin");
 
   tmp.plugin= plugin;
@@ -797,10 +2163,10 @@
   if (insert_dynamic(&plugin_array, (gptr)&tmp))
     DBUG_RETURN(1);
 
-  *ptr= dynamic_element(&plugin_array, plugin_array.elements - 1,
-                        struct st_plugin_int *);
+  ptr= dynamic_element(&plugin_array, plugin_array.elements - 1,
+                       struct st_plugin_int *);
 
-  if (my_hash_insert(&plugin_hash[plugin->type],(byte*) *ptr))
+  if (my_hash_insert(&plugin_hash[plugin->type],(byte*) ptr))
     DBUG_RETURN(1);
 
   DBUG_RETURN(0);
@@ -808,12 +2174,12 @@
 
 my_bool plugin_register_builtin(struct st_mysql_plugin *plugin)
 {
-  struct st_plugin_int *tmp;
-  return register_builtin(plugin, &tmp);
+  struct st_plugin_int tmp, *ptr;
+  return register_builtin(plugin, tmp, ptr);
 }
 
 
-void plugin_load(void)
+static void plugin_load(char **argv)
 {
   TABLE_LIST tables;
   TABLE *table;
@@ -857,7 +2223,7 @@
     LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
     LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
 
-    if (plugin_add(&name, &dl, REPORT_TO_LOG))
+    if (plugin_add(&name, &dl, argv, REPORT_TO_LOG))
       sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
                         str_name.c_ptr(), str_dl.c_ptr());
   }
@@ -887,6 +2253,8 @@
   {
     struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
                                                struct st_plugin_int *);
+    if (tmp->state != PLUGIN_IS_READY)
+      continue;
     plugin_deinitialize(tmp);
 
   }
@@ -929,7 +2297,7 @@
     DBUG_RETURN(TRUE);
 
   rw_wrlock(&THR_LOCK_plugin);
-  if (plugin_add(name, dl, REPORT_TO_USER))
+  if (plugin_add(name, dl, NULL, REPORT_TO_USER))
     goto err;
   tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
 

--- 1.13/sql/sql_plugin.h	2006-12-05 11:05:29 -08:00
+++ 1.14/sql/sql_plugin.h	2006-12-05 11:05:29 -08:00
@@ -17,6 +17,14 @@
 #ifndef _sql_plugin_h
 #define _sql_plugin_h
 
+class sys_var;
+
+/*
+  the following flags are valid for plugin_init()
+*/
+#define PLUGIN_INIT_SKIP_DYNAMIC_LOADING 1
+#define PLUGIN_INIT_SKIP_INITIALIZATION 2
+
 /*
   the following #define adds server-only members to enum_mysql_show_type,
   that is defined in plugin.h
@@ -55,7 +63,6 @@
 };
 
 /* A handle of a plugin */
-
 struct st_plugin_int
 {
   LEX_STRING name;
@@ -64,6 +71,9 @@
   uint state;
   uint ref_count;               /* number of threads using the plugin */
   void *data;                   /* plugin type specific, e.g. handlerton */
+  MEM_ROOT mem_root;		/* memory for dynamic structures */
+  struct my_option *cmd_options;
+  sys_var *system_vars;
 };
 
 typedef int (*plugin_type_init)(struct st_plugin_int *);
@@ -71,7 +81,9 @@
 extern char *opt_plugin_dir_ptr;
 extern char opt_plugin_dir[FN_REFLEN];
 extern const LEX_STRING plugin_type_names[];
-extern int plugin_init(int, char **);
+extern int plugin_init(char **argv, int init_flags);
+extern void mysql_pluginvar_cleanup(THD *thd);
+extern void plugin_print_help(struct my_option *options, uint size);
 extern void plugin_shutdown(void);
 extern my_bool plugin_is_ready(const LEX_STRING *name, int type);
 extern st_plugin_int *plugin_lock(const LEX_STRING *name, int type);
Thread
bk commit into 5.1 tree (antony:1.2372)antony5 Dec