summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql.cc2
-rw-r--r--include/hash.h3
-rw-r--r--include/my_getopt.h9
-rw-r--r--include/my_global.h8
-rw-r--r--include/my_sys.h11
-rw-r--r--include/mysql.h3
-rw-r--r--include/mysql/plugin.h318
-rw-r--r--include/mysys_err.h1
-rw-r--r--include/typelib.h4
-rwxr-xr-xmysql-test/mysql-test-run.pl19
-rw-r--r--mysql-test/r/flush2.result2
-rw-r--r--mysql-test/r/im_utils.result8
-rw-r--r--mysql-test/r/log_tables.result3
-rw-r--r--mysql-test/r/ps_1general.result7
-rw-r--r--mysql-test/r/variables.result16
-rw-r--r--mysql-test/t/log_tables.test3
-rw-r--r--mysql-test/t/ndb_dd_basic.test1
-rw-r--r--mysql-test/t/ps_1general.test6
-rw-r--r--mysql-test/t/variables.test16
-rw-r--r--mysql-test/t/warnings_engine_disabled-master.opt2
-rw-r--r--mysys/array.c62
-rw-r--r--mysys/hash.c17
-rw-r--r--mysys/my_getopt.c66
-rw-r--r--mysys/typelib.c55
-rw-r--r--sql/event_queue.cc2
-rw-r--r--sql/ha_ndbcluster.cc33
-rw-r--r--sql/ha_partition.cc31
-rw-r--r--sql/ha_partition.h6
-rw-r--r--sql/handler.cc159
-rw-r--r--sql/handler.h13
-rw-r--r--sql/item_create.cc394
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/log.cc4
-rw-r--r--sql/mysql_priv.h16
-rw-r--r--sql/mysqld.cc550
-rw-r--r--sql/partition_element.h4
-rw-r--r--sql/rpl_utility.h2
-rw-r--r--sql/set_var.cc1380
-rw-r--r--sql/set_var.h391
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/sql_cache.cc18
-rw-r--r--sql/sql_class.cc116
-rw-r--r--sql/sql_class.h18
-rw-r--r--sql/sql_connect.cc1
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc25
-rw-r--r--sql/sql_lex.h7
-rw-r--r--sql/sql_parse.cc62
-rw-r--r--sql/sql_partition.cc22
-rw-r--r--sql/sql_plugin.cc2324
-rw-r--r--sql/sql_plugin.h69
-rw-r--r--sql/sql_repl.cc143
-rw-r--r--sql/sql_repl.h1
-rw-r--r--sql/sql_select.cc24
-rw-r--r--sql/sql_show.cc93
-rw-r--r--sql/sql_table.cc24
-rw-r--r--sql/sql_tablespace.cc4
-rw-r--r--sql/sql_yacc.yy147
-rw-r--r--sql/structs.h2
-rw-r--r--sql/table.cc65
-rw-r--r--sql/table.h7
-rw-r--r--storage/example/ha_example.cc5
-rw-r--r--storage/federated/ha_federated.cc11
-rw-r--r--storage/heap/ha_heap.cc33
-rw-r--r--storage/innobase/handler/ha_innodb.cc708
-rw-r--r--storage/innobase/handler/ha_innodb.h12
-rw-r--r--storage/innobase/include/trx0trx.h8
-rw-r--r--storage/myisam/ha_myisam.cc40
-rw-r--r--storage/myisammrg/ha_myisammrg.cc37
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.cpp27
72 files changed, 5091 insertions, 2601 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index d2c7bd8812c..981e0ce5f16 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -739,7 +739,7 @@ static struct my_option my_long_options[] =
"Number of seconds before connection timeout.",
(gptr*) &opt_connect_timeout,
(gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0,
- 0, 1},
+ 0, 0},
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
"Max packet length to send to, or receive from server",
(gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0, GET_ULONG,
diff --git a/include/hash.h b/include/hash.h
index 97e947d7c6a..78499a4f810 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -27,6 +27,9 @@ extern "C" {
*/
#define HASH_OVERHEAD (sizeof(char*)*2)
+/* flags for hash_init */
+#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
+
typedef byte *(*hash_get_key)(const byte *,uint*,my_bool);
typedef void (*hash_free_key)(void *);
diff --git a/include/my_getopt.h b/include/my_getopt.h
index dcd6ad9d79b..a14507847be 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -29,12 +29,16 @@ C_MODE_START
#define GET_STR 9
#define GET_STR_ALLOC 10
#define GET_DISABLED 11
+#define GET_ENUM 12
+#define GET_SET 13
#define GET_ASK_ADDR 128
#define GET_TYPE_MASK 127
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
+struct st_typelib;
+
struct my_option
{
const char *name; /* Name of the option */
@@ -42,7 +46,7 @@ struct my_option
const char *comment; /* option comment, for autom. --help */
gptr *value; /* The variable value */
gptr *u_max_value; /* The user def. max variable value */
- const char **str_values; /* Pointer to possible values */
+ struct st_typelib *typelib; /* Pointer to possible values */
ulong var_type;
enum get_opt_arg_type arg_type;
longlong def_value; /* Default value */
@@ -50,7 +54,7 @@ struct my_option
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 */
+ void *app_type; /* To be used by an application */
};
typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
@@ -58,6 +62,7 @@ typedef void (* my_error_reporter) (enum loglevel level, const char *format, ...
extern char *disabled_my_option;
extern my_bool my_getopt_print_errors;
+extern my_bool my_getopt_skip_unknown;
extern my_error_reporter my_getopt_error_reporter;
extern int handle_options (int *argc, char ***argv,
diff --git a/include/my_global.h b/include/my_global.h
index 8b35f995a48..c88cf4e6e4b 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -458,6 +458,14 @@ C_MODE_END
*/
#include <assert.h>
+/* an assert that works at compile-time. only for constant expression */
+#define compile_time_assert(X) \
+ do \
+ { \
+ char compile_time_assert[(X) ? 1 : -1] \
+ __attribute__ ((unused)); \
+ } while(0)
+
/* Go around some bugs in different OS and compilers */
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
#define _LARGEFILE64_SOURCE
diff --git a/include/my_sys.h b/include/my_sys.h
index cff8c73c9ff..691233b9839 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -759,8 +759,15 @@ extern my_bool real_open_cached_file(IO_CACHE *cache);
extern void close_cached_file(IO_CACHE *cache);
File create_temp_file(char *to, const char *dir, const char *pfx,
int mode, myf MyFlags);
-#define my_init_dynamic_array(A,B,C,D) init_dynamic_array(A,B,C,D CALLER_INFO)
-#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array(A,B,C,D ORIG_CALLER_INFO)
+#define my_init_dynamic_array(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D CALLER_INFO)
+#define my_init_dynamic_array_ci(A,B,C,D) init_dynamic_array2(A,B,NULL,C,D ORIG_CALLER_INFO)
+#define my_init_dynamic_array2(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E CALLER_INFO)
+#define my_init_dynamic_array2_ci(A,B,C,D,E) init_dynamic_array2(A,B,C,D,E ORIG_CALLER_INFO)
+extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array,uint element_size,
+ void *init_buffer, uint init_alloc,
+ uint alloc_increment
+ CALLER_INFO_PROTO);
+/* init_dynamic_array() function is deprecated */
extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
uint init_alloc,uint alloc_increment
CALLER_INFO_PROTO);
diff --git a/include/mysql.h b/include/mysql.h
index 33bdf80ef73..f657e1ae64b 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -67,7 +67,6 @@ typedef int my_socket;
#include "mysql_version.h"
#include "mysql_com.h"
#include "mysql_time.h"
-#include "typelib.h"
#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */
@@ -126,6 +125,8 @@ typedef unsigned long long my_ulonglong;
#endif
#endif
+#include "typelib.h"
+
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
/* backward compatibility define - to be removed eventually */
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 660ce49d7ee..751ce516a39 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -16,6 +16,15 @@
#ifndef _my_plugin_h
#define _my_plugin_h
+#ifdef __cplusplus
+class THD;
+class Item;
+#define MYSQL_THD THD*
+#else
+#define MYSQL_THD void*
+#endif
+
+
/*************************************************************************
Plugin API. Common for all plugin types.
*/
@@ -85,7 +94,261 @@ struct st_mysql_show_var {
};
#define SHOW_VAR_FUNC_BUFF_SIZE 1024
-typedef int (*mysql_show_var_func)(void *, struct st_mysql_show_var*, char *);
+typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, char *);
+
+
+/*
+ declarations for server variables and command line options
+*/
+
+
+#define PLUGIN_VAR_BOOL 0x0001
+#define PLUGIN_VAR_INT 0x0002
+#define PLUGIN_VAR_LONG 0x0003
+#define PLUGIN_VAR_LONGLONG 0x0004
+#define PLUGIN_VAR_STR 0x0005
+#define PLUGIN_VAR_ENUM 0x0006
+#define PLUGIN_VAR_SET 0x0007
+#define PLUGIN_VAR_UNSIGNED 0x0080
+#define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */
+#define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */
+#define PLUGIN_VAR_NOSYSVAR 0x0400 /* Not a server variable */
+#define PLUGIN_VAR_NOCMDOPT 0x0800 /* Not a command line option */
+#define PLUGIN_VAR_NOCMDARG 0x1000 /* No argument for cmd line */
+#define PLUGIN_VAR_RQCMDARG 0x0000 /* Argument required for cmd line */
+#define PLUGIN_VAR_OPCMDARG 0x2000 /* Argument optional for cmd line */
+#define PLUGIN_VAR_MEMALLOC 0x8000 /* String needs memory allocated */
+
+struct st_mysql_sys_var;
+struct st_mysql_value;
+
+/*
+ SYNOPSIS
+ (*mysql_var_check_func)()
+ thd thread handle
+ var dynamic variable being altered
+ save pointer to temporary storage
+ value user provided value
+ RETURN
+ 0 user provided value is OK and the update func may be called.
+ any other value indicates error.
+
+ This function should parse the user provided value and store in the
+ provided temporary storage any data as required by the update func.
+ There is sufficient space in the temporary storage to store a double.
+ Note that the update func may not be called if any other error occurs
+ so any memory allocated should be thread-local so that it may be freed
+ automatically at the end of the statement.
+*/
+
+typedef int (*mysql_var_check_func)(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *save, struct st_mysql_value *value);
+
+/*
+ SYNOPSIS
+ (*mysql_var_update_func)()
+ thd thread handle
+ var dynamic variable being altered
+ var_ptr pointer to dynamic variable
+ save pointer to temporary storage
+ RETURN
+ NONE
+
+ This function should use the validated value stored in the temporary store
+ and persist it in the provided pointer to the dynamic variable.
+ For example, strings may require memory to be allocated.
+*/
+typedef void (*mysql_var_update_func)(MYSQL_THD thd,
+ struct st_mysql_sys_var *var,
+ void *var_ptr, void *save);
+
+
+/* the following declarations are for internal use only */
+
+
+#define PLUGIN_VAR_MASK \
+ (PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR | \
+ PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_NOCMDARG | \
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC)
+
+#define MYSQL_PLUGIN_VAR_HEADER \
+ int flags; \
+ const char *name; \
+ const char *comment; \
+ mysql_var_check_func check; \
+ mysql_var_update_func update
+
+#define MYSQL_SYSVAR_NAME(name) mysql_sysvar_ ## name
+#define MYSQL_SYSVAR(name) \
+ ((struct st_mysql_sys_var *)&(MYSQL_SYSVAR_NAME(name)))
+
+/*
+ for global variables, the value pointer is the first
+ element after the header, the default value is the second.
+ for thread variables, the value offset is the first
+ element after the header, the default value is the second.
+*/
+
+
+#define DECLARE_MYSQL_SYSVAR_BASIC(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ type *value; type def_val; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_SYSVAR_SIMPLE(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ type *value; type def_val; \
+ type min_val; type max_val; \
+ type blk_sz; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_SYSVAR_TYPELIB(name) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ unsigned long *value, def_val;\
+ TYPELIB *typelib; \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_THDVAR_FUNC(type) \
+ type *(*resolve)(MYSQL_THD thd, int offset)
+
+#define DECLARE_MYSQL_THDVAR_BASIC(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ type def_val; \
+ DECLARE_THDVAR_FUNC(type); \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_THDVAR_SIMPLE(name, type) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ type def_val; type min_val; \
+ type max_val; type blk_sz; \
+ DECLARE_THDVAR_FUNC(type); \
+} MYSQL_SYSVAR_NAME(name)
+
+#define DECLARE_MYSQL_THDVAR_TYPELIB(name) struct { \
+ MYSQL_PLUGIN_VAR_HEADER; \
+ int offset; \
+ unsigned long def_val; \
+ DECLARE_THDVAR_FUNC(unsigned long); \
+ TYPELIB *typelib; \
+} MYSQL_SYSVAR_NAME(name)
+
+
+/*
+ the following declarations are for use by plugin implementors
+*/
+
+#define MYSQL_SYSVAR_BOOL(name, varname, opt, comment, check, update, def) \
+DECLARE_MYSQL_SYSVAR_BASIC(name, char) = { \
+ PLUGIN_VAR_BOOL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def}
+
+#define MYSQL_SYSVAR_STR(name, varname, opt, comment, check, update, def) \
+DECLARE_MYSQL_SYSVAR_BASIC(name, char *) = { \
+ PLUGIN_VAR_STR | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def}
+
+#define MYSQL_SYSVAR_INT(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, int) = { \
+ PLUGIN_VAR_INT | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_UINT(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, unsigned int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_LONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, long) = { \
+ PLUGIN_VAR_LONG | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_ULONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, unsigned long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_LONGLONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, longlong) = { \
+ PLUGIN_VAR_LONGLONG | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_ULONGLONG(name, varname, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_SYSVAR_SIMPLE(name, ulonglong) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, min, max, blk }
+
+#define MYSQL_SYSVAR_ENUM(name, varname, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_SYSVAR_TYPELIB(name) = { \
+ PLUGIN_VAR_ENUM | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, typelib }
+
+#define MYSQL_SYSVAR_SET(name, varname, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_SYSVAR_TYPELIB(name) = { \
+ PLUGIN_VAR_SET | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, &varname, def, typelib }
+
+#define MYSQL_THDVAR_BOOL(name, opt, comment, check, update, def) \
+DECLARE_MYSQL_THDVAR_BASIC(name, char) = { \
+ PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL}
+
+#define MYSQL_THDVAR_STR(name, opt, comment, check, update, def) \
+DECLARE_MYSQL_THDVAR_BASIC(name, char *) = { \
+ PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL}
+
+#define MYSQL_THDVAR_INT(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_UINT(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, unsigned int) = { \
+ PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_LONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ULONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, unsigned long) = { \
+ PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_LONGLONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, longlong) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ULONGLONG(name, opt, comment, check, update, def, min, max, blk) \
+DECLARE_MYSQL_THDVAR_SIMPLE(name, ulonglong) = { \
+ PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_UNSIGNED | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, min, max, blk, NULL }
+
+#define MYSQL_THDVAR_ENUM(name, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_THDVAR_TYPELIB(name) = { \
+ PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL, typelib }
+
+#define MYSQL_THDVAR_SET(name, opt, comment, check, update, def, typelib) \
+DECLARE_MYSQL_THDVAR_TYPELIB(name) = { \
+ PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
+ #name, comment, check, update, -1, def, NULL, typelib }
+
+/* accessor macros */
+
+#define SYSVAR(name) \
+ (*(MYSQL_SYSVAR_NAME(name).value))
+
+/* when thd == null, result points to global value */
+#define THDVAR(thd, name) \
+ (*(MYSQL_SYSVAR_NAME(name).resolve(thd, MYSQL_SYSVAR_NAME(name).offset)))
+
/*
Plugin description structure.
@@ -103,8 +366,8 @@ struct st_mysql_plugin
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 */
- void * __reserved2; /* placeholder for config options */
+ struct st_mysql_sys_var **system_vars;
+ void * __reserved1; /* reserved for dependency checking */
};
/*************************************************************************
@@ -328,6 +591,8 @@ struct st_mysql_storage_engine
int interface_version;
};
+struct handlerton;
+
/*
Here we define only the descriptor structure, that is referred from
st_mysql_plugin.
@@ -348,5 +613,52 @@ struct st_mysql_information_schema
int interface_version;
};
+
+/*
+ st_mysql_value struct for reading values from mysqld.
+ Used by server variables framework to parse user-provided values.
+ Will be used for arguments when implementing UDFs.
+
+ Note that val_str() returns a string in temporary memory
+ that will be freed at the end of statement. Copy the string
+ if you need it to persist.
+*/
+
+#define MYSQL_VALUE_TYPE_STRING 0
+#define MYSQL_VALUE_TYPE_REAL 1
+#define MYSQL_VALUE_TYPE_INT 2
+
+struct st_mysql_value
+{
+ int (*value_type)(struct st_mysql_value *);
+ const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
+ int (*val_real)(struct st_mysql_value *, double *realbuf);
+ int (*val_int)(struct st_mysql_value *, long long *intbuf);
+};
+
+
+/*************************************************************************
+ Miscellaneous functions for plugin implementors
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int thd_in_lock_tables(const MYSQL_THD thd);
+int thd_tablespace_op(const MYSQL_THD thd);
+long long thd_test_options(const MYSQL_THD thd, long long test_options);
+int thd_sql_command(const MYSQL_THD thd);
+const char *thd_proc_info(MYSQL_THD thd, const char *info);
+void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
+int thd_tx_isolation(const MYSQL_THD thd);
+char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
+ unsigned int max_query_len);
+
+
+#ifdef __cplusplus
+};
+#endif
+
#endif
diff --git a/include/mysys_err.h b/include/mysys_err.h
index b92027a4e3c..09e77248c17 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -79,6 +79,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EXIT_NO_PTR_TO_VARIABLE 10
#define EXIT_CANNOT_CONNECT_TO_SERVICE 11
#define EXIT_OPTION_DISABLED 12
+#define EXIT_ARGUMENT_INVALID 13
#ifdef __cplusplus
diff --git a/include/typelib.h b/include/typelib.h
index e04ec20f2bc..3a63f1c7403 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -26,8 +26,8 @@ typedef struct st_typelib { /* Different types saved here */
unsigned int *type_lengths;
} TYPELIB;
-extern int find_type(char *x, const TYPELIB *typelib,
- unsigned int full_name);
+extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
+extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 46938ea7cde..4ed1686a121 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1345,10 +1345,13 @@ sub collect_mysqld_features () {
my $found_variable_list_start= 0;
#
- # Execute "mysqld --no-defaults --help --verbose" to get a
+ # Execute "mysqld --help --verbose" to get a list
# list of all features and settings
#
- my $list= `$exe_mysqld --no-defaults --verbose --help`;
+ # --no-defaults and --skip-grant-tables are to avoid loading
+ # system-wide configs and plugins
+ #
+ my $list= `$exe_mysqld --no-defaults --skip-grant-tables --verbose --help`;
foreach my $line (split('\n', $list))
{
@@ -2975,8 +2978,8 @@ sub install_db ($$) {
mtr_add_arg($args, "--bootstrap");
mtr_add_arg($args, "--basedir=%s", $path_my_basedir);
mtr_add_arg($args, "--datadir=%s", $data_dir);
- mtr_add_arg($args, "--skip-innodb");
- mtr_add_arg($args, "--skip-ndbcluster");
+ mtr_add_arg($args, "--loose-skip-innodb");
+ mtr_add_arg($args, "--loose-skip-ndbcluster");
mtr_add_arg($args, "--tmpdir=.");
mtr_add_arg($args, "--core-file");
@@ -3117,8 +3120,8 @@ basedir = $path_my_basedir
server_id = $server_id
shutdown-delay = 10
skip-stack-trace
-skip-innodb
-skip-ndbcluster
+loose-skip-innodb
+loose-skip-ndbcluster
EOF
;
if ( $mysql_version_id < 50100 )
@@ -3788,7 +3791,7 @@ sub mysqld_arguments ($$$$) {
if ( $opt_skip_ndbcluster ||
!$cluster->{'pid'})
{
- mtr_add_arg($args, "%s--skip-ndbcluster", $prefix);
+ mtr_add_arg($args, "%s--loose-skip-ndbcluster", $prefix);
}
else
{
@@ -3862,7 +3865,7 @@ sub mysqld_arguments ($$$$) {
$mysqld->{'cluster'} == -1 ||
!$clusters->[$mysqld->{'cluster'}]->{'pid'} )
{
- mtr_add_arg($args, "%s--skip-ndbcluster", $prefix);
+ mtr_add_arg($args, "%s--loose-skip-ndbcluster", $prefix);
}
else
{
diff --git a/mysql-test/r/flush2.result b/mysql-test/r/flush2.result
index 13bcc371ef6..5056955c7b7 100644
--- a/mysql-test/r/flush2.result
+++ b/mysql-test/r/flush2.result
@@ -4,9 +4,11 @@ show variables like 'log_bin%';
Variable_name Value
log_bin OFF
log_bin_trust_function_creators ON
+log_bin_trust_routine_creators ON
flush logs;
show variables like 'log_bin%';
Variable_name Value
log_bin OFF
log_bin_trust_function_creators ON
+log_bin_trust_routine_creators ON
set global expire_logs_days = 0;
diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result
index 397050635e1..586a5ab6a8d 100644
--- a/mysql-test/r/im_utils.result
+++ b/mysql-test/r/im_utils.result
@@ -21,8 +21,8 @@ basedir VALUE
server_id VALUE
shutdown-delay VALUE
skip-stack-trace VALUE
-skip-innodb VALUE
-skip-ndbcluster VALUE
+loose-skip-innodb VALUE
+loose-skip-ndbcluster VALUE
log-output VALUE
SHOW INSTANCE OPTIONS mysqld2;
option_name value
@@ -40,8 +40,8 @@ basedir VALUE
server_id VALUE
shutdown-delay VALUE
skip-stack-trace VALUE
-skip-innodb VALUE
-skip-ndbcluster VALUE
+loose-skip-innodb VALUE
+loose-skip-ndbcluster VALUE
nonguarded VALUE
log-output VALUE
START INSTANCE mysqld2;
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index 8264f252287..5a90c22fa06 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -169,6 +169,8 @@ lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL;
unlock tables;
set global general_log='OFF';
set global slow_query_log='OFF';
+set @save_storage_engine= @@session.storage_engine;
+set storage_engine= MEMORY;
alter table mysql.slow_log engine=ndb;
ERROR HY000: This storage engine cannot be used for log tables"
alter table mysql.slow_log engine=innodb;
@@ -177,6 +179,7 @@ alter table mysql.slow_log engine=archive;
ERROR HY000: This storage engine cannot be used for log tables"
alter table mysql.slow_log engine=blackhole;
ERROR HY000: This storage engine cannot be used for log tables"
+set storage_engine= @save_storage_engine;
drop table mysql.slow_log;
drop table mysql.general_log;
drop table mysql.general_log;
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index 391d22d232b..26692a992fe 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -303,10 +303,9 @@ prepare stmt4 from ' show variables like ''sql_mode'' ';
execute stmt4;
Variable_name Value
sql_mode
-prepare stmt4 from ' show engine bdb logs ';
-ERROR 42000: Unknown table engine 'bdb'
-prepare stmt4 from ' show engine foo logs ';
-ERROR 42000: Unknown table engine 'foo'
+prepare stmt4 from ' show engine myisam logs ';
+execute stmt4;
+Type Name Status
prepare stmt4 from ' show grants for user ';
prepare stmt4 from ' show create table t2 ';
prepare stmt4 from ' show master status ';
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 6927f07da6b..67259dbf5d4 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -235,7 +235,7 @@ net_buffer_length 1024
net_read_timeout 300
net_retry_count 10
net_write_timeout 200
-select * from information_schema.global_variables where variable_name like 'net_%';
+select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 1024
NET_READ_TIMEOUT 300
@@ -247,7 +247,7 @@ net_buffer_length 2048
net_read_timeout 600
net_retry_count 10
net_write_timeout 500
-select * from information_schema.session_variables where variable_name like 'net_%';
+select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 2048
NET_READ_TIMEOUT 600
@@ -260,7 +260,7 @@ net_buffer_length 1024
net_read_timeout 900
net_retry_count 10
net_write_timeout 1000
-select * from information_schema.global_variables where variable_name like 'net_%';
+select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 1024
NET_READ_TIMEOUT 900
@@ -272,7 +272,7 @@ net_buffer_length 7168
net_read_timeout 600
net_retry_count 10
net_write_timeout 500
-select * from information_schema.session_variables where variable_name like 'net_%';
+select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
NET_BUFFER_LENGTH 7168
NET_READ_TIMEOUT 600
@@ -313,7 +313,7 @@ query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
@@ -335,7 +335,7 @@ query_prealloc_size 18432
range_alloc_block_size 16384
transaction_alloc_block_size 19456
transaction_prealloc_size 20480
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 17408
QUERY_PREALLOC_SIZE 18432
@@ -352,7 +352,7 @@ query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
QUERY_ALLOC_BLOCK_SIZE 8192
QUERY_PREALLOC_SIZE 8192
@@ -880,7 +880,7 @@ ssl_capath #
ssl_cert #
ssl_cipher #
ssl_key #
-select * from information_schema.session_variables where variable_name like 'ssl%';
+select * from information_schema.session_variables where variable_name like 'ssl%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
SSL_CA #
SSL_CAPATH #
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index f1ff91a6d1d..b02a47dde6b 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -252,6 +252,8 @@ set global general_log='OFF';
set global slow_query_log='OFF';
# check that alter table doesn't work for other engines
+set @save_storage_engine= @@session.storage_engine;
+set storage_engine= MEMORY;
--error ER_UNSUPORTED_LOG_ENGINE
alter table mysql.slow_log engine=ndb;
--error ER_UNSUPORTED_LOG_ENGINE
@@ -260,6 +262,7 @@ alter table mysql.slow_log engine=innodb;
alter table mysql.slow_log engine=archive;
--error ER_UNSUPORTED_LOG_ENGINE
alter table mysql.slow_log engine=blackhole;
+set storage_engine= @save_storage_engine;
drop table mysql.slow_log;
drop table mysql.general_log;
diff --git a/mysql-test/t/ndb_dd_basic.test b/mysql-test/t/ndb_dd_basic.test
index 81286d3121f..7f74fe7d050 100644
--- a/mysql-test/t/ndb_dd_basic.test
+++ b/mysql-test/t/ndb_dd_basic.test
@@ -25,6 +25,7 @@ INITIAL_SIZE 16M
UNDO_BUFFER_SIZE = 1M
ENGINE=MYISAM;
+--error ER_UNKNOWN_STORAGE_ENGINE
ALTER LOGFILE GROUP lg1
ADD UNDOFILE 'undofile02.dat'
INITIAL_SIZE = 4M
diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test
index df3d1f0791c..2d5dd14e847 100644
--- a/mysql-test/t/ps_1general.test
+++ b/mysql-test/t/ps_1general.test
@@ -321,10 +321,8 @@ prepare stmt4 from ' show status like ''Threads_running'' ';
execute stmt4;
prepare stmt4 from ' show variables like ''sql_mode'' ';
execute stmt4;
---error ER_UNKNOWN_STORAGE_ENGINE
-prepare stmt4 from ' show engine bdb logs ';
---error ER_UNKNOWN_STORAGE_ENGINE
-prepare stmt4 from ' show engine foo logs ';
+prepare stmt4 from ' show engine myisam logs ';
+execute stmt4;
prepare stmt4 from ' show grants for user ';
prepare stmt4 from ' show create table t2 ';
prepare stmt4 from ' show master status ';
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index d381ed62bc7..c2a3d3a8e3d 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -150,14 +150,14 @@ set global net_retry_count=10, session net_retry_count=10;
set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600;
show global variables like 'net_%';
-select * from information_schema.global_variables where variable_name like 'net_%';
+select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
show session variables like 'net_%';
-select * from information_schema.session_variables where variable_name like 'net_%';
+select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000;
show global variables like 'net_%';
-select * from information_schema.global_variables where variable_name like 'net_%';
+select * from information_schema.global_variables where variable_name like 'net_%' order by 1;
show session variables like 'net_%';
-select * from information_schema.session_variables where variable_name like 'net_%';
+select * from information_schema.session_variables where variable_name like 'net_%' order by 1;
set net_buffer_length=1;
show variables like 'net_buffer_length';
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
@@ -174,7 +174,7 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5);
show variables like '%alloc%';
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
set @@range_alloc_block_size=1024*16;
set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18;
@@ -182,12 +182,12 @@ set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size;
show variables like '%alloc%';
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%';
-select * from information_schema.session_variables where variable_name like '%alloc%';
+select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
#
# Bug #10904 Illegal mix of collations between
@@ -668,7 +668,7 @@ select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
--replace_column 2 #
show variables like 'ssl%';
--replace_column 2 #
-select * from information_schema.session_variables where variable_name like 'ssl%';
+select * from information_schema.session_variables where variable_name like 'ssl%' order by 1;
#
# Bug #19616: make log_queries_not_using_indexes available in SHOW VARIABLES
diff --git a/mysql-test/t/warnings_engine_disabled-master.opt b/mysql-test/t/warnings_engine_disabled-master.opt
index 99837e4a4cb..f51c1789a16 100644
--- a/mysql-test/t/warnings_engine_disabled-master.opt
+++ b/mysql-test/t/warnings_engine_disabled-master.opt
@@ -1 +1 @@
---loose-skip-ndb
+--loose-skip-plugin-ndbcluster
diff --git a/mysys/array.c b/mysys/array.c
index 60f5b255e18..130a8f358de 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -22,9 +22,10 @@
Initiate dynamic array
SYNOPSIS
- init_dynamic_array()
+ init_dynamic_array2()
array Pointer to an array
element_size Size of element
+ init_buffer Initial buffer pointer
init_alloc Number of initial elements
alloc_increment Increment for adding new elements
@@ -32,14 +33,15 @@
init_dynamic_array() initiates array and allocate space for
init_alloc eilements.
Array is usable even if space allocation failed.
+ Static buffers must begin immediately after the array structure.
RETURN VALUE
TRUE my_malloc_ci() failed
FALSE Ok
*/
-my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
- uint init_alloc,
+my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
+ void *init_buffer, uint init_alloc,
uint alloc_increment CALLER_INFO_PROTO)
{
DBUG_ENTER("init_dynamic_array");
@@ -51,11 +53,16 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
}
if (!init_alloc)
+ {
init_alloc=alloc_increment;
+ init_buffer= 0;
+ }
array->elements=0;
array->max_element=init_alloc;
array->alloc_increment=alloc_increment;
array->size_of_element=element_size;
+ if ((array->buffer= init_buffer))
+ DBUG_RETURN(FALSE);
if (!(array->buffer=(char*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME))))
{
array->max_element=0;
@@ -64,6 +71,14 @@ my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
DBUG_RETURN(FALSE);
}
+my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
+ uint init_alloc,
+ uint alloc_increment CALLER_INFO_PROTO)
+{
+ /* placeholder to preserve ABI */
+ return my_init_dynamic_array_ci(array, element_size, init_alloc,
+ alloc_increment);
+}
/*
Insert element at the end of array. Allocate memory if needed.
@@ -117,6 +132,21 @@ byte *alloc_dynamic(DYNAMIC_ARRAY *array)
if (array->elements == array->max_element)
{
char *new_ptr;
+ if (array->buffer == (char *)(array + 1))
+ {
+ /*
+ In this senerio, the buffer is statically preallocated,
+ so we have to create an all-new malloc since we overflowed
+ */
+ if (!(new_ptr= (char *) my_malloc((array->max_element+
+ array->alloc_increment) *
+ array->size_of_element,
+ MYF(MY_WME))))
+ return 0;
+ memcpy(new_ptr, array->buffer,
+ array->elements * array->size_of_element);
+ }
+ else
if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
array->alloc_increment)*
array->size_of_element,
@@ -176,6 +206,20 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
char *new_ptr;
size=(idx+array->alloc_increment)/array->alloc_increment;
size*= array->alloc_increment;
+ if (array->buffer == (char *)(array + 1))
+ {
+ /*
+ In this senerio, the buffer is statically preallocated,
+ so we have to create an all-new malloc since we overflowed
+ */
+ if (!(new_ptr= (char *) my_malloc(size *
+ array->size_of_element,
+ MYF(MY_WME))))
+ return 0;
+ memcpy(new_ptr, array->buffer,
+ array->elements * array->size_of_element);
+ }
+ else
if (!(new_ptr=(char*) my_realloc(array->buffer,size*
array->size_of_element,
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
@@ -226,6 +270,12 @@ void get_dynamic(DYNAMIC_ARRAY *array, gptr element, uint idx)
void delete_dynamic(DYNAMIC_ARRAY *array)
{
+ /*
+ Just mark as empty if we are using a static buffer
+ */
+ if (array->buffer == (char *)(array + 1))
+ array->elements= 0;
+ else
if (array->buffer)
{
my_free(array->buffer,MYF(MY_WME));
@@ -265,6 +315,12 @@ void freeze_size(DYNAMIC_ARRAY *array)
{
uint elements=max(array->elements,1);
+ /*
+ Do nothing if we are using a static buffer
+ */
+ if (array->buffer == (char *)(array + 1))
+ return;
+
if (array->buffer && array->max_element != elements)
{
array->buffer=(char*) my_realloc(array->buffer,
diff --git a/mysys/hash.c b/mysys/hash.c
index 60168e01e20..ab875848989 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -315,6 +315,10 @@ my_bool my_hash_insert(HASH *info,const byte *record)
LINT_INIT(gpos); LINT_INIT(gpos2);
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
+ if (HASH_UNIQUE & info->flags &&
+ hash_search(info, hash_key(info, record, &idx, 1), idx))
+ return(TRUE); /* Duplicate entry */
+
flag=0;
if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
return(TRUE); /* No more memory */
@@ -530,6 +534,19 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length)
uint idx,new_index,new_pos_index,blength,records,empty;
HASH_LINK org_link,*data,*previous,*pos;
DBUG_ENTER("hash_update");
+
+ if (HASH_UNIQUE & hash->flags)
+ {
+ HASH_SEARCH_STATE state;
+ byte *found, *new_key= hash_key(hash, record, &idx, 1);
+ if ((found= hash_first(hash, new_key, idx, &state)))
+ do
+ {
+ if (found != record)
+ DBUG_RETURN(1); /* Duplicate entry */
+ }
+ while ((found= hash_next(hash, new_key, idx, &state)));
+ }
data=dynamic_element(&hash->array,0,HASH_LINK*);
blength=hash->blength; records=hash->records;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index aa470282aa4..4573d27555a 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -58,6 +58,13 @@ char *disabled_my_option= (char*) "0";
my_bool my_getopt_print_errors= 1;
+/*
+ This is a flag that can be set in client programs. 1 means that
+ my_getopt will skip over options it does not know how to handle.
+*/
+
+my_bool my_getopt_skip_unknown= 0;
+
static void default_reporter(enum loglevel level,
const char *format, ...)
{
@@ -90,18 +97,18 @@ void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint,
getopt_get_addr= func_addr;
}
-int handle_options(int *argc, char ***argv,
+int handle_options(int *argc, char ***argv,
const struct my_option *longopts,
my_get_one_option get_one_option)
{
- uint opt_found, argvpos= 0, length, i;
+ uint opt_found, argvpos= 0, length;
my_bool end_of_options= 0, must_be_var, set_maximum_value,
option_is_loose;
char **pos, **pos_end, *optend, *prev_found,
*opt_str, key_name[FN_REFLEN];
const struct my_option *optp;
gptr *value;
- int error;
+ int error, i;
LINT_INIT(opt_found);
(*argc)--; /* Skip the program name */
@@ -110,6 +117,7 @@ int handle_options(int *argc, char ***argv,
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 */
{
@@ -216,12 +224,11 @@ int handle_options(int *argc, char ***argv,
/*
We were called with a special prefix, we can reuse opt_found
*/
- opt_str+= (special_opt_prefix_lengths[i] + 1);
+ opt_str+= special_opt_prefix_lengths[i] + 1;
+ length-= special_opt_prefix_lengths[i] + 1;
if (i == OPT_LOOSE)
option_is_loose= 1;
- if ((opt_found= findopt(opt_str, length -
- (special_opt_prefix_lengths[i] + 1),
- &optp, &prev_found)))
+ if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
{
if (opt_found > 1)
{
@@ -245,7 +252,7 @@ int handle_options(int *argc, char ***argv,
break;
case OPT_ENABLE:
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
- disabled_my_option : (char*) "1";
+ disabled_my_option : (char*) "1";
break;
case OPT_MAXIMUM:
set_maximum_value= 1;
@@ -254,11 +261,25 @@ int handle_options(int *argc, char ***argv,
}
break; /* break from the inner loop, main loop continues */
}
+ i= -1; /* restart the loop */
}
}
}
if (!opt_found)
{
+ if (my_getopt_skip_unknown)
+ {
+ /*
+ preserve all the components of this unknown option, this may
+ occurr when the user provides options like: "-O foo" or
+ "--set-variable foo" (note that theres a space in there)
+ Generally, these kind of options are to be avoided
+ */
+ do {
+ (*argv)[argvpos++]= *first++;
+ } while (first <= pos);
+ continue;
+ }
if (must_be_var)
{
if (my_getopt_print_errors)
@@ -596,6 +617,15 @@ static int setval(const struct my_option *opts, gptr *value, char *argument,
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
return EXIT_OUT_OF_MEMORY;
break;
+ case GET_ENUM:
+ if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
+ return EXIT_ARGUMENT_INVALID;
+ break;
+ case GET_SET:
+ *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
+ if (err)
+ return EXIT_ARGUMENT_INVALID;
+ break;
default: /* dummy default to avoid compiler warnings */
break;
}
@@ -788,6 +818,7 @@ static void init_one_value(const struct my_option *option, gptr *variable,
*((int*) variable)= (int) value;
break;
case GET_UINT:
+ case GET_ENUM:
*((uint*) variable)= (uint) value;
break;
case GET_LONG:
@@ -800,6 +831,7 @@ static void init_one_value(const struct my_option *option, gptr *variable,
*((longlong*) variable)= (longlong) value;
break;
case GET_ULL:
+ case GET_SET:
*((ulonglong*) variable)= (ulonglong) value;
break;
default: /* dummy default to avoid compiler warnings */
@@ -928,7 +960,8 @@ void my_print_help(const struct my_option *options)
void my_print_variables(const struct my_option *options)
{
- uint name_space= 34, length;
+ uint name_space= 34, length, nr;
+ ulonglong bit, llvalue;
char buff[255];
const struct my_option *optp;
@@ -946,6 +979,21 @@ void my_print_variables(const struct my_option *options)
for (; length < name_space; length++)
putchar(' ');
switch ((optp->var_type & GET_TYPE_MASK)) {
+ case GET_SET:
+ if (!(llvalue= *(ulonglong*) value))
+ printf("%s\n", "(No default value)");
+ else
+ for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
+ {
+ if (!(bit & llvalue))
+ continue;
+ llvalue&= ~bit;
+ printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
+ }
+ break;
+ case GET_ENUM:
+ printf("%s\n", get_type(optp->typelib, *(uint*) value));
+ break;
case GET_STR:
case GET_STR_ALLOC: /* fall through */
printf("%s\n", *((char**) value) ? *((char**) value) :
diff --git a/mysys/typelib.c b/mysys/typelib.c
index dc9f0850bbc..8b0b4eb8740 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -20,6 +20,8 @@
#include <m_ctype.h>
+static const char field_separator=',';
+
/*
Search after a string in a list of strings. Endspace in x is not compared.
@@ -31,6 +33,7 @@
If & 1 accept only whole names
If & 2 don't expand if half field
If & 4 allow #number# as type
+ If & 8 use ',' as string terminator
NOTES
If part, uniq field is found and full_name == 0 then x is expanded
@@ -60,16 +63,18 @@ int find_type(char *x, const TYPELIB *typelib, uint full_name)
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
{
for (i=x ;
- *i && my_toupper(&my_charset_latin1,*i) ==
+ *i && (!(full_name & 8) || *i != field_separator) &&
+ my_toupper(&my_charset_latin1,*i) ==
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
if (! *j)
{
while (*i == ' ')
i++; /* skip_end_space */
- if (! *i)
+ if (! *i || ((full_name & 8) && *i == field_separator))
DBUG_RETURN(pos+1);
}
- if (! *i && (!*j || !(full_name & 1)))
+ if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
+ (!*j || !(full_name & 1)))
{
find++;
findpos=pos;
@@ -121,6 +126,50 @@ const char *get_type(TYPELIB *typelib, uint nr)
/*
+ Create an integer value to represent the supplied comma-seperated
+ string where each string in the TYPELIB denotes a bit position.
+
+ SYNOPSIS
+ find_typeset()
+ x string to decompose
+ lib TYPELIB (struct of pointer to values + count)
+ err index (not char position) of string element which was not
+ found or 0 if there was no error
+
+ RETURN
+ a integer representation of the supplied string
+*/
+
+my_ulonglong find_typeset(my_string x, TYPELIB *lib, int *err)
+{
+ my_ulonglong result;
+ int find;
+ my_string i;
+ DBUG_ENTER("find_set");
+ DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) lib));
+
+ if (!lib->count)
+ {
+ DBUG_PRINT("exit",("no count"));
+ DBUG_RETURN(0);
+ }
+ result= 0;
+ *err= 0;
+ while (*x)
+ {
+ (*err)++;
+ i= x;
+ while (*x && *x != field_separator) x++;
+ if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
+ DBUG_RETURN(0);
+ result|= (ULL(1) << find);
+ }
+ *err= 0;
+ DBUG_RETURN(result);
+} /* find_set */
+
+
+/*
Create a copy of a specified TYPELIB structure.
SYNOPSIS
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 9b14d3cda7e..92622bcc2c2 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -70,7 +70,7 @@ event_queue_element_compare_q(void *vptr, byte* a, byte *b)
*/
Event_queue::Event_queue()
- :mutex_last_unlocked_at_line(0), mutex_last_locked_at_line(0),
+ :mutex_last_locked_at_line(0), mutex_last_unlocked_at_line(0),
mutex_last_attempted_lock_at_line(0),
mutex_queue_data_locked(FALSE),
mutex_queue_data_attempting_lock(FALSE),
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index d12f94c6967..a2ca0c8047d 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -2628,7 +2628,7 @@ int ha_ndbcluster::write_row(byte *record)
DBUG_RETURN(peek_res);
}
- statistic_increment(thd->status_var.ha_write_count, &LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
@@ -2853,7 +2853,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
DBUG_RETURN(peek_res);
}
- statistic_increment(thd->status_var.ha_update_count, &LOCK_status);
+ ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
{
table->timestamp_field->set_time();
@@ -3029,7 +3029,7 @@ int ha_ndbcluster::delete_row(const byte *record)
DBUG_ENTER("delete_row");
m_write_op= TRUE;
- statistic_increment(thd->status_var.ha_delete_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_delete_count);
m_rows_changed++;
if (m_use_partition_function &&
@@ -3412,8 +3412,7 @@ int ha_ndbcluster::index_read(byte *buf,
int ha_ndbcluster::index_next(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_next");
- statistic_increment(current_thd->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
DBUG_RETURN(next_result(buf));
}
@@ -3421,8 +3420,7 @@ int ha_ndbcluster::index_next(byte *buf)
int ha_ndbcluster::index_prev(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_prev");
- statistic_increment(current_thd->status_var.ha_read_prev_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_prev_count);
DBUG_RETURN(next_result(buf));
}
@@ -3430,8 +3428,7 @@ int ha_ndbcluster::index_prev(byte *buf)
int ha_ndbcluster::index_first(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_first");
- statistic_increment(current_thd->status_var.ha_read_first_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_first_count);
// Start the ordered index scan and fetch the first row
// Only HA_READ_ORDER indexes get called by index_first
@@ -3442,7 +3439,7 @@ int ha_ndbcluster::index_first(byte *buf)
int ha_ndbcluster::index_last(byte *buf)
{
DBUG_ENTER("ha_ndbcluster::index_last");
- statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_last_count);
DBUG_RETURN(ordered_index_scan(0, 0, TRUE, TRUE, buf, NULL));
}
@@ -3628,8 +3625,7 @@ int ha_ndbcluster::rnd_end()
int ha_ndbcluster::rnd_next(byte *buf)
{
DBUG_ENTER("rnd_next");
- statistic_increment(current_thd->status_var.ha_read_rnd_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
if (!m_active_cursor)
DBUG_RETURN(full_table_scan(buf));
@@ -3647,8 +3643,7 @@ int ha_ndbcluster::rnd_next(byte *buf)
int ha_ndbcluster::rnd_pos(byte *buf, byte *pos)
{
DBUG_ENTER("rnd_pos");
- statistic_increment(current_thd->status_var.ha_read_rnd_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_count);
// The primary key for the record is stored in pos
// Perform a pk_read using primary key "index"
{
@@ -6876,7 +6871,7 @@ static int ndbcluster_init(void *p)
{
handlerton *h= ndbcluster_hton;
- h->state= have_ndbcluster;
+ h->state= SHOW_OPTION_YES;
h->db_type= DB_TYPE_NDBCLUSTER;
h->close_connection= ndbcluster_close_connection;
h->commit= ndbcluster_commit;
@@ -6898,9 +6893,6 @@ static int ndbcluster_init(void *p)
h->table_exists_in_engine= ndbcluster_table_exists_in_engine;
}
- if (have_ndbcluster != SHOW_OPTION_YES)
- DBUG_RETURN(0); // nothing else to do
-
// Initialize ndb interface
ndb_init_internal();
@@ -7016,7 +7008,6 @@ ndbcluster_init_error:
if (g_ndb_cluster_connection)
delete g_ndb_cluster_connection;
g_ndb_cluster_connection= NULL;
- have_ndbcluster= SHOW_OPTION_DISABLED; // If we couldn't use handler
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
DBUG_RETURN(TRUE);
@@ -10380,10 +10371,6 @@ ndbcluster_show_status(handlerton *hton, THD* thd, stat_print_fn *stat_print,
uint buflen;
DBUG_ENTER("ndbcluster_show_status");
- if (have_ndbcluster != SHOW_OPTION_YES)
- {
- DBUG_RETURN(FALSE);
- }
if (stat_type != HA_ENGINE_STATUS)
{
DBUG_RETURN(FALSE);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 3c25dcd202f..762c11ed6b2 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1987,6 +1987,8 @@ bool ha_partition::create_handler_file(const char *name)
void ha_partition::clear_handler_file()
{
+ if (m_engine_array)
+ plugin_unlock_list(NULL, m_engine_array, m_tot_parts);
my_free((char*) m_file_buffer, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) m_engine_array, MYF(MY_ALLOW_ZERO_PTR));
m_file_buffer= NULL;
@@ -2009,6 +2011,7 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
{
uint i;
uint alloc_len= (m_tot_parts + 1) * sizeof(handler*);
+ handlerton *hton0;
DBUG_ENTER("create_handlers");
if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
@@ -2017,19 +2020,21 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
bzero((char*) m_file, alloc_len);
for (i= 0; i < m_tot_parts; i++)
{
+ handlerton *hton= plugin_data(m_engine_array[i], handlerton*);
if (!(m_file[i]= get_new_handler(table_share, mem_root,
- m_engine_array[i])))
+ hton)))
DBUG_RETURN(TRUE);
- DBUG_PRINT("info", ("engine_type: %u", m_engine_array[i]->db_type));
+ DBUG_PRINT("info", ("engine_type: %u", hton->db_type));
}
/* For the moment we only support partition over the same table engine */
- if (m_engine_array[0] == myisam_hton)
+ hton0= plugin_data(m_engine_array[0], handlerton*);
+ if (hton0 == myisam_hton)
{
DBUG_PRINT("info", ("MyISAM"));
m_myisam= TRUE;
}
/* INNODB may not be compiled in... */
- else if (ha_legacy_type(m_engine_array[0]) == DB_TYPE_INNODB)
+ else if (ha_legacy_type(hton0) == DB_TYPE_INNODB)
{
DBUG_PRINT("info", ("InnoDB"));
m_innodb= TRUE;
@@ -2160,8 +2165,7 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
m_tot_parts= uint4korr((file_buffer) + 8);
DBUG_PRINT("info", ("No of parts = %u", m_tot_parts));
tot_partition_words= (m_tot_parts + 3) / 4;
- if (!(engine_array= (handlerton **) my_malloc(m_tot_parts * sizeof(handlerton*),MYF(0))))
- goto err2;
+ engine_array= (handlerton **) my_alloca(m_tot_parts * sizeof(handlerton*));
for (i= 0; i < m_tot_parts; i++)
engine_array[i]= ha_resolve_by_legacy_type(current_thd,
(enum legacy_db_type)
@@ -2169,12 +2173,21 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words;
tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4;
if (len_words != (tot_partition_words + tot_name_words + 4))
- goto err2;
+ goto err3;
name_buffer_ptr= file_buffer + 16 + 4 * tot_partition_words;
VOID(my_close(file, MYF(0)));
m_file_buffer= file_buffer; // Will be freed in clear_handler_file()
m_name_buffer_ptr= name_buffer_ptr;
- m_engine_array= engine_array;
+
+ if (!(m_engine_array= (plugin_ref*)
+ my_malloc(m_tot_parts * sizeof(plugin_ref), MYF(MY_WME))))
+ goto err3;
+
+ for (i= 0; i < m_tot_parts; i++)
+ m_engine_array[i]= ha_lock_engine(NULL, engine_array[i]);
+
+ my_afree((gptr) engine_array);
+
if (!m_file && create_handlers(mem_root))
{
clear_handler_file();
@@ -2182,6 +2195,8 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
}
DBUG_RETURN(FALSE);
+err3:
+ my_afree((gptr) engine_array);
err2:
my_free(file_buffer, MYF(0));
err1:
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index a081e4bb472..f5695e91ee0 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -27,6 +27,7 @@ enum partition_keywords
The partition implements the minimum of what you will probably need.
*/
+#ifdef NOT_USED
typedef struct st_partition_share
{
char *table_name;
@@ -34,6 +35,7 @@ typedef struct st_partition_share
pthread_mutex_t mutex;
THR_LOCK lock;
} PARTITION_SHARE;
+#endif
#define PARTITION_BYTES_IN_POS 2
@@ -54,7 +56,7 @@ private:
uint m_open_test_lock; // Open test_if_locked
char *m_file_buffer; // Buffer with names
char *m_name_buffer_ptr; // Pointer to first partition name
- handlerton **m_engine_array; // Array of types of the handlers
+ plugin_ref *m_engine_array; // Array of types of the handlers
handler **m_file; // Array of references to handler inst.
uint m_file_tot_parts; // Debug
handler **m_new_file; // Array of references to new handlers
@@ -130,7 +132,9 @@ private:
Variables for lock structures.
*/
THR_LOCK_DATA lock; /* MySQL lock */
+#ifdef NOT_USED
PARTITION_SHARE *share; /* Shared lock info */
+#endif
/*
TRUE <=> this object was created with ha_partition::clone and doesn't
diff --git a/sql/handler.cc b/sql/handler.cc
index 617bf9ee378..07ca6de5023 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -77,6 +77,15 @@ static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
uint known_extensions_id= 0;
+
+static plugin_ref ha_default_plugin(THD *thd)
+{
+ if (thd->variables.table_plugin)
+ return thd->variables.table_plugin;
+ return my_plugin_lock(thd, &global_system_variables.table_plugin);
+}
+
+
/** @brief
Return the default storage engine handlerton for thread
@@ -89,10 +98,11 @@ uint known_extensions_id= 0;
*/
handlerton *ha_default_handlerton(THD *thd)
{
- return (thd->variables.table_type != NULL) ?
- thd->variables.table_type :
- (global_system_variables.table_type != NULL ?
- global_system_variables.table_type : myisam_hton);
+ plugin_ref plugin= ha_default_plugin(thd);
+ DBUG_ASSERT(plugin);
+ handlerton *hton= plugin_data(plugin, handlerton*);
+ DBUG_ASSERT(hton);
+ return hton;
}
@@ -105,26 +115,30 @@ handlerton *ha_default_handlerton(THD *thd)
name name of storage engine
RETURN
- pointer to handlerton
+ pointer to storage engine plugin handle
*/
-handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name)
+plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name)
{
const LEX_STRING *table_alias;
- st_plugin_int *plugin;
+ plugin_ref plugin;
redo:
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1,
(const uchar *)name->str, name->length,
(const uchar *)STRING_WITH_LEN("DEFAULT"), 0))
- return ha_default_handlerton(thd);
+ return ha_default_plugin(thd);
- if ((plugin= plugin_lock(name, MYSQL_STORAGE_ENGINE_PLUGIN)))
+ if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN)))
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
- return hton;
- plugin_unlock(plugin);
+ return plugin;
+
+ /*
+ unlocking plugin immediately after locking is relatively low cost.
+ */
+ plugin_unlock(thd, plugin);
}
/*
@@ -145,19 +159,19 @@ redo:
}
-const char *ha_get_storage_engine(enum legacy_db_type db_type)
+plugin_ref ha_lock_engine(THD *thd, handlerton *hton)
{
- switch (db_type) {
- case DB_TYPE_DEFAULT:
- return "DEFAULT";
- default:
- if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
- installed_htons[db_type])
- return hton2plugin[installed_htons[db_type]->slot]->name.str;
- /* fall through */
- case DB_TYPE_UNKNOWN:
- return "UNKNOWN";
+ if (hton)
+ {
+ st_plugin_int **plugin= hton2plugin + hton->slot;
+
+#ifdef DBUG_OFF
+ return my_plugin_lock(thd, plugin);
+#else
+ return my_plugin_lock(thd, &plugin);
+#endif
}
+ return NULL;
}
@@ -172,14 +186,16 @@ static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root)
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
{
+ plugin_ref plugin;
switch (db_type) {
case DB_TYPE_DEFAULT:
return ha_default_handlerton(thd);
- case DB_TYPE_UNKNOWN:
- return NULL;
default:
- if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT)
- return installed_htons[db_type];
+ if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
+ (plugin= ha_lock_engine(thd, installed_htons[db_type])))
+ return plugin_data(plugin, handlerton*);
+ /* fall through */
+ case DB_TYPE_UNKNOWN:
return NULL;
}
}
@@ -199,7 +215,7 @@ handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
{
if (report_error)
{
- const char *engine_name= ha_get_storage_engine(database_type);
+ const char *engine_name= ha_resolve_storage_engine_name(hton);
my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name);
}
return NULL;
@@ -238,8 +254,7 @@ handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
Here the call to current_thd() is ok as we call this function a lot of
times but we enter this branch very seldom.
*/
- DBUG_RETURN(get_new_handler(share, alloc,
- current_thd->variables.table_type));
+ DBUG_RETURN(get_new_handler(share, alloc, ha_default_handlerton(current_thd)));
}
@@ -522,10 +537,10 @@ int ha_end()
DBUG_RETURN(error);
}
-static my_bool dropdb_handlerton(THD *unused1, st_plugin_int *plugin,
+static my_bool dropdb_handlerton(THD *unused1, plugin_ref plugin,
void *path)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->drop_database)
hton->drop_database(hton, (char *)path);
return FALSE;
@@ -538,10 +553,10 @@ void ha_drop_database(char* path)
}
-static my_bool closecon_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
void *unused)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
/*
there's no need to rollback here as all transactions must
be rolled back already
@@ -638,7 +653,7 @@ int ha_prepare(THD *thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
- hton2plugin[(*ht)->slot]->name.str);
+ ha_resolve_storage_engine_name(*ht));
}
}
}
@@ -886,10 +901,10 @@ struct xahton_st {
int result;
};
-static my_bool xacommit_handlerton(THD *unused1, st_plugin_int *plugin,
+static my_bool xacommit_handlerton(THD *unused1, plugin_ref plugin,
void *arg)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->recover)
{
hton->commit_by_xid(hton, ((struct xahton_st *)arg)->xid);
@@ -898,10 +913,10 @@ static my_bool xacommit_handlerton(THD *unused1, st_plugin_int *plugin,
return FALSE;
}
-static my_bool xarollback_handlerton(THD *unused1, st_plugin_int *plugin,
+static my_bool xarollback_handlerton(THD *unused1, plugin_ref plugin,
void *arg)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->recover)
{
hton->rollback_by_xid(hton, ((struct xahton_st *)arg)->xid);
@@ -1004,10 +1019,10 @@ struct xarecover_st
bool dry_run;
};
-static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin,
+static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
void *arg)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
struct xarecover_st *info= (struct xarecover_st *) arg;
int got;
@@ -1016,7 +1031,7 @@ static my_bool xarecover_handlerton(THD *unused, st_plugin_int *plugin,
while ((got= hton->recover(hton, info->list, info->len)) > 0 )
{
sql_print_information("Found %d prepared transaction(s) in %s",
- got, hton2plugin[hton->slot]->name.str);
+ got, ha_resolve_storage_engine_name(hton));
for (int i=0; i < got; i ++)
{
my_xid x=info->list[i].get_my_xid();
@@ -1192,10 +1207,10 @@ bool mysql_xa_recover(THD *thd)
thd: the thread handle of the current connection
return value: always 0
*/
-static my_bool release_temporary_latches(THD *thd, st_plugin_int *plugin,
+static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
void *unused)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->release_temporary_latches)
hton->release_temporary_latches(hton, thd);
@@ -1318,10 +1333,10 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
}
-static my_bool snapshot_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES &&
hton->start_consistent_snapshot)
{
@@ -1349,10 +1364,10 @@ int ha_start_consistent_snapshot(THD *thd)
}
-static my_bool flush_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool flush_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->flush_logs &&
hton->flush_logs(hton))
return TRUE;
@@ -1397,7 +1412,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
if (table_type == NULL ||
- ! (file=get_new_handler(&dummy_share, thd->mem_root, table_type)))
+ ! (file=get_new_handler((TABLE_SHARE*)0, thd->mem_root, table_type)))
DBUG_RETURN(ENOENT);
if (lower_case_table_names == 2 && !(file->ha_table_flags() & HA_FILE_BASED))
@@ -1438,6 +1453,8 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
dummy_share.table_name.length= strlen(alias);
dummy_table.alias= alias;
+ file->table_share= &dummy_share;
+ file->table= &dummy_table;
file->print_error(error, 0);
strmake(new_error, thd->net.last_error, sizeof(buff)-1);
@@ -1458,7 +1475,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
****************************************************************************/
handler *handler::clone(MEM_ROOT *mem_root)
{
- handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type);
+ handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
if (new_handler && !new_handler->ha_open(table,
table->s->normalized_path.str,
table->db_stat,
@@ -1474,6 +1491,17 @@ void handler::ha_statistic_increment(ulong SSV::*offset) const
statistic_increment(table->in_use->status_var.*offset, &LOCK_status);
}
+void **handler::ha_data(THD *thd) const
+{
+ return (void **) thd->ha_data + ht->slot;
+}
+
+THD *handler::ha_thd(void) const
+{
+ DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd);
+ return (table && table->in_use) ? table->in_use : current_thd;
+}
+
bool handler::check_if_log_table_locking_is_allowed(uint sql_command,
ulong type, TABLE *table)
@@ -1567,8 +1595,7 @@ int handler::read_first_row(byte * buf, uint primary_key)
register int error;
DBUG_ENTER("handler::read_first_row");
- statistic_increment(table->in_use->status_var.ha_read_first_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_first_count);
/*
If there is very few deleted rows in the table, find the first row by
@@ -2778,11 +2805,11 @@ struct st_discover_args
uint* frmlen;
};
-static my_bool discover_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool discover_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
st_discover_args *vargs= (st_discover_args *)arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->discover &&
(!(hton->discover(hton, thd, vargs->db, vargs->name,
vargs->frmblob,
@@ -2827,11 +2854,11 @@ struct st_find_files_args
List<char> *files;
};
-static my_bool find_files_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool find_files_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
st_find_files_args *vargs= (st_find_files_args *)arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->find_files)
@@ -2874,11 +2901,11 @@ struct st_table_exists_in_engine_args
const char *name;
};
-static my_bool table_exists_in_engine_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool table_exists_in_engine_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
st_table_exists_in_engine_args *vargs= (st_table_exists_in_engine_args *)arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
if ((hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name)) == 1)
@@ -2922,10 +2949,10 @@ struct binlog_func_st
/** @brief
Listing handlertons first to avoid recursive calls and deadlock
*/
-static my_bool binlog_func_list(THD *thd, st_plugin_int *plugin, void *arg)
+static my_bool binlog_func_list(THD *thd, plugin_ref plugin, void *arg)
{
hton_list_st *hton_list= (hton_list_st *)arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->binlog_func)
{
uint sz= hton_list->sz;
@@ -3012,10 +3039,10 @@ static my_bool binlog_log_query_handlerton2(THD *thd,
}
static my_bool binlog_log_query_handlerton(THD *thd,
- st_plugin_int *plugin,
+ plugin_ref plugin,
void *args)
{
- return binlog_log_query_handlerton2(thd, (handlerton *)plugin->data, args);
+ return binlog_log_query_handlerton2(thd, plugin_data(plugin, handlerton *), args);
}
void ha_binlog_log_query(THD *thd, handlerton *hton,
@@ -3307,11 +3334,11 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key,
RETURN VALUE
pointer pointer to TYPELIB structure
*/
-static my_bool exts_handlerton(THD *unused, st_plugin_int *plugin,
+static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
void *arg)
{
List<char> *found_exts= (List<char> *) arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
handler *file;
if (hton->state == SHOW_OPTION_YES && hton->create &&
(file= hton->create(hton, (TABLE_SHARE*) 0, current_thd->mem_root)))
@@ -3382,11 +3409,11 @@ static bool stat_print(THD *thd, const char *type, uint type_len,
}
-static my_bool showstat_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool showstat_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
enum ha_stat_type stat= *(enum ha_stat_type *) arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->show_status &&
hton->show_status(hton, thd, stat_print, stat))
return TRUE;
diff --git a/sql/handler.h b/sql/handler.h
index cfa86358fa1..a940841170b 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -888,6 +888,8 @@ uint calculate_key_len(TABLE *, uint, const byte *, key_part_map);
class handler :public Sql_alloc
{
friend class ha_partition;
+ friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
+ const char*,bool);
protected:
struct st_table_share *table_share; /* The table definition */
@@ -906,7 +908,10 @@ class handler :public Sql_alloc
virtual int rnd_init(bool scan) =0;
virtual int rnd_end() { return 0; }
virtual ulonglong table_flags(void) const =0;
+
void ha_statistic_increment(ulong SSV::*offset) const;
+ void **ha_data(THD *) const;
+ THD *ha_thd(void) const;
ha_rows estimation_rows_to_insert;
virtual void start_bulk_insert(ha_rows rows) {}
@@ -1570,6 +1575,10 @@ public:
/* lock_count() can be more than one if the table is a MERGE */
virtual uint lock_count(void) const { return 1; }
+ /*
+ NOTE that one can NOT rely on table->in_use in store_lock(). It may
+ refer to a different thread if called from mysql_lock_abort_for_thread().
+ */
virtual THR_LOCK_DATA **store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)=0;
@@ -1687,9 +1696,9 @@ extern ulong total_ha, total_ha_2pc;
/* lookups */
handlerton *ha_default_handlerton(THD *thd);
-handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name);
+plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
+plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
-const char *ha_get_storage_engine(enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
handlerton *db_type);
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 8ff78ef1b48..d11a2f84a0a 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -4681,203 +4681,203 @@ struct Native_func_registry
static Native_func_registry func_array[] =
{
- { C_STRING_WITH_LEN("ABS"), BUILDER(Create_func_abs)},
- { C_STRING_WITH_LEN("ACOS"), BUILDER(Create_func_acos)},
- { C_STRING_WITH_LEN("ADDTIME"), BUILDER(Create_func_addtime)},
- { C_STRING_WITH_LEN("AES_DECRYPT"), BUILDER(Create_func_aes_decrypt)},
- { C_STRING_WITH_LEN("AES_ENCRYPT"), BUILDER(Create_func_aes_encrypt)},
- { C_STRING_WITH_LEN("AREA"), GEOM_BUILDER(Create_func_area)},
- { C_STRING_WITH_LEN("ASBINARY"), GEOM_BUILDER(Create_func_as_wkb)},
- { C_STRING_WITH_LEN("ASIN"), BUILDER(Create_func_asin)},
- { C_STRING_WITH_LEN("ASTEXT"), GEOM_BUILDER(Create_func_as_wkt)},
- { C_STRING_WITH_LEN("ASWKB"), GEOM_BUILDER(Create_func_as_wkb)},
- { C_STRING_WITH_LEN("ASWKT"), GEOM_BUILDER(Create_func_as_wkt)},
- { C_STRING_WITH_LEN("ATAN"), BUILDER(Create_func_atan)},
- { C_STRING_WITH_LEN("ATAN2"), BUILDER(Create_func_atan)},
- { C_STRING_WITH_LEN("BENCHMARK"), BUILDER(Create_func_benchmark)},
- { C_STRING_WITH_LEN("BIN"), BUILDER(Create_func_bin)},
- { C_STRING_WITH_LEN("BIT_COUNT"), BUILDER(Create_func_bit_count)},
- { C_STRING_WITH_LEN("BIT_LENGTH"), BUILDER(Create_func_bit_length)},
- { C_STRING_WITH_LEN("CEIL"), BUILDER(Create_func_ceiling)},
- { C_STRING_WITH_LEN("CEILING"), BUILDER(Create_func_ceiling)},
- { C_STRING_WITH_LEN("CENTROID"), GEOM_BUILDER(Create_func_centroid)},
- { C_STRING_WITH_LEN("CHARACTER_LENGTH"), BUILDER(Create_func_char_length)},
- { C_STRING_WITH_LEN("CHAR_LENGTH"), BUILDER(Create_func_char_length)},
- { C_STRING_WITH_LEN("COERCIBILITY"), BUILDER(Create_func_coercibility)},
- { C_STRING_WITH_LEN("COMPRESS"), BUILDER(Create_func_compress)},
- { C_STRING_WITH_LEN("CONCAT"), BUILDER(Create_func_concat)},
- { C_STRING_WITH_LEN("CONCAT_WS"), BUILDER(Create_func_concat_ws)},
- { C_STRING_WITH_LEN("CONNECTION_ID"), BUILDER(Create_func_connection_id)},
- { C_STRING_WITH_LEN("CONV"), BUILDER(Create_func_conv)},
- { C_STRING_WITH_LEN("CONVERT_TZ"), BUILDER(Create_func_convert_tz)},
- { C_STRING_WITH_LEN("COS"), BUILDER(Create_func_cos)},
- { C_STRING_WITH_LEN("COT"), BUILDER(Create_func_cot)},
- { C_STRING_WITH_LEN("CRC32"), BUILDER(Create_func_crc32)},
- { C_STRING_WITH_LEN("CROSSES"), GEOM_BUILDER(Create_func_crosses)},
- { C_STRING_WITH_LEN("DATEDIFF"), BUILDER(Create_func_datediff)},
- { C_STRING_WITH_LEN("DATE_FORMAT"), BUILDER(Create_func_date_format)},
- { C_STRING_WITH_LEN("DAYNAME"), BUILDER(Create_func_dayname)},
- { C_STRING_WITH_LEN("DAYOFMONTH"), BUILDER(Create_func_dayofmonth)},
- { C_STRING_WITH_LEN("DAYOFWEEK"), BUILDER(Create_func_dayofweek)},
- { C_STRING_WITH_LEN("DAYOFYEAR"), BUILDER(Create_func_dayofyear)},
- { C_STRING_WITH_LEN("DECODE"), BUILDER(Create_func_decode)},
- { C_STRING_WITH_LEN("DEGREES"), BUILDER(Create_func_degrees)},
- { C_STRING_WITH_LEN("DES_DECRYPT"), BUILDER(Create_func_des_decrypt)},
- { C_STRING_WITH_LEN("DES_ENCRYPT"), BUILDER(Create_func_des_encrypt)},
- { C_STRING_WITH_LEN("DIMENSION"), GEOM_BUILDER(Create_func_dimension)},
- { C_STRING_WITH_LEN("DISJOINT"), GEOM_BUILDER(Create_func_disjoint)},
- { C_STRING_WITH_LEN("ELT"), BUILDER(Create_func_elt)},
- { C_STRING_WITH_LEN("ENCODE"), BUILDER(Create_func_encode)},
- { C_STRING_WITH_LEN("ENCRYPT"), BUILDER(Create_func_encrypt)},
- { C_STRING_WITH_LEN("ENDPOINT"), GEOM_BUILDER(Create_func_endpoint)},
- { C_STRING_WITH_LEN("ENVELOPE"), GEOM_BUILDER(Create_func_envelope)},
- { C_STRING_WITH_LEN("EQUALS"), GEOM_BUILDER(Create_func_equals)},
- { C_STRING_WITH_LEN("EXP"), BUILDER(Create_func_exp)},
- { C_STRING_WITH_LEN("EXPORT_SET"), BUILDER(Create_func_export_set)},
- { C_STRING_WITH_LEN("EXTERIORRING"), GEOM_BUILDER(Create_func_exteriorring)},
- { C_STRING_WITH_LEN("EXTRACTVALUE"), BUILDER(Create_func_xml_extractvalue)},
- { C_STRING_WITH_LEN("FIELD"), BUILDER(Create_func_field)},
- { C_STRING_WITH_LEN("FIND_IN_SET"), BUILDER(Create_func_find_in_set)},
- { C_STRING_WITH_LEN("FLOOR"), BUILDER(Create_func_floor)},
- { C_STRING_WITH_LEN("FORMAT"), BUILDER(Create_func_format)},
- { C_STRING_WITH_LEN("FOUND_ROWS"), BUILDER(Create_func_found_rows)},
- { C_STRING_WITH_LEN("FROM_DAYS"), BUILDER(Create_func_from_days)},
- { C_STRING_WITH_LEN("FROM_UNIXTIME"), BUILDER(Create_func_from_unixtime)},
- { C_STRING_WITH_LEN("GEOMCOLLFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("GEOMCOLLFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("GEOMETRYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("GEOMETRYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("GEOMETRYN"), GEOM_BUILDER(Create_func_geometryn)},
- { C_STRING_WITH_LEN("GEOMETRYTYPE"), GEOM_BUILDER(Create_func_geometry_type)},
- { C_STRING_WITH_LEN("GEOMFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("GEOMFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("GET_LOCK"), BUILDER(Create_func_get_lock)},
- { C_STRING_WITH_LEN("GLENGTH"), GEOM_BUILDER(Create_func_glength)},
- { C_STRING_WITH_LEN("GREATEST"), BUILDER(Create_func_greatest)},
- { C_STRING_WITH_LEN("HEX"), BUILDER(Create_func_hex)},
- { C_STRING_WITH_LEN("IFNULL"), BUILDER(Create_func_ifnull)},
- { C_STRING_WITH_LEN("INET_ATON"), BUILDER(Create_func_inet_aton)},
- { C_STRING_WITH_LEN("INET_NTOA"), BUILDER(Create_func_inet_ntoa)},
- { C_STRING_WITH_LEN("INSTR"), BUILDER(Create_func_instr)},
- { C_STRING_WITH_LEN("INTERIORRINGN"), GEOM_BUILDER(Create_func_interiorringn)},
- { C_STRING_WITH_LEN("INTERSECTS"), GEOM_BUILDER(Create_func_intersects)},
- { C_STRING_WITH_LEN("ISCLOSED"), GEOM_BUILDER(Create_func_isclosed)},
- { C_STRING_WITH_LEN("ISEMPTY"), GEOM_BUILDER(Create_func_isempty)},
- { C_STRING_WITH_LEN("ISNULL"), BUILDER(Create_func_isnull)},
- { C_STRING_WITH_LEN("ISSIMPLE"), GEOM_BUILDER(Create_func_issimple)},
- { C_STRING_WITH_LEN("IS_FREE_LOCK"), BUILDER(Create_func_is_free_lock)},
- { C_STRING_WITH_LEN("IS_USED_LOCK"), BUILDER(Create_func_is_used_lock)},
- { C_STRING_WITH_LEN("LAST_DAY"), BUILDER(Create_func_last_day)},
- { C_STRING_WITH_LEN("LAST_INSERT_ID"), BUILDER(Create_func_last_insert_id)},
- { C_STRING_WITH_LEN("LCASE"), BUILDER(Create_func_lcase)},
- { C_STRING_WITH_LEN("LEAST"), BUILDER(Create_func_least)},
- { C_STRING_WITH_LEN("LENGTH"), BUILDER(Create_func_length)},
- { C_STRING_WITH_LEN("LINEFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("LINEFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("LINESTRINGFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("LINESTRINGFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("LN"), BUILDER(Create_func_ln)},
- { C_STRING_WITH_LEN("LOAD_FILE"), BUILDER(Create_func_load_file)},
- { C_STRING_WITH_LEN("LOCATE"), BUILDER(Create_func_locate)},
- { C_STRING_WITH_LEN("LOG"), BUILDER(Create_func_log)},
- { C_STRING_WITH_LEN("LOG10"), BUILDER(Create_func_log10)},
- { C_STRING_WITH_LEN("LOG2"), BUILDER(Create_func_log2)},
- { C_STRING_WITH_LEN("LOWER"), BUILDER(Create_func_lcase)},
- { C_STRING_WITH_LEN("LPAD"), BUILDER(Create_func_lpad)},
- { C_STRING_WITH_LEN("LTRIM"), BUILDER(Create_func_ltrim)},
- { C_STRING_WITH_LEN("MAKEDATE"), BUILDER(Create_func_makedate)},
- { C_STRING_WITH_LEN("MAKETIME"), BUILDER(Create_func_maketime)},
- { C_STRING_WITH_LEN("MAKE_SET"), BUILDER(Create_func_make_set)},
- { C_STRING_WITH_LEN("MASTER_POS_WAIT"), BUILDER(Create_func_master_pos_wait)},
- { C_STRING_WITH_LEN("MBRCONTAINS"), GEOM_BUILDER(Create_func_contains)},
- { C_STRING_WITH_LEN("MBRDISJOINT"), GEOM_BUILDER(Create_func_disjoint)},
- { C_STRING_WITH_LEN("MBREQUAL"), GEOM_BUILDER(Create_func_equals)},
- { C_STRING_WITH_LEN("MBRINTERSECTS"), GEOM_BUILDER(Create_func_intersects)},
- { C_STRING_WITH_LEN("MBROVERLAPS"), GEOM_BUILDER(Create_func_overlaps)},
- { C_STRING_WITH_LEN("MBRTOUCHES"), GEOM_BUILDER(Create_func_touches)},
- { C_STRING_WITH_LEN("MBRWITHIN"), GEOM_BUILDER(Create_func_within)},
- { C_STRING_WITH_LEN("MD5"), BUILDER(Create_func_md5)},
- { C_STRING_WITH_LEN("MLINEFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MLINEFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("MONTHNAME"), BUILDER(Create_func_monthname)},
- { C_STRING_WITH_LEN("MPOINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MPOINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("MPOLYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MPOLYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("MULTILINESTRINGFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MULTILINESTRINGFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("MULTIPOINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MULTIPOINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("MULTIPOLYGONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("MULTIPOLYGONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("NAME_CONST"), BUILDER(Create_func_name_const)},
- { C_STRING_WITH_LEN("NULLIF"), BUILDER(Create_func_nullif)},
- { C_STRING_WITH_LEN("NUMGEOMETRIES"), GEOM_BUILDER(Create_func_numgeometries)},
- { C_STRING_WITH_LEN("NUMINTERIORRINGS"), GEOM_BUILDER(Create_func_numinteriorring)},
- { C_STRING_WITH_LEN("NUMPOINTS"), GEOM_BUILDER(Create_func_numpoints)},
- { C_STRING_WITH_LEN("OCT"), BUILDER(Create_func_oct)},
- { C_STRING_WITH_LEN("OCTET_LENGTH"), BUILDER(Create_func_length)},
- { C_STRING_WITH_LEN("ORD"), BUILDER(Create_func_ord)},
- { C_STRING_WITH_LEN("OVERLAPS"), GEOM_BUILDER(Create_func_overlaps)},
- { C_STRING_WITH_LEN("PERIOD_ADD"), BUILDER(Create_func_period_add)},
- { C_STRING_WITH_LEN("PERIOD_DIFF"), BUILDER(Create_func_period_diff)},
- { C_STRING_WITH_LEN("PI"), BUILDER(Create_func_pi)},
- { C_STRING_WITH_LEN("POINTFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("POINTFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("POINTN"), GEOM_BUILDER(Create_func_pointn)},
- { C_STRING_WITH_LEN("POLYFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("POLYFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("POLYGONFROMTEXT"), GEOM_BUILDER(Create_func_geometry_from_text)},
- { C_STRING_WITH_LEN("POLYGONFROMWKB"), GEOM_BUILDER(Create_func_geometry_from_wkb)},
- { C_STRING_WITH_LEN("POW"), BUILDER(Create_func_pow)},
- { C_STRING_WITH_LEN("POWER"), BUILDER(Create_func_pow)},
- { C_STRING_WITH_LEN("QUOTE"), BUILDER(Create_func_quote)},
- { C_STRING_WITH_LEN("RADIANS"), BUILDER(Create_func_radians)},
- { C_STRING_WITH_LEN("RAND"), BUILDER(Create_func_rand)},
- { C_STRING_WITH_LEN("RELEASE_LOCK"), BUILDER(Create_func_release_lock)},
- { C_STRING_WITH_LEN("REVERSE"), BUILDER(Create_func_reverse)},
- { C_STRING_WITH_LEN("ROUND"), BUILDER(Create_func_round)},
- { C_STRING_WITH_LEN("ROW_COUNT"), BUILDER(Create_func_row_count)},
- { C_STRING_WITH_LEN("RPAD"), BUILDER(Create_func_rpad)},
- { C_STRING_WITH_LEN("RTRIM"), BUILDER(Create_func_rtrim)},
- { C_STRING_WITH_LEN("SEC_TO_TIME"), BUILDER(Create_func_sec_to_time)},
- { C_STRING_WITH_LEN("SHA"), BUILDER(Create_func_sha)},
- { C_STRING_WITH_LEN("SHA1"), BUILDER(Create_func_sha)},
- { C_STRING_WITH_LEN("SIGN"), BUILDER(Create_func_sign)},
- { C_STRING_WITH_LEN("SIN"), BUILDER(Create_func_sin)},
- { C_STRING_WITH_LEN("SLEEP"), BUILDER(Create_func_sleep)},
- { C_STRING_WITH_LEN("SOUNDEX"), BUILDER(Create_func_soundex)},
- { C_STRING_WITH_LEN("SPACE"), BUILDER(Create_func_space)},
- { C_STRING_WITH_LEN("SQRT"), BUILDER(Create_func_sqrt)},
- { C_STRING_WITH_LEN("SRID"), GEOM_BUILDER(Create_func_srid)},
- { C_STRING_WITH_LEN("STARTPOINT"), GEOM_BUILDER(Create_func_startpoint)},
- { C_STRING_WITH_LEN("STRCMP"), BUILDER(Create_func_strcmp)},
- { C_STRING_WITH_LEN("STR_TO_DATE"), BUILDER(Create_func_str_to_date)},
- { C_STRING_WITH_LEN("SUBSTRING_INDEX"), BUILDER(Create_func_substr_index)},
- { C_STRING_WITH_LEN("SUBTIME"), BUILDER(Create_func_subtime)},
- { C_STRING_WITH_LEN("TAN"), BUILDER(Create_func_tan)},
- { C_STRING_WITH_LEN("TIMEDIFF"), BUILDER(Create_func_timediff)},
- { C_STRING_WITH_LEN("TIME_FORMAT"), BUILDER(Create_func_time_format)},
- { C_STRING_WITH_LEN("TIME_TO_SEC"), BUILDER(Create_func_time_to_sec)},
- { C_STRING_WITH_LEN("TOUCHES"), GEOM_BUILDER(Create_func_touches)},
- { C_STRING_WITH_LEN("TO_DAYS"), BUILDER(Create_func_to_days)},
- { C_STRING_WITH_LEN("UCASE"), BUILDER(Create_func_ucase)},
- { C_STRING_WITH_LEN("UNCOMPRESS"), BUILDER(Create_func_uncompress)},
- { C_STRING_WITH_LEN("UNCOMPRESSED_LENGTH"), BUILDER(Create_func_uncompressed_length)},
- { C_STRING_WITH_LEN("UNHEX"), BUILDER(Create_func_unhex)},
- { C_STRING_WITH_LEN("UNIX_TIMESTAMP"), BUILDER(Create_func_unix_timestamp)},
- { C_STRING_WITH_LEN("UPDATEXML"), BUILDER(Create_func_xml_update)},
- { C_STRING_WITH_LEN("UPPER"), BUILDER(Create_func_ucase)},
- { C_STRING_WITH_LEN("UUID"), BUILDER(Create_func_uuid)},
- { C_STRING_WITH_LEN("VERSION"), BUILDER(Create_func_version)},
- { C_STRING_WITH_LEN("WEEKDAY"), BUILDER(Create_func_weekday)},
- { C_STRING_WITH_LEN("WEEKOFYEAR"), BUILDER(Create_func_weekofyear)},
- { C_STRING_WITH_LEN("WITHIN"), GEOM_BUILDER(Create_func_within)},
- { C_STRING_WITH_LEN("X"), GEOM_BUILDER(Create_func_x)},
- { C_STRING_WITH_LEN("Y"), GEOM_BUILDER(Create_func_y)},
- { C_STRING_WITH_LEN("YEARWEEK"), BUILDER(Create_func_year_week)},
+ { { C_STRING_WITH_LEN("ABS") }, BUILDER(Create_func_abs)},
+ { { C_STRING_WITH_LEN("ACOS") }, BUILDER(Create_func_acos)},
+ { { C_STRING_WITH_LEN("ADDTIME") }, BUILDER(Create_func_addtime)},
+ { { C_STRING_WITH_LEN("AES_DECRYPT") }, BUILDER(Create_func_aes_decrypt)},
+ { { C_STRING_WITH_LEN("AES_ENCRYPT") }, BUILDER(Create_func_aes_encrypt)},
+ { { C_STRING_WITH_LEN("AREA") }, GEOM_BUILDER(Create_func_area)},
+ { { C_STRING_WITH_LEN("ASBINARY") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { C_STRING_WITH_LEN("ASIN") }, BUILDER(Create_func_asin)},
+ { { C_STRING_WITH_LEN("ASTEXT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { C_STRING_WITH_LEN("ASWKB") }, GEOM_BUILDER(Create_func_as_wkb)},
+ { { C_STRING_WITH_LEN("ASWKT") }, GEOM_BUILDER(Create_func_as_wkt)},
+ { { C_STRING_WITH_LEN("ATAN") }, BUILDER(Create_func_atan)},
+ { { C_STRING_WITH_LEN("ATAN2") }, BUILDER(Create_func_atan)},
+ { { C_STRING_WITH_LEN("BENCHMARK") }, BUILDER(Create_func_benchmark)},
+ { { C_STRING_WITH_LEN("BIN") }, BUILDER(Create_func_bin)},
+ { { C_STRING_WITH_LEN("BIT_COUNT") }, BUILDER(Create_func_bit_count)},
+ { { C_STRING_WITH_LEN("BIT_LENGTH") }, BUILDER(Create_func_bit_length)},
+ { { C_STRING_WITH_LEN("CEIL") }, BUILDER(Create_func_ceiling)},
+ { { C_STRING_WITH_LEN("CEILING") }, BUILDER(Create_func_ceiling)},
+ { { C_STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
+ { { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
+ { { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
+ { { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
+ { { C_STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)},
+ { { C_STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)},
+ { { C_STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)},
+ { { C_STRING_WITH_LEN("CONNECTION_ID") }, BUILDER(Create_func_connection_id)},
+ { { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
+ { { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
+ { { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
+ { { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
+ { { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
+ { { C_STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
+ { { C_STRING_WITH_LEN("DATEDIFF") }, BUILDER(Create_func_datediff)},
+ { { C_STRING_WITH_LEN("DATE_FORMAT") }, BUILDER(Create_func_date_format)},
+ { { C_STRING_WITH_LEN("DAYNAME") }, BUILDER(Create_func_dayname)},
+ { { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
+ { { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
+ { { C_STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)},
+ { { C_STRING_WITH_LEN("DECODE") }, BUILDER(Create_func_decode)},
+ { { C_STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)},
+ { { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
+ { { C_STRING_WITH_LEN("DES_ENCRYPT") }, BUILDER(Create_func_des_encrypt)},
+ { { C_STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
+ { { C_STRING_WITH_LEN("DISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
+ { { C_STRING_WITH_LEN("ELT") }, BUILDER(Create_func_elt)},
+ { { C_STRING_WITH_LEN("ENCODE") }, BUILDER(Create_func_encode)},
+ { { C_STRING_WITH_LEN("ENCRYPT") }, BUILDER(Create_func_encrypt)},
+ { { C_STRING_WITH_LEN("ENDPOINT") }, GEOM_BUILDER(Create_func_endpoint)},
+ { { C_STRING_WITH_LEN("ENVELOPE") }, GEOM_BUILDER(Create_func_envelope)},
+ { { C_STRING_WITH_LEN("EQUALS") }, GEOM_BUILDER(Create_func_equals)},
+ { { C_STRING_WITH_LEN("EXP") }, BUILDER(Create_func_exp)},
+ { { C_STRING_WITH_LEN("EXPORT_SET") }, BUILDER(Create_func_export_set)},
+ { { C_STRING_WITH_LEN("EXTERIORRING") }, GEOM_BUILDER(Create_func_exteriorring)},
+ { { C_STRING_WITH_LEN("EXTRACTVALUE") }, BUILDER(Create_func_xml_extractvalue)},
+ { { C_STRING_WITH_LEN("FIELD") }, BUILDER(Create_func_field)},
+ { { C_STRING_WITH_LEN("FIND_IN_SET") }, BUILDER(Create_func_find_in_set)},
+ { { C_STRING_WITH_LEN("FLOOR") }, BUILDER(Create_func_floor)},
+ { { C_STRING_WITH_LEN("FORMAT") }, BUILDER(Create_func_format)},
+ { { C_STRING_WITH_LEN("FOUND_ROWS") }, BUILDER(Create_func_found_rows)},
+ { { C_STRING_WITH_LEN("FROM_DAYS") }, BUILDER(Create_func_from_days)},
+ { { C_STRING_WITH_LEN("FROM_UNIXTIME") }, BUILDER(Create_func_from_unixtime)},
+ { { C_STRING_WITH_LEN("GEOMCOLLFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("GEOMCOLLFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("GEOMETRYCOLLECTIONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("GEOMETRYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("GEOMETRYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("GEOMETRYN") }, GEOM_BUILDER(Create_func_geometryn)},
+ { { C_STRING_WITH_LEN("GEOMETRYTYPE") }, GEOM_BUILDER(Create_func_geometry_type)},
+ { { C_STRING_WITH_LEN("GEOMFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("GEOMFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("GET_LOCK") }, BUILDER(Create_func_get_lock)},
+ { { C_STRING_WITH_LEN("GLENGTH") }, GEOM_BUILDER(Create_func_glength)},
+ { { C_STRING_WITH_LEN("GREATEST") }, BUILDER(Create_func_greatest)},
+ { { C_STRING_WITH_LEN("HEX") }, BUILDER(Create_func_hex)},
+ { { C_STRING_WITH_LEN("IFNULL") }, BUILDER(Create_func_ifnull)},
+ { { C_STRING_WITH_LEN("INET_ATON") }, BUILDER(Create_func_inet_aton)},
+ { { C_STRING_WITH_LEN("INET_NTOA") }, BUILDER(Create_func_inet_ntoa)},
+ { { C_STRING_WITH_LEN("INSTR") }, BUILDER(Create_func_instr)},
+ { { C_STRING_WITH_LEN("INTERIORRINGN") }, GEOM_BUILDER(Create_func_interiorringn)},
+ { { C_STRING_WITH_LEN("INTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
+ { { C_STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
+ { { C_STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
+ { { C_STRING_WITH_LEN("ISNULL") }, BUILDER(Create_func_isnull)},
+ { { C_STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
+ { { C_STRING_WITH_LEN("IS_FREE_LOCK") }, BUILDER(Create_func_is_free_lock)},
+ { { C_STRING_WITH_LEN("IS_USED_LOCK") }, BUILDER(Create_func_is_used_lock)},
+ { { C_STRING_WITH_LEN("LAST_DAY") }, BUILDER(Create_func_last_day)},
+ { { C_STRING_WITH_LEN("LAST_INSERT_ID") }, BUILDER(Create_func_last_insert_id)},
+ { { C_STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
+ { { C_STRING_WITH_LEN("LEAST") }, BUILDER(Create_func_least)},
+ { { C_STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_length)},
+ { { C_STRING_WITH_LEN("LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("LN") }, BUILDER(Create_func_ln)},
+ { { C_STRING_WITH_LEN("LOAD_FILE") }, BUILDER(Create_func_load_file)},
+ { { C_STRING_WITH_LEN("LOCATE") }, BUILDER(Create_func_locate)},
+ { { C_STRING_WITH_LEN("LOG") }, BUILDER(Create_func_log)},
+ { { C_STRING_WITH_LEN("LOG10") }, BUILDER(Create_func_log10)},
+ { { C_STRING_WITH_LEN("LOG2") }, BUILDER(Create_func_log2)},
+ { { C_STRING_WITH_LEN("LOWER") }, BUILDER(Create_func_lcase)},
+ { { C_STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad)},
+ { { C_STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim)},
+ { { C_STRING_WITH_LEN("MAKEDATE") }, BUILDER(Create_func_makedate)},
+ { { C_STRING_WITH_LEN("MAKETIME") }, BUILDER(Create_func_maketime)},
+ { { C_STRING_WITH_LEN("MAKE_SET") }, BUILDER(Create_func_make_set)},
+ { { C_STRING_WITH_LEN("MASTER_POS_WAIT") }, BUILDER(Create_func_master_pos_wait)},
+ { { C_STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_contains)},
+ { { C_STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_disjoint)},
+ { { C_STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_equals)},
+ { { C_STRING_WITH_LEN("MBRINTERSECTS") }, GEOM_BUILDER(Create_func_intersects)},
+ { { C_STRING_WITH_LEN("MBROVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { C_STRING_WITH_LEN("MBRTOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { C_STRING_WITH_LEN("MBRWITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { C_STRING_WITH_LEN("MD5") }, BUILDER(Create_func_md5)},
+ { { C_STRING_WITH_LEN("MLINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MLINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("MONTHNAME") }, BUILDER(Create_func_monthname)},
+ { { C_STRING_WITH_LEN("MPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("MPOLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MPOLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("MULTILINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MULTILINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("MULTIPOINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MULTIPOINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("MULTIPOLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("MULTIPOLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("NAME_CONST") }, BUILDER(Create_func_name_const)},
+ { { C_STRING_WITH_LEN("NULLIF") }, BUILDER(Create_func_nullif)},
+ { { C_STRING_WITH_LEN("NUMGEOMETRIES") }, GEOM_BUILDER(Create_func_numgeometries)},
+ { { C_STRING_WITH_LEN("NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
+ { { C_STRING_WITH_LEN("NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
+ { { C_STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)},
+ { { C_STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_length)},
+ { { C_STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)},
+ { { C_STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_overlaps)},
+ { { C_STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)},
+ { { C_STRING_WITH_LEN("PERIOD_DIFF") }, BUILDER(Create_func_period_diff)},
+ { { C_STRING_WITH_LEN("PI") }, BUILDER(Create_func_pi)},
+ { { C_STRING_WITH_LEN("POINTFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("POINTFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("POINTN") }, GEOM_BUILDER(Create_func_pointn)},
+ { { C_STRING_WITH_LEN("POLYFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("POLYFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("POLYGONFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
+ { { C_STRING_WITH_LEN("POLYGONFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
+ { { C_STRING_WITH_LEN("POW") }, BUILDER(Create_func_pow)},
+ { { C_STRING_WITH_LEN("POWER") }, BUILDER(Create_func_pow)},
+ { { C_STRING_WITH_LEN("QUOTE") }, BUILDER(Create_func_quote)},
+ { { C_STRING_WITH_LEN("RADIANS") }, BUILDER(Create_func_radians)},
+ { { C_STRING_WITH_LEN("RAND") }, BUILDER(Create_func_rand)},
+ { { C_STRING_WITH_LEN("RELEASE_LOCK") }, BUILDER(Create_func_release_lock)},
+ { { C_STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
+ { { C_STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
+ { { C_STRING_WITH_LEN("ROW_COUNT") }, BUILDER(Create_func_row_count)},
+ { { C_STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
+ { { C_STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)},
+ { { C_STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)},
+ { { C_STRING_WITH_LEN("SHA") }, BUILDER(Create_func_sha)},
+ { { C_STRING_WITH_LEN("SHA1") }, BUILDER(Create_func_sha)},
+ { { C_STRING_WITH_LEN("SIGN") }, BUILDER(Create_func_sign)},
+ { { C_STRING_WITH_LEN("SIN") }, BUILDER(Create_func_sin)},
+ { { C_STRING_WITH_LEN("SLEEP") }, BUILDER(Create_func_sleep)},
+ { { C_STRING_WITH_LEN("SOUNDEX") }, BUILDER(Create_func_soundex)},
+ { { C_STRING_WITH_LEN("SPACE") }, BUILDER(Create_func_space)},
+ { { C_STRING_WITH_LEN("SQRT") }, BUILDER(Create_func_sqrt)},
+ { { C_STRING_WITH_LEN("SRID") }, GEOM_BUILDER(Create_func_srid)},
+ { { C_STRING_WITH_LEN("STARTPOINT") }, GEOM_BUILDER(Create_func_startpoint)},
+ { { C_STRING_WITH_LEN("STRCMP") }, BUILDER(Create_func_strcmp)},
+ { { C_STRING_WITH_LEN("STR_TO_DATE") }, BUILDER(Create_func_str_to_date)},
+ { { C_STRING_WITH_LEN("SUBSTRING_INDEX") }, BUILDER(Create_func_substr_index)},
+ { { C_STRING_WITH_LEN("SUBTIME") }, BUILDER(Create_func_subtime)},
+ { { C_STRING_WITH_LEN("TAN") }, BUILDER(Create_func_tan)},
+ { { C_STRING_WITH_LEN("TIMEDIFF") }, BUILDER(Create_func_timediff)},
+ { { C_STRING_WITH_LEN("TIME_FORMAT") }, BUILDER(Create_func_time_format)},
+ { { C_STRING_WITH_LEN("TIME_TO_SEC") }, BUILDER(Create_func_time_to_sec)},
+ { { C_STRING_WITH_LEN("TOUCHES") }, GEOM_BUILDER(Create_func_touches)},
+ { { C_STRING_WITH_LEN("TO_DAYS") }, BUILDER(Create_func_to_days)},
+ { { C_STRING_WITH_LEN("UCASE") }, BUILDER(Create_func_ucase)},
+ { { C_STRING_WITH_LEN("UNCOMPRESS") }, BUILDER(Create_func_uncompress)},
+ { { C_STRING_WITH_LEN("UNCOMPRESSED_LENGTH") }, BUILDER(Create_func_uncompressed_length)},
+ { { C_STRING_WITH_LEN("UNHEX") }, BUILDER(Create_func_unhex)},
+ { { C_STRING_WITH_LEN("UNIX_TIMESTAMP") }, BUILDER(Create_func_unix_timestamp)},
+ { { C_STRING_WITH_LEN("UPDATEXML") }, BUILDER(Create_func_xml_update)},
+ { { C_STRING_WITH_LEN("UPPER") }, BUILDER(Create_func_ucase)},
+ { { C_STRING_WITH_LEN("UUID") }, BUILDER(Create_func_uuid)},
+ { { C_STRING_WITH_LEN("VERSION") }, BUILDER(Create_func_version)},
+ { { C_STRING_WITH_LEN("WEEKDAY") }, BUILDER(Create_func_weekday)},
+ { { C_STRING_WITH_LEN("WEEKOFYEAR") }, BUILDER(Create_func_weekofyear)},
+ { { C_STRING_WITH_LEN("WITHIN") }, GEOM_BUILDER(Create_func_within)},
+ { { C_STRING_WITH_LEN("X") }, GEOM_BUILDER(Create_func_x)},
+ { { C_STRING_WITH_LEN("Y") }, GEOM_BUILDER(Create_func_y)},
+ { { C_STRING_WITH_LEN("YEARWEEK") }, BUILDER(Create_func_year_week)},
{ {0, 0}, NULL}
};
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 5c4e83d0e17..5e5d174a8c2 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4904,7 +4904,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
component_name= &component; // Empty string
}
- if (!(var= find_sys_var(base_name->str, base_name->length)))
+ if (!(var= find_sys_var(thd, base_name->str, base_name->length)))
return 0;
if (component.str)
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index f217a6ea953..9c0bfbe0256 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2479,7 +2479,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
- if (table->s->db_type == heap_hton)
+ if (table->s->db_type() == heap_hton)
{
/*
No blobs, otherwise it would have been MyISAM: set up a compare
diff --git a/sql/log.cc b/sql/log.cc
index 3cfcabd8363..bff43f2f662 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1917,8 +1917,8 @@ shutdown the MySQL server and restart it.", name, errno);
}
MYSQL_LOG::MYSQL_LOG()
- : name(0), log_type(LOG_UNKNOWN), log_state(LOG_CLOSED), write_error(FALSE),
- inited(FALSE)
+ : name(0), write_error(FALSE), inited(FALSE), log_type(LOG_UNKNOWN),
+ log_state(LOG_CLOSED)
{
/*
We don't want to initialize LOCK_Log here as such initialization depends on
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9b7b17cc498..43145e5c160 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -38,6 +38,7 @@
#include <queues.h>
#include "sql_bitmap.h"
#include "sql_array.h"
+#include "sql_plugin.h"
#include "scheduler.h"
/* TODO convert all these three maps to Bitmap classes */
@@ -549,11 +550,6 @@ inline THD *_current_thd(void)
}
#define current_thd _current_thd()
-/* below functions are required for plugins as THD class is opaque */
-my_bool thd_in_lock_tables(const THD *thd);
-my_bool thd_tablespace_op(const THD *thd);
-const char *thd_proc_info(THD *thd, const char *info);
-void **thd_ha_data(const THD *thd, const struct handlerton *hton);
/*
External variables
@@ -568,7 +564,6 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "sql_list.h"
#include "sql_map.h"
#include "my_decimal.h"
-#include "sql_plugin.h"
#include "handler.h"
#include "parse_file.h"
#include "table.h"
@@ -1116,6 +1111,7 @@ int add_status_vars(SHOW_VAR *list);
void remove_status_vars(SHOW_VAR *list);
void init_status_vars();
void free_status_vars();
+void reset_status_vars();
/* information schema */
extern LEX_STRING information_schema_name;
@@ -1710,6 +1706,7 @@ extern pthread_mutex_t LOCK_server_started;
extern pthread_cond_t COND_server_started;
extern int mysqld_server_started;
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
+extern rw_lock_t LOCK_system_variables_hash;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
extern pthread_cond_t COND_global_read_lock;
extern pthread_attr_t connection_attrib;
@@ -1718,7 +1715,7 @@ extern I_List<NAMED_LIST> key_caches;
extern MY_BITMAP temp_pool;
extern String my_empty_string;
extern const String my_null_string;
-extern SHOW_VAR init_vars[], status_vars[], internal_vars[];
+extern SHOW_VAR status_vars[];
extern struct system_variables global_system_variables;
extern struct system_variables max_system_variables;
extern struct system_status_var global_status_var;
@@ -1741,11 +1738,6 @@ extern TYPELIB log_output_typelib;
/* optional things, have_* variables */
-extern SHOW_COMP_OPTION have_innodb;
-extern SHOW_COMP_OPTION have_csv_db;
-extern SHOW_COMP_OPTION have_ndbcluster;
-extern SHOW_COMP_OPTION have_partition_db;
-
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
extern handlerton *heap_hton;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b70cf226803..9fa726734c8 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -29,22 +29,13 @@
#include "rpl_injector.h"
-#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
#ifndef DEFAULT_SKIP_THREAD_PRIORITY
@@ -317,7 +308,6 @@ static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
-static my_bool opt_ndbcluster;
static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created;
@@ -360,7 +350,6 @@ my_bool opt_local_infile, opt_slave_compressed_protocol;
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0;
-my_bool opt_innodb;
bool slave_warning_issued = false;
/*
@@ -370,45 +359,6 @@ handlerton *heap_hton;
handlerton *myisam_hton;
handlerton *partition_hton;
-#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_rollback_on_timeout,
- innobase_stats_on_metadata,
- 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;
const char *opt_ndb_connectstring= 0;
@@ -592,6 +542,7 @@ pthread_mutex_t LOCK_prepared_stmt_count;
pthread_mutex_t LOCK_des_key_file;
#endif
rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
+rw_lock_t LOCK_system_variables_hash;
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
pthread_t signal_thread;
pthread_attr_t connection_attrib;
@@ -623,6 +574,7 @@ static ulong opt_specialflag, opt_myisam_block_size;
static char *opt_update_logname, *opt_binlog_index_name;
static char *opt_tc_heuristic_recover;
static char *mysql_home_ptr, *pidfile_name_ptr;
+static int defaults_argc;
static char **defaults_argv;
static char *opt_bin_logname;
@@ -715,7 +667,9 @@ struct st_VioSSLFd *ssl_acceptor_fd;
pthread_handler_t signal_hand(void *arg);
static void mysql_init_variables(void);
-static void get_options(int argc,char **argv);
+static void get_options(int *argc,char **argv);
+static my_bool get_one_option(int, const struct my_option *, char *);
+static void usage(void);
static void set_server_version(void);
static int init_thread_environment();
static char *get_relative_path(const char *path);
@@ -1160,6 +1114,8 @@ void unireg_end(void)
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 */
@@ -1347,6 +1303,7 @@ static void clean_up_mutexes()
(void) rwlock_destroy(&LOCK_sys_init_connect);
(void) rwlock_destroy(&LOCK_sys_init_slave);
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
+ (void) rwlock_destroy(&LOCK_system_variables_hash);
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
(void) pthread_mutex_destroy(&LOCK_uuid_generator);
(void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
@@ -2347,7 +2304,7 @@ static void init_signals(void)
sigaddset(&set,SIGTSTP);
#endif
if (thd_lib_detected != THD_LIB_LT)
- sigaddset(&set,THR_SERVER_ALARM);
+ sigaddset(&set,THR_SERVER_ALARM);
if (test_flags & TEST_SIGINT)
{
// May be SIGINT
@@ -2705,7 +2662,7 @@ static bool init_global_datetime_format(timestamp_type format_type,
static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
{
- char buff[FN_REFLEN];
+ char buff[FN_REFLEN], *s;
umask(((~my_umask) & 0666));
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
tzset(); // Set tzname
@@ -2757,7 +2714,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
strmake(pidfile_name, STRING_WITH_LEN("mysql"));
}
else
- strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
+ strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
/*
@@ -2771,7 +2728,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
load_defaults(conf_file_name, groups, &argc, &argv);
defaults_argv=argv;
- get_options(argc,argv);
+ defaults_argc=argc;
+ get_options(&defaults_argc, defaults_argv);
set_server_version();
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
@@ -2783,10 +2741,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
{
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 */
@@ -2849,7 +2803,12 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (item_create_init())
return 1;
item_init();
- set_var_init();
+ if (set_var_init())
+ return 1;
+#ifdef HAVE_REPLICATION
+ if (init_replication_sys_vars())
+ return 1;
+#endif
mysys_uses_curses=0;
#ifdef USE_REGEX
my_regex_init(&my_charset_latin1);
@@ -2938,15 +2897,13 @@ static int init_common_variables(const char *conf_file_name, int argc,
"--log-slow-queries option, log tables are used. "
"To enable logging to files use the --log-output option.");
- if (!opt_logname)
- opt_logname= make_default_log_name(buff, ".log");
- sys_var_general_log_path.value= my_strdup(opt_logname, MYF(0));
- sys_var_general_log_path.value_length= strlen(opt_logname);
+ s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
+ sys_var_general_log_path.value= my_strdup(s, MYF(0));
+ sys_var_general_log_path.value_length= strlen(s);
- if (!opt_slow_logname)
- opt_slow_logname= make_default_log_name(buff, "-slow.log");
- sys_var_slow_log_path.value= my_strdup(opt_slow_logname, MYF(0));
- sys_var_slow_log_path.value_length= strlen(opt_slow_logname);
+ s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
+ sys_var_slow_log_path.value= my_strdup(s, MYF(0));
+ sys_var_slow_log_path.value_length= strlen(s);
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
@@ -3025,6 +2982,7 @@ static int init_thread_environment()
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
+ (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
(void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
@@ -3298,13 +3256,13 @@ with --log-bin instead.");
}
if (!opt_bin_log)
if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
- {
- sql_print_error("You need to use --log-bin to make "
- "--binlog-format work.");
- unireg_abort(1);
- }
+ {
+ sql_print_error("You need to use --log-bin to make "
+ "--binlog-format work.");
+ unireg_abort(1);
+ }
else
- {
+ {
global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
}
else
@@ -3313,7 +3271,7 @@ with --log-bin instead.");
else
{
DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
- }
+ }
/* Check that we have not let the format to unspecified at this point */
DBUG_ASSERT((uint)global_system_variables.binlog_format <=
@@ -3367,10 +3325,45 @@ server.");
using_update_log=1;
}
- if (plugin_init(opt_bootstrap))
+ if (plugin_init(&defaults_argc, defaults_argv,
+ (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
+ (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
{
- sql_print_error("Failed to init plugins.");
- return 1;
+ sql_print_error("Failed to initialize plugins.");
+ unireg_abort(1);
+ }
+
+ if (opt_help)
+ unireg_abort(0);
+
+ /* we do want to exit if there are any other unknown options */
+ if (defaults_argc > 1)
+ {
+ int ho_error;
+ char **tmp_argv= defaults_argv;
+ struct my_option no_opts[]=
+ {
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+ };
+ /*
+ We need to eat any 'loose' arguments first before we conclude
+ that there are unprocessed options.
+ But we need to preserve defaults_argv pointer intact for
+ free_defaults() to work. Thus we use a copy here.
+ */
+ my_getopt_skip_unknown= 0;
+
+ if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
+ get_one_option)))
+ unireg_abort(ho_error);
+
+ if (defaults_argc)
+ {
+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
+ "Use --verbose --help to get a list of available options\n",
+ my_progname, *tmp_argv);
+ unireg_abort(1);
+ }
}
/* We have to initialize the storage engines before CSV logging */
@@ -3401,7 +3394,8 @@ server.");
else
{
/* fall back to the log files if tables are not present */
- if (have_csv_db == SHOW_OPTION_NO)
+ LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
+ if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
{
/* purecov: begin inspected */
sql_print_error("CSV engine is not present, falling back to the "
@@ -3421,11 +3415,16 @@ server.");
/*
Check that the default storage engine is actually available.
*/
+ if (default_storage_engine_str)
{
LEX_STRING name= { default_storage_engine_str,
strlen(default_storage_engine_str) };
- handlerton *hton= ha_resolve_by_name(0, &name);
- if (hton == NULL)
+ plugin_ref plugin;
+ handlerton *hton;
+
+ if ((plugin= ha_resolve_by_name(0, &name)))
+ hton= plugin_data(plugin, handlerton*);
+ else
{
sql_print_error("Unknown/unsupported table type: %s",
default_storage_engine_str);
@@ -3439,9 +3438,17 @@ server.");
default_storage_engine_str);
unireg_abort(1);
}
- hton= myisam_hton;
+ DBUG_ASSERT(global_system_variables.table_plugin);
+ }
+ else
+ {
+ /*
+ Need to unlock as global_system_variables.table_plugin
+ was acquired during plugin_init()
+ */
+ plugin_unlock(0, global_system_variables.table_plugin);
+ global_system_variables.table_plugin= plugin;
}
- global_system_variables.table_type= hton;
}
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
@@ -4851,11 +4858,6 @@ enum options_mysqld
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,
@@ -4874,28 +4876,14 @@ enum options_mysqld
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_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
@@ -4958,34 +4946,6 @@ enum options_mysqld
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_INNODB_STATS_ON_METADATA,
- 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,
@@ -4995,7 +4955,6 @@ enum options_mysqld
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,
@@ -5025,12 +4984,12 @@ enum options_mysqld
OPT_OLD_STYLE_USER_LIMITS,
OPT_LOG_SLOW_ADMIN_STATEMENTS,
OPT_TABLE_LOCK_WAIT_TIMEOUT,
+ OPT_PLUGIN_LOAD,
OPT_PLUGIN_DIR,
OPT_LOG_OUTPUT,
OPT_PORT_OPEN_TIMEOUT,
OPT_GENERAL_LOG,
OPT_SLOW_LOG,
- OPT_MERGE,
OPT_THREAD_HANDLING,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_SECURE_FILE_PRIV,
@@ -5252,98 +5211,6 @@ Disable with --skip-large-pages.",
{"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},
- {"innodb", OPT_INNODB, "Enable InnoDB (if this version of MySQL supports it). \
-Disable with --skip-innodb (will save memory).",
- (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, OPT_INNODB_DEFAULT, 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_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT,
- "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
- (gptr*) &innobase_rollback_on_timeout, (gptr*) &innobase_rollback_on_timeout,
- 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 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_stats_on_metadata", OPT_INNODB_STATS_ON_METADATA,
- "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
- (gptr*) &innobase_stats_on_metadata, (gptr*) &innobase_stats_on_metadata,
- 0, GET_BOOL, NO_ARG, 1, 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,
@@ -5517,10 +5384,6 @@ master-ssl",
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
(gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"ndbcluster", OPT_NDBCLUSTER, "Enable NDB Cluster (if this version of MySQL supports it). \
-Disable with --skip-ndbcluster (will save memory).",
- (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG,
- OPT_NDBCLUSTER_DEFAULT, 0, 0, 0, 0, 0},
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
{"ndb-connectstring", OPT_NDB_CONNECTSTRING,
"Connect string for ndbcluster.",
@@ -5980,84 +5843,6 @@ log and this option does nothing anymore.",
(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,
@@ -6287,6 +6072,11 @@ The minimum value for this variable is 4096.",
"Directory for plugins.",
(gptr*) &opt_plugin_dir_ptr, (gptr*) &opt_plugin_dir_ptr, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin_load", OPT_PLUGIN_LOAD,
+ "Optional colon separated list of plugins to load, where each plugin is "
+ "identified by name and path to library seperated by an equals.",
+ (gptr*) &opt_plugin_load, (gptr*) &opt_plugin_load, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
@@ -7101,8 +6891,8 @@ Starts the MySQL database server\n");
fix_paths();
set_ports();
- my_print_help(my_long_options);
- my_print_variables(my_long_options);
+ /* Print out all the options including plugin supplied options */
+ my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
puts("\n\
To see what values a running MySQL server is using, type\n\
@@ -7145,6 +6935,7 @@ static void mysql_init_variables(void)
mqh_used= 0;
segfaulted= kill_in_progress= 0;
cleanup_done= 0;
+ defaults_argc= 0;
defaults_argv= 0;
server_id_supplied= 0;
test_flags= select_errors= dropping_tables= ha_open_options=0;
@@ -7232,7 +7023,7 @@ static void mysql_init_variables(void)
/* Set default values for some option variables */
default_storage_engine_str= (char*) "MyISAM";
- global_system_variables.table_type= myisam_hton;
+ global_system_variables.table_plugin= NULL;
global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
max_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
@@ -7253,36 +7044,13 @@ static void mysql_init_variables(void)
"d:t:i:o,/tmp/mysqld.trace");
#endif
opt_error_log= IF_WIN(1,0);
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
- have_innodb= SHOW_OPTION_YES;
-#else
- have_innodb= SHOW_OPTION_NO;
-#endif
-#ifdef WITH_CSV_STORAGE_ENGINE
- have_csv_db= SHOW_OPTION_YES;
-#else
- have_csv_db= SHOW_OPTION_NO;
-#endif
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- have_ndbcluster= SHOW_OPTION_DISABLED;
-#else
- have_ndbcluster= SHOW_OPTION_NO;
-#endif
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- have_partition_db= SHOW_OPTION_YES;
-#else
- have_partition_db= SHOW_OPTION_NO;
-#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- have_ndbcluster=SHOW_OPTION_DISABLED;
global_system_variables.ndb_index_stat_enable=FALSE;
max_system_variables.ndb_index_stat_enable=TRUE;
global_system_variables.ndb_index_stat_cache_entries=32;
max_system_variables.ndb_index_stat_cache_entries=~0L;
global_system_variables.ndb_index_stat_update_freq=20;
max_system_variables.ndb_index_stat_update_freq=~0L;
-#else
- have_ndbcluster=SHOW_OPTION_NO;
#endif
#ifdef HAVE_OPENSSL
have_ssl=SHOW_OPTION_YES;
@@ -7593,7 +7361,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#endif
case OPT_EVENT_SCHEDULER:
if (Events::set_opt_event_scheduler(argument))
- exit(1);
+ exit(1);
break;
case (int) OPT_SKIP_NEW:
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
@@ -7753,17 +7521,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
global_system_variables.tx_isolation= (type-1);
break;
}
- case OPT_MERGE:
- case OPT_BDB:
- break;
- case OPT_NDBCLUSTER:
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- if (opt_ndbcluster)
- have_ndbcluster= SHOW_OPTION_YES;
- else
- have_ndbcluster= SHOW_OPTION_DISABLED;
-#endif
- break;
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
case OPT_NDB_MGMD:
case OPT_NDB_NODEID:
@@ -7811,24 +7568,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
ndb_extra_logging= atoi(argument);
break;
#endif
- case OPT_INNODB:
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
- if (opt_innodb)
- have_innodb= SHOW_OPTION_YES;
- else
- have_innodb= SHOW_OPTION_DISABLED;
-#endif
- 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])
@@ -7982,7 +7721,7 @@ static void option_error_reporter(enum loglevel level, const char *format, ...)
}
-static void get_options(int argc,char **argv)
+static void get_options(int *argc,char **argv)
{
int ho_error;
@@ -7990,34 +7729,20 @@ static void get_options(int argc,char **argv)
strmake(def_ft_boolean_syntax, ft_boolean_syntax,
sizeof(ft_boolean_syntax)-1);
my_getopt_error_reporter= option_error_reporter;
- if ((ho_error= handle_options(&argc, &argv, my_long_options,
+
+ /* 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)))
exit(ho_error);
+ (*argc)++; /* add back one for the progname handle_options removes */
+ /* no need to do this for argv as we are discarding it. */
-#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
- if (opt_ndbcluster)
- sql_print_warning("this binary does not contain NDBCLUSTER storage engine");
-#endif
-#ifndef WITH_INNOBASE_STORAGE_ENGINE
- if (opt_innodb)
- sql_print_warning("this binary does not contain INNODB storage engine");
-#endif
if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) &&
!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 (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? */
- exit(1);
- }
-
- if (opt_help)
- {
- usage();
- exit(0);
- }
#if defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
@@ -8346,12 +8071,7 @@ void refresh_status(THD *thd)
bzero((char*) &thd->status_var, sizeof(thd->status_var));
/* Reset some global variables */
- for (SHOW_VAR *ptr= status_vars; ptr->name; ptr++)
- {
- /* Note that SHOW_LONG_NOFLUSH variables are not reset */
- if (ptr->type == SHOW_LONG)
- *(ulong*) ptr->value= 0;
- }
+ reset_status_vars();
/* Reset the counters of all key caches (default and named). */
process_key_caches(reset_key_cache_counters);
@@ -8370,51 +8090,9 @@ void refresh_status(THD *thd)
/*****************************************************************************
- Instantiate have_xyx for missing storage engines
+ Instantiate variables for missing storage engines
+ This section should go away soon
*****************************************************************************/
-#undef have_innodb
-#undef have_ndbcluster
-#undef have_csv_db
-
-SHOW_COMP_OPTION have_innodb= SHOW_OPTION_NO;
-SHOW_COMP_OPTION have_ndbcluster= SHOW_OPTION_NO;
-SHOW_COMP_OPTION have_csv_db= SHOW_OPTION_NO;
-SHOW_COMP_OPTION have_partition_db= SHOW_OPTION_NO;
-
-#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,
- innobase_rollback_on_timeout,
- innobase_stats_on_metadata;
-
-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;
diff --git a/sql/partition_element.h b/sql/partition_element.h
index c056d40b85b..905bc38165b 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -84,9 +84,9 @@ public:
partition_element(partition_element *part_elem)
: part_max_rows(part_elem->part_max_rows),
part_min_rows(part_elem->part_min_rows),
- partition_name(NULL),
+ range_value(0), partition_name(NULL),
tablespace_name(part_elem->tablespace_name),
- range_value(0), part_comment(part_elem->part_comment),
+ part_comment(part_elem->part_comment),
data_file_name(part_elem->data_file_name),
index_file_name(part_elem->index_file_name),
engine_type(part_elem->engine_type),
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 17879a9ecfc..82992eec690 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -59,7 +59,7 @@ public:
@param size Number of elements in array 'types'
*/
table_def(field_type *types, my_size_t size)
- : m_type(new unsigned char [size]), m_size(size)
+ : m_size(size), m_type(new unsigned char [size])
{
if (m_type)
memcpy(m_type, types, size);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index bdbd7b080d0..dd271ddcae6 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -27,8 +27,6 @@
of it in the my_option structure list in mysqld.cc
- Don't forget to initialize new fields in global_system_variables and
max_system_variables!
- - If the variable should show up in 'show variables' add it to the
- init_vars[] struct in this file
NOTES:
- Be careful with var->save_result: sys_var::check() only updates
@@ -58,41 +56,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,
- innobase_rollback_on_timeout,
- innobase_stats_on_metadata;
-
-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;
extern ulong ndb_extra_logging;
@@ -101,9 +64,12 @@ extern ulong ndb_report_thresh_binlog_epoch_slip;
extern ulong ndb_report_thresh_binlog_mem_usage;
#endif
+extern CHARSET_INFO *character_set_filesystem;
+static DYNAMIC_ARRAY fixed_show_vars;
static HASH system_variable_hash;
+
const char *bool_type_names[]= { "OFF", "ON", NullS };
TYPELIB bool_typelib=
{
@@ -170,888 +136,564 @@ static void sys_default_slow_log_path(THD *thd, enum_var_type type);
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",
+static 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",
+static 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",
+static 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",
+static sys_var_const_str sys_basedir(&vars, "basedir", mysql_home);
+static 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",
+static 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",
+static 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",
+static sys_var_character_set_sv sys_character_set_server(&vars, "character_set_server",
+ &SV::collation_server,
+ &default_charset_info);
+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",
+static sys_var_character_set_database sys_character_set_database(&vars, "character_set_database");
+static sys_var_character_set_sv sys_character_set_client(&vars, "character_set_client",
+ &SV::character_set_client,
+ &default_charset_info);
+static sys_var_character_set_sv sys_character_set_connection(&vars, "character_set_connection",
+ &SV::collation_connection,
+ &default_charset_info);
+static sys_var_character_set_sv sys_character_set_results(&vars, "character_set_results",
+ &SV::character_set_results,
+ &default_charset_info, true);
+static sys_var_character_set_sv sys_character_set_filesystem(&vars, "character_set_filesystem",
+ &SV::character_set_filesystem,
+ &character_set_filesystem);
+static 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",
+static sys_var_collation_sv sys_collation_connection(&vars, "collation_connection",
+ &SV::collation_connection,
+ &default_charset_info);
+static sys_var_collation_sv sys_collation_database(&vars, "collation_database",
+ &SV::collation_database,
+ &default_charset_info);
+static sys_var_collation_sv sys_collation_server(&vars, "collation_server",
+ &SV::collation_server,
+ &default_charset_info);
+static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert",
&myisam_concurrent_insert);
-sys_var_long_ptr sys_connect_timeout("connect_timeout",
+static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
&connect_timeout);
-sys_var_const_str sys_datadir("datadir", mysql_real_data_home);
+static sys_var_const_str sys_datadir(&vars, "datadir", mysql_real_data_home);
#ifndef DBUG_OFF
-sys_var_thd_dbug sys_dbug("debug");
+static sys_var_thd_dbug sys_dbug(&vars, "debug");
#endif
-sys_var_enum sys_delay_key_write("delay_key_write",
+static 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",
+static 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",
+static 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",
+static 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",
+static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
+static 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",
+static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
+static sys_var_long_ptr sys_flush_time(&vars, "flush_time", &flush_time);
+static 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",
+static 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",
+static 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",
+static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
+static 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",
+static 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",
+static 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",
+static 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",
+static sys_var_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",
+static sys_var_bool_ptr
+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",
+static sys_var_bool_ptr
+ 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",
+static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static sys_var_max_user_conn sys_max_user_connections(&vars, "max_user_connections");
+static 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",
+static 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",
+static 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",
+static 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",
+static 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);
+static sys_var_thd_ulong sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads);
+static sys_var_thd_ulong sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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_bool_ptr_readonly sys_old_mode("old",
+static sys_var_thd_bool sys_new_mode(&vars, "new", &SV::new_mode);
+static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
&global_system_variables.old_mode);
-sys_var_thd_bool sys_old_alter_table("old_alter_table",
+static 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);
+static 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",
+static 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",
+static 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",
+static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size",
&SV::read_buff_size);
-sys_var_opt_readonly sys_readonly("read_only", &opt_readonly);
-sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly);
+static 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",
+static 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",
- &relay_log_purge);
-#endif
-sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+static 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",
+static 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",
+static 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",
+static 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",
+static 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",
+static sys_var_readonly sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
+static 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",
+static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
&SV::trans_prealloc_size,
0, fix_trans_mem_root);
-sys_var_thd_enum sys_thread_handling("thread_handling",
+sys_var_thd_enum sys_thread_handling(&vars, "thread_handling",
&SV::thread_handling,
&thread_handling_typelib,
NULL);
#ifdef HAVE_QUERY_CACHE
-sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
+static 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",
+static 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",
+static 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",
+static sys_var_thd_bool
+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_const_str_ptr sys_secure_file_priv("secure_file_priv",
+static sys_var_bool_ptr sys_secure_auth(&vars, "secure_auth", &opt_secure_auth);
+static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
&opt_secure_file_priv);
-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",
+static sys_var_long_ptr sys_server_id(&vars, "server_id", &server_id, fix_server_id);
+static 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",
- &slave_net_timeout);
-sys_var_long_ptr sys_slave_trans_retries("slave_transaction_retries",
- &slave_trans_retries);
-#endif
-sys_var_long_ptr sys_slow_launch_time("slow_launch_time",
+static 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",
+static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size",
&SV::sortbuff_size);
-sys_var_thd_sql_mode sys_sql_mode("sql_mode",
+static 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);
+static sys_var_const_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca);
+static sys_var_const_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath);
+static sys_var_const_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert);
+static sys_var_const_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher);
+static 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);
+static sys_var_const_str sys_ssl_ca(&vars, "ssl_ca", NULL);
+static sys_var_const_str sys_ssl_capath(&vars, "ssl_capath", NULL);
+static sys_var_const_str sys_ssl_cert(&vars, "ssl_cert", NULL);
+static sys_var_const_str sys_ssl_cipher(&vars, "ssl_cipher", NULL);
+static 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",
+static sys_var_thd_enum
+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",
- &SV::table_type);
-sys_var_thd_storage_engine sys_storage_engine("storage_engine",
- &SV::table_type);
-#ifdef HAVE_REPLICATION
-sys_var_sync_binlog_period sys_sync_binlog_period("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",
+static sys_var_thd_table_type sys_table_type(&vars, "table_type",
+ &SV::table_plugin);
+static sys_var_thd_storage_engine sys_storage_engine(&vars, "storage_engine",
+ &SV::table_plugin);
+static sys_var_bool_ptr sys_sync_frm(&vars, "sync_frm", &opt_sync_frm);
+static 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",
+static 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",
+static 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",
+static 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",
+static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
&thread_cache_size);
#if HAVE_POOL_OF_THREADS == 1
-sys_var_long_ptr sys_thread_pool_size("thread_pool_size",
+sys_var_long_ptr sys_thread_pool_size(&vars, "thread_pool_size",
&thread_pool_size);
#endif
-sys_var_thd_enum sys_tx_isolation("tx_isolation",
+static 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",
+static 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",
+static 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",
+static sys_var_const_str sys_version(&vars, "version", server_version);
+static sys_var_const_str sys_version_comment(&vars, "version_comment",
MYSQL_COMPILATION_COMMENT);
-sys_var_const_str sys_version_compile_machine("version_compile_machine",
+static 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",
+static sys_var_const_str sys_version_compile_os(&vars, "version_compile_os",
SYSTEM_TYPE);
-sys_var_thd_ulong sys_net_wait_timeout("wait_timeout",
+static 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",
+static sys_var_thd_bool
+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",
+static sys_var_thd_ulong
+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);
+static sys_var_thd_bool
+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",
+static sys_var_long_ptr
+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",
+static sys_var_long_ptr
+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_var_thd_bool
-sys_ndb_use_transactions("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_var_thd_bool
-sys_ndb_index_stat_enable("ndb_index_stat_enable",
+static sys_var_thd_bool
+sys_ndb_use_exact_count(&vars, "ndb_use_exact_count", &SV::ndb_use_exact_count);
+static sys_var_thd_bool
+sys_ndb_use_transactions(&vars, "ndb_use_transactions", &SV::ndb_use_transactions);
+static sys_var_long_ptr
+sys_ndb_cache_check_time(&vars, "ndb_cache_check_time", &ndb_cache_check_time);
+static sys_var_thd_bool
+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",
+static sys_var_thd_ulong
+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",
+static sys_var_thd_ulong
+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_var_thd_bool
-sys_ndb_use_copying_alter_table("ndb_use_copying_alter_table", &SV::ndb_use_copying_alter_table);
+static sys_var_long_ptr
+sys_ndb_extra_logging(&vars, "ndb_extra_logging", &ndb_extra_logging);
+static sys_var_thd_bool
+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",
+static 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",
+static 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",
+static 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");
-#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");
+
+/* Global read-only variable containing hostname */
+static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
/* Read only variables */
-/* Global read-only variable containing hostname */
-sys_var_const_str sys_hostname("hostname", glob_hostname);
-
-
-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_csv_db("have_csv", &have_csv_db);
-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_innodb("have_innodb", &have_innodb);
-sys_var_have_variable sys_have_ndbcluster("have_ndbcluster", &have_ndbcluster);
-sys_var_have_variable sys_have_openssl("have_openssl", &have_ssl);
-sys_var_have_variable sys_have_ssl("have_ssl", &have_ssl);
-sys_var_have_variable sys_have_partition_db("have_partitioning",
- &have_partition_db);
-sys_var_have_variable sys_have_query_cache("have_query_cache",
+static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
+static sys_var_have_variable sys_have_crypt(&vars, "have_crypt", &have_crypt);
+static sys_var_have_plugin sys_have_csv(&vars, "have_csv", C_STRING_WITH_LEN("csv"), MYSQL_STORAGE_ENGINE_PLUGIN);
+static sys_var_have_variable sys_have_dlopen(&vars, "have_dynamic_loading", &have_dlopen);
+static sys_var_have_variable sys_have_geometry(&vars, "have_geometry", &have_geometry);
+static sys_var_have_plugin sys_have_innodb(&vars, "have_innodb", C_STRING_WITH_LEN("innodb"), MYSQL_STORAGE_ENGINE_PLUGIN);
+static sys_var_have_plugin sys_have_ndbcluster(&vars, "have_ndbcluster", C_STRING_WITH_LEN("ndbcluster"), MYSQL_STORAGE_ENGINE_PLUGIN);
+static sys_var_have_variable sys_have_openssl(&vars, "have_openssl", &have_openssl);
+static sys_var_have_plugin sys_have_partition_db(&vars, "have_partitioning", C_STRING_WITH_LEN("partition"), MYSQL_STORAGE_ENGINE_PLUGIN);
+static 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);
+static sys_var_have_variable sys_have_rtree_keys(&vars, "have_rtree_keys", &have_rtree_keys);
+static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
/* Global read-only variable describing server license */
-sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
+static 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,
+static 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,
+static 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,
+static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
&log_output_typelib, 0);
-#ifdef HAVE_REPLICATION
-static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
-{
- var->type=SHOW_CHAR;
- var->value= buff;
- if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
- {
- var->value= const_cast<char *>("OFF");
- }
- else if (bitmap_is_set_all(&slave_error_mask))
- {
- var->value= const_cast<char *>("ALL");
- }
- else
- {
- /* 10 is enough assuming errors are max 4 digits */
- int i;
- var->value= buff;
- for (i= 1;
- i < MAX_SLAVE_ERROR &&
- (buff - var->value) < SHOW_VAR_FUNC_BUFF_SIZE;
- i++)
- {
- if (bitmap_is_set(&slave_error_mask, i))
- {
- buff= int10_to_str(i, buff, 10);
- *buff++= ',';
- }
- }
- if (var->value != buff)
- buff--; // Remove last ','
- if (i < MAX_SLAVE_ERROR)
- buff= strmov(buff, "..."); // Couldn't show all errors
- *buff=0;
- }
- return 0;
-}
-#endif /* HAVE_REPLICATION */
/*
- Variables shown by SHOW VARIABLES in alphabetical order
+ Additional variables (not derived from sys_var class, not accessible as
+ @@varname in SELECT or SET). Sorted in alphabetical order to facilitate
+ maintenance - SHOW VARIABLES will sort its output.
+ TODO: remove this list completely
*/
-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},
+#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR))
+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_hostname.name, (char*) &sys_hostname, SHOW_SYS},
- {sys_have_compress.name, (char*) &have_compress, SHOW_HAVE},
- {sys_have_crypt.name, (char*) &have_crypt, SHOW_HAVE},
- {sys_have_csv_db.name, (char*) &have_csv_db, SHOW_HAVE},
- {sys_have_dlopen.name, (char*) &have_dlopen, SHOW_HAVE},
- {sys_have_geometry.name, (char*) &have_geometry, SHOW_HAVE},
- {sys_have_innodb.name, (char*) &have_innodb, SHOW_HAVE},
- {sys_have_ndbcluster.name, (char*) &have_ndbcluster, SHOW_HAVE},
- {sys_have_openssl.name, (char*) &have_ssl, SHOW_HAVE},
- {sys_have_ssl.name, (char*) &have_ssl, SHOW_HAVE},
- {sys_have_partition_db.name,(char*) &have_partition_db, SHOW_HAVE},
- {sys_have_query_cache.name, (char*) &have_query_cache, 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 },
- {"innodb_rollback_on_timeout", (char*) &innobase_rollback_on_timeout, SHOW_MY_BOOL},
- {"innodb_stats_on_metadata", (char*) &innobase_stats_on_metadata, SHOW_MY_BOOL},
- {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},
+ {"locked_in_memory", (char*) &locked_in_memory, SHOW_MY_BOOL},
#endif
- {"log", (char*) &opt_log, SHOW_BOOL},
+ {"log", (char*) &opt_log, SHOW_MY_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_MY_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_mode.name, (char*) &sys_old_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},
+ {"port", (char*) &mysqld_port, SHOW_INT},
{"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},
- {"secure_file_priv", (char*) &sys_secure_file_priv, 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},
+ {"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR},
#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
- {sys_thread_handling.name, (char*) &sys_thread_handling, SHOW_SYS},
-#if HAVE_POOL_OF_THREADS == 1
- {sys_thread_pool_size.name, (char*) &sys_thread_pool_size, SHOW_SYS},
-#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}
};
@@ -1346,7 +988,8 @@ bool sys_var_thd_binlog_format::is_readonly() const
/*
Cluster does not support changing the binlog format on the fly yet.
*/
- if (opt_bin_log && (have_ndbcluster == SHOW_OPTION_YES))
+ 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));
return 1;
@@ -1437,9 +1080,9 @@ static void fix_server_id(THD *thd, enum_var_type type)
sys_var_long_ptr::
-sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg,
+sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
sys_after_update_func after_update_arg)
- :sys_var_long_ptr_global(name_arg, value_ptr_arg,
+ :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
&LOCK_global_system_variables, after_update_arg)
{}
@@ -1823,7 +1466,13 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
return new Item_int((longlong) value);
}
case SHOW_MY_BOOL:
- return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type, base),1);
+ {
+ int32 value;
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ value= *(my_bool*) value_ptr(thd, var_type, base);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return new Item_int(value,1);
+ }
case SHOW_CHAR:
{
Item *tmp;
@@ -2132,122 +1781,25 @@ byte *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
}
-CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd,
- enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- return &global_system_variables.collation_connection;
- else
- return &thd->variables.collation_connection;
-}
-
-
-void sys_var_character_set_connection::set_default(THD *thd,
- enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.collation_connection= default_charset_info;
- else
- {
- thd->variables.collation_connection= global_system_variables.collation_connection;
- thd->update_charset();
- }
-}
-
-
-CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd,
- enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- return &global_system_variables.character_set_client;
- else
- return &thd->variables.character_set_client;
-}
-
-
-void sys_var_character_set_client::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.character_set_client= default_charset_info;
- else
- {
- thd->variables.character_set_client= (global_system_variables.
- character_set_client);
- thd->update_charset();
- }
-}
-
-
-CHARSET_INFO **
-sys_var_character_set_filesystem::ci_ptr(THD *thd, enum_var_type type)
+void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
- return &global_system_variables.character_set_filesystem;
+ global_system_variables.*offset= *global_default;
else
- return &thd->variables.character_set_filesystem;
-}
-
-
-extern CHARSET_INFO *character_set_filesystem;
-
-void
-sys_var_character_set_filesystem::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.character_set_filesystem= character_set_filesystem;
- else
- {
- thd->variables.character_set_filesystem= (global_system_variables.
- character_set_filesystem);
- thd->update_charset();
- }
-}
-
-
-CHARSET_INFO **
-sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- return &global_system_variables.character_set_results;
- else
- return &thd->variables.character_set_results;
-}
-
-
-void sys_var_character_set_results::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.character_set_results= default_charset_info;
- else
- {
- thd->variables.character_set_results= (global_system_variables.
- character_set_results);
- thd->update_charset();
- }
+ {
+ thd->variables.*offset= global_system_variables.*offset;
+ thd->update_charset();
+ }
}
-
-
-CHARSET_INFO **
-sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type)
+CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
- return &global_system_variables.collation_server;
+ return &(global_system_variables.*offset);
else
- return &thd->variables.collation_server;
+ return &(thd->variables.*offset);
}
-void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.collation_server= default_charset_info;
- else
- {
- thd->variables.collation_server= global_system_variables.collation_server;
- thd->update_charset();
- }
-}
-
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
enum_var_type type)
{
@@ -2270,113 +1822,39 @@ void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
}
-bool sys_var_collation_connection::update(THD *thd, set_var *var)
+bool sys_var_collation_sv::update(THD *thd, set_var *var)
{
if (var->type == OPT_GLOBAL)
- global_system_variables.collation_connection= var->save_result.charset;
+ global_system_variables.*offset= var->save_result.charset;
else
{
- thd->variables.collation_connection= var->save_result.charset;
+ thd->variables.*offset= var->save_result.charset;
thd->update_charset();
}
return 0;
}
-byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
+void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
{
- CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
- global_system_variables.collation_connection :
- thd->variables.collation_connection);
- return cs ? (byte*) cs->name : (byte*) "NULL";
-}
-
-
-void sys_var_collation_connection::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.collation_connection= default_charset_info;
- else
- {
- thd->variables.collation_connection= (global_system_variables.
- collation_connection);
- thd->update_charset();
- }
-}
-
-bool sys_var_collation_database::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.collation_database= var->save_result.charset;
- else
- {
- thd->variables.collation_database= var->save_result.charset;
- thd->update_charset();
- }
- return 0;
-}
-
-
-byte *sys_var_collation_database::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
- global_system_variables.collation_database :
- thd->variables.collation_database);
- return cs ? (byte*) cs->name : (byte*) "NULL";
-}
-
-
-void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.collation_database= default_charset_info;
- else
- {
- thd->variables.collation_database= (global_system_variables.
- collation_database);
- thd->update_charset();
- }
-}
-
-
-bool sys_var_collation_server::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.collation_server= var->save_result.charset;
+ if (type == OPT_GLOBAL)
+ global_system_variables.*offset= *global_default;
else
{
- thd->variables.collation_server= var->save_result.charset;
+ thd->variables.*offset= global_system_variables.*offset;
thd->update_charset();
}
- return 0;
}
-byte *sys_var_collation_server::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
+byte *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{
CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
- global_system_variables.collation_server :
- thd->variables.collation_server);
+ global_system_variables.*offset : thd->variables.*offset);
return cs ? (byte*) cs->name : (byte*) "NULL";
}
-void sys_var_collation_server::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.collation_server= default_charset_info;
- else
- {
- thd->variables.collation_server= (global_system_variables.
- collation_server);
- thd->update_charset();
- }
-}
-
-
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
static KEY_CACHE zero_key_cache;
@@ -2818,52 +2296,6 @@ byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
}
-#ifdef HAVE_REPLICATION
-bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
-{
- int result= 0;
- pthread_mutex_lock(&LOCK_active_mi);
- pthread_mutex_lock(&active_mi->rli.run_lock);
- if (active_mi->rli.slave_running)
- {
- my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
- result=1;
- }
- pthread_mutex_unlock(&active_mi->rli.run_lock);
- pthread_mutex_unlock(&LOCK_active_mi);
- var->save_result.ulong_value= (ulong) var->value->val_int();
- return result;
-}
-
-
-bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
-{
- pthread_mutex_lock(&LOCK_active_mi);
- pthread_mutex_lock(&active_mi->rli.run_lock);
- /*
- The following test should normally never be true as we test this
- in the check function; To be safe against multiple
- SQL_SLAVE_SKIP_COUNTER request, we do the check anyway
- */
- if (!active_mi->rli.slave_running)
- {
- pthread_mutex_lock(&active_mi->rli.data_lock);
- active_mi->rli.slave_skip_counter= var->save_result.ulong_value;
- pthread_mutex_unlock(&active_mi->rli.data_lock);
- }
- pthread_mutex_unlock(&active_mi->rli.run_lock);
- pthread_mutex_unlock(&LOCK_active_mi);
- return 0;
-}
-
-
-bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
-{
- sync_binlog_period= (ulong) var->save_result.ulonglong_value;
- return 0;
-}
-#endif /* HAVE_REPLICATION */
-
bool sys_var_rand_seed1::update(THD *thd, set_var *var)
{
thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
@@ -3246,22 +2678,151 @@ static byte *get_sys_var_length(const sys_var *var, uint *length,
/*
- Initialises sys variables and put them in system_variable_hash
+ Add variables to the dynamic hash of system variables
+
+ SYNOPSIS
+ mysql_add_sys_var_chain()
+ first Pointer to first system variable to add
+ long_opt (optional)command line arguments may be tied for limit checks.
+
+ RETURN VALUES
+ 0 SUCCESS
+ otherwise FAILURE
*/
-
-void set_var_init()
+int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
{
sys_var *var;
-
- hash_init(&system_variable_hash, system_charset_info, sys_var::sys_vars, 0,
- 0, (hash_get_key) get_sys_var_length, 0, 0);
- for (var= sys_var::first; var; var= var->next)
+
+ /* A write lock should be held on LOCK_system_variables_hash */
+
+ for (var= first; var; var= var->next)
{
var->name_length= strlen(var->name);
- var->option_limits= find_option(my_long_options, var->name);
- my_hash_insert(&system_variable_hash, (byte*) var);
+ /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
+ if (my_hash_insert(&system_variable_hash, (byte*) var))
+ goto error;
+ if (long_options)
+ var->option_limits= find_option(long_options, var->name);
}
+ return 0;
+
+error:
+ for (; first != var; first= first->next)
+ hash_delete(&system_variable_hash, (byte*) first);
+ return 1;
+}
+
+
+/*
+ Remove variables to the dynamic hash of system variables
+
+ SYNOPSIS
+ mysql_del_sys_var_chain()
+ first Pointer to first system variable to remove
+
+ RETURN VALUES
+ 0 SUCCESS
+ otherwise FAILURE
+*/
+
+int mysql_del_sys_var_chain(sys_var *first)
+{
+ int result= 0;
+
+ /* A write lock should be held on LOCK_system_variables_hash */
+
+ for (sys_var *var= first; var; var= var->next)
+ result|= hash_delete(&system_variable_hash, (byte*) var);
+
+ return result;
+}
+
+
+static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
+{
+ return strcmp(a->name, b->name);
+}
+
+
+/*
+ Constructs an array of system variables for display to the user.
+
+ SYNOPSIS
+ enumerate_sys_vars()
+ thd current thread
+ sorted If TRUE, the system variables should be sorted
+
+ RETURN VALUES
+ pointer Array of SHOW_VAR elements for display
+ NULL FAILURE
+*/
+
+SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
+{
+ int count= system_variable_hash.records, i;
+ int fixed_count= fixed_show_vars.elements;
+ 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_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
+
+ for (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 */
+ if (sorted)
+ qsort(result, count + fixed_count, sizeof(SHOW_VAR), (qsort_cmp)show_cmp);
+
+ /* make last element empty */
+ bzero(show, sizeof(SHOW_VAR));
+ }
+ return result;
+}
+
+
+/*
+ Initialize the system variables
+
+ SYNOPSIS
+ set_var_init()
+
+ RETURN VALUES
+ 0 SUCCESS
+ otherwise FAILURE
+*/
+
+int set_var_init()
+{
+ uint count= 0;
+ DBUG_ENTER("set_var_init");
+
+ for (sys_var *var=vars.first; var; var= var->next, count++);
+
+ if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR),
+ FIXED_VARS_SIZE + 64, 64))
+ goto error;
+
+ fixed_show_vars.elements= FIXED_VARS_SIZE;
+ memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
+
+ if (hash_init(&system_variable_hash, system_charset_info, count, 0,
+ 0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
+ goto error;
+
+ vars.last->next= NULL;
+ if (mysql_add_sys_var_chain(vars.first, my_long_options))
+ goto error;
+
/*
Special cases
Needed because MySQL can't find the limits for a variable it it has
@@ -3269,12 +2830,40 @@ void set_var_init()
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);
+
+error:
+ fprintf(stderr, "failed to initialize system variables");
+ DBUG_RETURN(1);
}
void set_var_free()
{
hash_free(&system_variable_hash);
+ delete_dynamic(&fixed_show_vars);
+}
+
+
+/*
+ Add elements to the dynamic list of read-only system variables.
+
+ SYNOPSIS
+ mysql_append_static_vars()
+ show_vars Pointer to start of array
+ count Number of elements
+
+ RETURN VALUES
+ 0 SUCCESS
+ otherwise FAILURE
+*/
+int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count)
+{
+ for (; count > 0; count--, show_vars++)
+ if (insert_dynamic(&fixed_show_vars, (char*) show_vars))
+ return 1;
+ return 0;
}
@@ -3282,7 +2871,7 @@ void set_var_free()
Find a user set-table variable
SYNOPSIS
- find_sys_var()
+ intern_find_sys_var()
str Name of system variable to find
length Length of variable. zero means that we should use strlen()
on the variable
@@ -3292,14 +2881,19 @@ void set_var_free()
0 Unknown variable (error message is given)
*/
-sys_var *find_sys_var(const char *str, uint length)
+sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
{
- sys_var *var= (sys_var*) hash_search(&system_variable_hash,
- (byte*) str,
- length ? length :
- strlen(str));
- if (!var)
+ sys_var *var;
+
+ /*
+ This function is only called from the sql_plugin.cc.
+ A lock on LOCK_system_variable_hash should be held
+ */
+ var= (sys_var*) hash_search(&system_variable_hash,
+ (byte*) str, length ? length : strlen(str));
+ if (!(var || no_error))
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
+
return var;
}
@@ -3565,14 +3159,16 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
const char *value;
String str(buff, sizeof(buff), &my_charset_latin1), *res;
+ var->save_result.plugin= NULL;
if (var->value->result_type() == STRING_RESULT)
{
LEX_STRING name;
- handlerton *db_type;
+ handlerton *hton;
if (!(res=var->value->val_str(&str)) ||
!(name.str= (char *)res->ptr()) || !(name.length= res->length()) ||
- !(var->save_result.hton= db_type= ha_resolve_by_name(thd, &name)) ||
- ha_checktype(thd, ha_legacy_type(db_type), 1, 0) != db_type)
+ !(var->save_result.plugin= ha_resolve_by_name(thd, &name)) ||
+ !(hton= plugin_data(var->save_result.plugin, handlerton *)) ||
+ ha_checktype(thd, ha_legacy_type(hton), 1, 0) != hton)
{
value= res ? res->c_ptr() : "NULL";
goto err;
@@ -3590,28 +3186,52 @@ err:
byte *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
- handlerton *val;
- val= (type == OPT_GLOBAL) ? global_system_variables.*offset :
- thd->variables.*offset;
- return (byte *) hton2plugin[val->slot]->name.str;
+ byte* result;
+ handlerton *hton;
+ LEX_STRING *name;
+ plugin_ref plugin= thd->variables.*offset;
+ if (type == OPT_GLOBAL)
+ plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
+ hton= plugin_data(plugin, handlerton*);
+ name= &hton2plugin[hton->slot]->name;
+ result= (byte *) thd->strmake(name->str, name->length);
+ if (type == OPT_GLOBAL)
+ plugin_unlock(thd, plugin);
+ return result;
}
void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
{
+ plugin_ref old_value, new_value, *value;
if (type == OPT_GLOBAL)
- global_system_variables.*offset= myisam_hton;
+ {
+ value= &(global_system_variables.*offset);
+ new_value= ha_lock_engine(NULL, myisam_hton);
+ }
else
- thd->variables.*offset= global_system_variables.*offset;
+ {
+ value= &(thd->variables.*offset);
+ new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
+ }
+ DBUG_ASSERT(new_value);
+ old_value= *value;
+ *value= new_value;
+ plugin_unlock(NULL, old_value);
}
bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
{
- handlerton **value= &(global_system_variables.*offset);
- if (var->type != OPT_GLOBAL)
- value= &(thd->variables.*offset);
- *value= var->save_result.hton;
+ plugin_ref *value= &(global_system_variables.*offset), old_value;
+ if (var->type != OPT_GLOBAL)
+ value= &(thd->variables.*offset);
+ old_value= *value;
+ if (old_value != var->save_result.plugin)
+ {
+ *value= my_plugin_lock(NULL, &var->save_result.plugin);
+ plugin_unlock(NULL, old_value);
+ }
return 0;
}
diff --git a/sql/set_var.h b/sql/set_var.h
index a3963171192..5ec7eb7ef4a 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -26,6 +26,7 @@
class sys_var;
class set_var;
+class sys_var_pluginvar; /* opaque */
typedef struct system_variables SV;
typedef struct my_locale_st MY_LOCALE;
@@ -37,11 +38,15 @@ typedef void (*sys_after_update_func)(THD *,enum_var_type);
typedef void (*sys_set_default_func)(THD *, enum_var_type);
typedef byte *(*sys_value_ptr_func)(THD *thd);
+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() */
@@ -52,13 +57,15 @@ public:
sys_var(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()
+ void chain_sys_var(sys_var_chain *chain_arg)
{
- next= first;
- first= this;
- sys_vars++;
+ if (chain_arg->last)
+ chain_arg->last->next= this;
+ else
+ chain_arg->first= this;
+ chain_arg->last= this;
}
virtual bool check(THD *thd, set_var *var);
bool check_enum(THD *thd, set_var *var, const TYPELIB *enum_names);
@@ -77,6 +84,7 @@ public:
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; }
};
@@ -105,12 +113,12 @@ class sys_var_long_ptr_global: public sys_var_global
{
public:
ulong *value;
- sys_var_long_ptr_global(const char *name_arg, ulong *value_ptr_arg,
+ sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
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_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
@@ -127,7 +135,7 @@ public:
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);
};
@@ -136,11 +144,13 @@ class sys_var_ulonglong_ptr :public sys_var
{
public:
ulonglong *value;
- sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr_arg)
- :sys_var(name_arg),value(value_ptr_arg) {}
- sys_var_ulonglong_ptr(const char *name_arg, ulonglong *value_ptr_arg,
+ sys_var_ulonglong_ptr(sys_var_chain *chain, const char *name_arg, ulonglong *value_ptr_arg)
+ :sys_var(name_arg),value(value_ptr_arg)
+ { chain_sys_var(chain); }
+ sys_var_ulonglong_ptr(sys_var_chain *chain, const char *name_arg, ulonglong *value_ptr_arg,
sys_after_update_func func)
- :sys_var(name_arg,func), value(value_ptr_arg) {}
+ :sys_var(name_arg,func), value(value_ptr_arg)
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_LONGLONG; }
@@ -153,9 +163,9 @@ class sys_var_bool_ptr :public sys_var
{
public:
my_bool *value;
- sys_var_bool_ptr(const char *name_arg, my_bool *value_arg)
+ sys_var_bool_ptr(sys_var_chain *chain, const char *name_arg, my_bool *value_arg)
:sys_var(name_arg),value(value_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
return check_enum(thd, var, &bool_typelib);
@@ -187,14 +197,14 @@ public:
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),
update_func(update_func_arg),set_default_func(set_default_func_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var)
{
@@ -219,9 +229,9 @@ 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_const_str(sys_var_chain *chain, const char *name_arg, const char *value_arg)
:sys_var(name_arg),value((char*) value_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
return 1;
@@ -248,9 +258,9 @@ class sys_var_const_str_ptr :public sys_var
{
public:
char **value; // Pointer to const value
- sys_var_const_str_ptr(const char *name_arg, char **value_arg)
+ sys_var_const_str_ptr(sys_var_chain *chain, const char *name_arg, char **value_arg)
:sys_var(name_arg),value(value_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
return 1;
@@ -278,10 +288,10 @@ class sys_var_enum :public sys_var
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)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
return check_enum(thd, var, enum_names);
@@ -296,7 +306,8 @@ public:
class sys_var_thd :public sys_var
{
public:
- sys_var_thd(const char *name_arg, sys_after_update_func func= NULL)
+ sys_var_thd(const char *name_arg,
+ sys_after_update_func func= NULL)
:sys_var(name_arg,func)
{}
bool check_type(enum_var_type type) { return 0; }
@@ -312,13 +323,13 @@ class sys_var_thd_ulong :public sys_var_thd
sys_check_func check_func;
public:
ulong SV::*offset;
- 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_var_thd(name_arg), check_func(0), offset(offset_arg)
- {}
- sys_var_thd_ulong(const char *name_arg, ulong SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
@@ -331,13 +342,15 @@ class sys_var_thd_ha_rows :public sys_var_thd
{
public:
ha_rows SV::*offset;
- 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_var_thd(name_arg), offset(offset_arg)
- {}
- sys_var_thd_ha_rows(const char *name_arg, ha_rows SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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)
- {}
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_HA_ROWS; }
@@ -350,14 +363,16 @@ class sys_var_thd_ulonglong :public sys_var_thd
public:
ulonglong SV::*offset;
bool only_global;
- 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_var_thd(name_arg), offset(offset_arg)
- {}
- sys_var_thd_ulonglong(const char *name_arg, ulonglong SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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),
only_global(only_global_arg)
- {}
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_LONGLONG; }
@@ -377,13 +392,13 @@ class sys_var_thd_bool :public sys_var_thd
{
public:
my_bool SV::*offset;
- 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_var_thd(name_arg), offset(offset_arg)
- {}
- sys_var_thd_bool(const char *name_arg, my_bool SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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)
- {}
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_MY_BOOL; }
@@ -403,23 +418,23 @@ protected:
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),
check_func(0)
- {}
- sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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),
check_func(0)
- {}
- sys_var_thd_enum(const char *name_arg, ulong SV::*offset_arg,
+ { chain_sys_var(chain); }
+ 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),
check_func(check)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
int ret= 0;
@@ -440,8 +455,9 @@ extern void fix_sql_mode_var(THD *thd, enum_var_type type);
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)
@@ -458,11 +474,12 @@ public:
class sys_var_thd_storage_engine :public sys_var_thd
{
protected:
- handlerton *SV::*offset;
+ plugin_ref SV::*offset;
public:
- sys_var_thd_storage_engine(const char *name_arg, handlerton *SV::*offset_arg)
+ sys_var_thd_storage_engine(sys_var_chain *chain, const char *name_arg,
+ plugin_ref SV::*offset_arg)
:sys_var_thd(name_arg), offset(offset_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
SHOW_TYPE show_type() { return SHOW_CHAR; }
bool check_update_type(Item_result type)
@@ -477,8 +494,9 @@ public:
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,
+ plugin_ref 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);
@@ -492,12 +510,12 @@ class sys_var_thd_bit :public sys_var_thd
public:
ulonglong 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,
ulonglong bit, bool reverse_arg=0)
:sys_var_thd(name_arg), check_func(c_func), update_func(u_func),
bit_flag(bit), reverse(reverse_arg)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var);
bool check_update_type(Item_result type) { return 0; }
@@ -509,7 +527,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
bool check_update_type(Item_result type) { return type != STRING_RESULT; }
bool check(THD *thd, set_var *var);
SHOW_TYPE show_type() { return SHOW_CHAR; }
@@ -525,7 +545,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
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; }
@@ -538,7 +560,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
SHOW_TYPE show_type() { return SHOW_LONGLONG; }
@@ -549,7 +573,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
SHOW_TYPE show_type() { return SHOW_LONGLONG; }
@@ -557,33 +583,12 @@ public:
};
-#ifdef HAVE_REPLICATION
-class sys_var_slave_skip_counter :public sys_var
-{
-public:
- sys_var_slave_skip_counter(const char *name_arg) :sys_var(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; }
- /*
- We can't retrieve the value of this, so we don't have to define
- show_type() or value_ptr()
- */
-};
-
-class sys_var_sync_binlog_period :public sys_var_long_ptr
-{
-public:
- sys_var_sync_binlog_period(const char *name_arg, ulong *value_ptr_arg)
- :sys_var_long_ptr(name_arg,value_ptr_arg) {}
- bool update(THD *thd, set_var *var);
-};
-#endif
-
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(name_arg)
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
};
@@ -591,7 +596,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var);
bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
};
@@ -600,7 +607,8 @@ public:
class sys_var_collation :public sys_var_thd
{
public:
- sys_var_collation(const char *name_arg) :sys_var_thd(name_arg)
+ sys_var_collation(const char *name_arg)
+ :sys_var_thd(name_arg)
{
no_support_one_shot= 0;
}
@@ -618,10 +626,9 @@ class sys_var_character_set :public sys_var_thd
{
public:
bool nullable;
- sys_var_character_set(const char *name_arg) :
- sys_var_thd(name_arg)
+ sys_var_character_set(const char *name_arg, bool is_nullable= 0) :
+ sys_var_thd(name_arg), nullable(is_nullable)
{
- nullable= 0;
/*
In fact only almost all variables derived from sys_var_character_set
support ONE_SHOT; character_set_results doesn't. But that's good enough.
@@ -641,83 +648,47 @@ public:
virtual CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type)= 0;
};
-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) {}
- void set_default(THD *thd, enum_var_type type);
- CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
-};
-
-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) {}
- void set_default(THD *thd, enum_var_type type);
- CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
-};
-class sys_var_character_set_results :public sys_var_character_set
+class sys_var_character_set_sv :public sys_var_character_set
{
+ CHARSET_INFO *SV::*offset;
+ CHARSET_INFO **global_default;
public:
- sys_var_character_set_results(const char *name_arg) :
- sys_var_character_set(name_arg)
- { nullable= 1; }
+ sys_var_character_set_sv(sys_var_chain *chain, const char *name_arg,
+ CHARSET_INFO *SV::*offset_arg,
+ CHARSET_INFO **global_default_arg,
+ bool is_nullable= 0)
+ : sys_var_character_set(name_arg, is_nullable),
+ offset(offset_arg), global_default(global_default_arg)
+ { chain_sys_var(chain); }
void set_default(THD *thd, enum_var_type type);
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
};
-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) {}
- void set_default(THD *thd, enum_var_type type);
- CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
-};
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(name_arg)
+ { chain_sys_var(chain); }
void set_default(THD *thd, enum_var_type type);
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
};
-class sys_var_character_set_connection :public sys_var_character_set
+class sys_var_collation_sv :public sys_var_collation
{
+ CHARSET_INFO *SV::*offset;
+ CHARSET_INFO **global_default;
public:
- sys_var_character_set_connection(const char *name_arg) :
- sys_var_character_set(name_arg) {}
- void set_default(THD *thd, enum_var_type type);
- CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
-};
-
-class sys_var_collation_connection :public sys_var_collation
-{
-public:
- sys_var_collation_connection(const char *name_arg) :sys_var_collation(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);
-};
-
-class sys_var_collation_server :public sys_var_collation
-{
-public:
- sys_var_collation_server(const char *name_arg) :sys_var_collation(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);
-};
-
-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_sv(sys_var_chain *chain, const char *name_arg,
+ CHARSET_INFO *SV::*offset_arg,
+ CHARSET_INFO **global_default_arg)
+ :sys_var_collation(name_arg),
+ offset(offset_arg), global_default(global_default_arg)
+ {
+ chain_sys_var(chain);
+ }
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);
@@ -729,9 +700,10 @@ class sys_var_key_cache_param :public sys_var
protected:
size_t offset;
public:
- sys_var_key_cache_param(const char *name_arg, size_t offset_arg)
+ sys_var_key_cache_param(sys_var_chain *chain, const char *name_arg,
+ size_t offset_arg)
:sys_var(name_arg), offset(offset_arg)
- {}
+ { chain_sys_var(chain); }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
bool check_default(enum_var_type type) { return 1; }
bool is_struct() { return 1; }
@@ -741,8 +713,9 @@ public:
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 show_type() { return SHOW_LONGLONG; }
@@ -752,8 +725,8 @@ public:
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 show_type() { return SHOW_LONG; }
@@ -765,12 +738,12 @@ class sys_var_thd_date_time_format :public sys_var_thd
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),
date_time_type(date_time_type_arg)
- {}
+ { chain_sys_var(chain); }
SHOW_TYPE show_type() { return SHOW_CHAR; }
bool check_update_type(Item_result type)
{
@@ -789,8 +762,9 @@ class sys_var_log_state :public sys_var_bool_ptr
{
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);
};
@@ -801,10 +775,10 @@ class sys_var_log_output :public sys_var
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)
- {}
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var)
{
return check_set(thd, var, enum_names);
@@ -825,12 +799,12 @@ public:
enum_var_type var_type;
SHOW_TYPE show_type_value;
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),
show_type_value(show_type_arg), value_ptr_func(value_ptr_func_arg)
- {}
+ { chain_sys_var(chain); }
bool update(THD *thd, set_var *var) { return 1; }
bool check_default(enum_var_type type) { return 1; }
bool check_type(enum_var_type type) { return type != var_type; }
@@ -844,19 +818,17 @@ public:
};
-class sys_var_have_variable: public sys_var
+class sys_var_have_option: public sys_var
{
- SHOW_COMP_OPTION *have_variable;
-
+protected:
+ virtual SHOW_COMP_OPTION get_option() = 0;
public:
- sys_var_have_variable(const char *variable_name,
- SHOW_COMP_OPTION *have_variable_arg):
- sys_var(variable_name),
- have_variable(have_variable_arg)
- { }
+ sys_var_have_option(sys_var_chain *chain, const char *variable_name):
+ sys_var(variable_name)
+ { chain_sys_var(chain); }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{
- return (byte*) show_comp_option_name[*have_variable];
+ return (byte*) show_comp_option_name[get_option()];
}
bool update(THD *thd, set_var *var) { return 1; }
bool check_default(enum_var_type type) { return 1; }
@@ -867,13 +839,47 @@ public:
};
+class sys_var_have_variable: public sys_var_have_option
+{
+ SHOW_COMP_OPTION *have_variable;
+
+public:
+ sys_var_have_variable(sys_var_chain *chain, const char *variable_name,
+ SHOW_COMP_OPTION *have_variable_arg):
+ sys_var_have_option(chain, variable_name),
+ have_variable(have_variable_arg)
+ { }
+ SHOW_COMP_OPTION get_option() { return *have_variable; }
+};
+
+
+class sys_var_have_plugin: public sys_var_have_option
+{
+ const char *plugin_name_str;
+ const uint plugin_name_len;
+ const int plugin_type;
+
+public:
+ sys_var_have_plugin(sys_var_chain *chain, const char *variable_name,
+ const char *plugin_name_str_arg, uint plugin_name_len_arg,
+ int plugin_type_arg):
+ sys_var_have_option(chain, variable_name),
+ plugin_name_str(plugin_name_str_arg), plugin_name_len(plugin_name_len_arg),
+ plugin_type(plugin_type_arg)
+ { }
+ /* the following method is declared in sql_plugin.cc */
+ SHOW_COMP_OPTION get_option();
+};
+
+
class sys_var_thd_time_zone :public sys_var_thd
{
public:
- sys_var_thd_time_zone(const char *name_arg):
+ sys_var_thd_time_zone(sys_var_chain *chain, const char *name_arg):
sys_var_thd(name_arg)
{
no_support_one_shot= 0;
+ chain_sys_var(chain);
}
bool check(THD *thd, set_var *var);
SHOW_TYPE show_type() { return SHOW_CHAR; }
@@ -891,8 +897,9 @@ public:
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(name_arg)
+ { chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var);
bool check_default(enum_var_type type)
@@ -908,8 +915,9 @@ class sys_var_trust_routine_creators :public sys_var_bool_ptr
{
/* 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);
@@ -923,8 +931,9 @@ public:
class sys_var_opt_readonly :public sys_var_bool_ptr
{
public:
- sys_var_opt_readonly(const char *name_arg, my_bool *value_arg) :
- sys_var_bool_ptr(name_arg, value_arg) {};
+ sys_var_opt_readonly(sys_var_chain *chain, const char *name_arg,
+ my_bool *value_arg) :
+ sys_var_bool_ptr(chain, name_arg, value_arg) {};
~sys_var_opt_readonly() {};
bool update(THD *thd, set_var *var);
};
@@ -933,12 +942,13 @@ public:
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(name_arg)
{
#if MYSQL_VERSION_ID < 50000
no_support_one_shot= 0;
#endif
+ chain_sys_var(chain);
}
bool check(THD *thd, set_var *var);
SHOW_TYPE show_type() { return SHOW_CHAR; }
@@ -957,8 +967,8 @@ class sys_var_event_scheduler :public sys_var_long_ptr
{
/* 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 show_type() { return SHOW_CHAR; }
@@ -974,8 +984,9 @@ extern void fix_binlog_format_after_update(THD *thd, enum_var_type type);
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
, fix_binlog_format_after_update
)
@@ -1013,7 +1024,7 @@ public:
CHARSET_INFO *charset;
ulong ulong_value;
ulonglong ulonglong_value;
- handlerton *hton;
+ plugin_ref plugin;
DATE_TIME_FORMAT *date_time_format;
Time_zone *time_zone;
MY_LOCALE *locale_value;
@@ -1142,9 +1153,13 @@ struct sys_var_with_base
Prototypes for helper functions
*/
-void set_var_init();
+int set_var_init();
void set_var_free();
-sys_var *find_sys_var(const char *str, uint length=0);
+int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count);
+SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted);
+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(THD *thd, 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);
void fix_delay_key_write(THD *thd, enum_var_type type);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8cc54aa3c8c..7dff4c78c27 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1716,7 +1716,7 @@ void close_temporary_table(THD *thd, TABLE *table,
void close_temporary(TABLE *table, bool free_share, bool delete_table)
{
- handlerton *table_type= table->s->db_type;
+ handlerton *table_type= table->s->db_type();
DBUG_ENTER("close_temporary");
free_io_cache(table);
@@ -6486,7 +6486,7 @@ my_bool mysql_rm_tmp_tables(void)
init_tmp_table_share(&share, "", 0, "", filePathCopy);
if (!open_table_def(thd, &share, 0) &&
((handler_file= get_new_handler(&share, thd->mem_root,
- share.db_type))))
+ share.db_type()))))
{
handler_file->delete_table(filePathCopy);
delete handler_file;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 89b7a25033f..f042748bf7d 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -2411,7 +2411,12 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
tables_used->engine_data))
DBUG_RETURN(0);
- if (tables_used->table->s->db_type->db_type == DB_TYPE_MRG_MYISAM)
+#ifdef WITH_MYISAMMRG_STORAGE_ENGINE
+ /*
+ XXX FIXME: Some generic mechanism is required here instead of this
+ MYISAMMRG-specific implementation.
+ */
+ if (tables_used->table->s->db_type()->db_type == DB_TYPE_MRG_MYISAM)
{
ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
MYRG_INFO *file = handler->myrg_info();
@@ -2434,6 +2439,7 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
DBUG_RETURN(0);
}
}
+#endif
}
}
DBUG_RETURN(n - counter);
@@ -3010,7 +3016,7 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
tables_used->table->s->table_name.str,
tables_used->table->s->db.str,
- tables_used->table->s->db_type->db_type));
+ tables_used->table->s->db_type()->db_type));
if (tables_used->derived)
{
table_count--;
@@ -3035,12 +3041,18 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
"other non-cacheable table(s)"));
DBUG_RETURN(0);
}
- if (tables_used->table->s->db_type->db_type == DB_TYPE_MRG_MYISAM)
+#ifdef WITH_MYISAMMRG_STORAGE_ENGINE
+ /*
+ XXX FIXME: Some generic mechanism is required here instead of this
+ MYISAMMRG-specific implementation.
+ */
+ if (tables_used->table->s->db_type()->db_type == DB_TYPE_MRG_MYISAM)
{
ha_myisammrg *handler = (ha_myisammrg *)tables_used->table->file;
MYRG_INFO *file = handler->myrg_info();
table_count+= (file->end_table - file->open_tables);
}
+#endif
}
}
DBUG_RETURN(table_count);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 0abda16ea6a..3d2683786c4 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -167,18 +167,25 @@ Open_tables_state::Open_tables_state(ulong version_arg)
reset_open_tables_state();
}
-my_bool thd_in_lock_tables(const THD *thd)
+/*
+ The following functions form part of the C plugin API
+*/
+
+extern "C"
+int thd_in_lock_tables(const THD *thd)
{
- return thd->in_lock_tables;
+ return test(thd->in_lock_tables);
}
-my_bool thd_tablespace_op(const THD *thd)
+extern "C"
+int thd_tablespace_op(const THD *thd)
{
- return thd->tablespace_op;
+ return test(thd->tablespace_op);
}
+extern "C"
const char *thd_proc_info(THD *thd, const char *info)
{
const char *old_info= thd->proc_info;
@@ -186,11 +193,98 @@ const char *thd_proc_info(THD *thd, const char *info)
return old_info;
}
+extern "C"
void **thd_ha_data(const THD *thd, const struct handlerton *hton)
{
return (void **) thd->ha_data + hton->slot;
}
+extern "C"
+long long thd_test_options(const THD *thd, long long test_options)
+{
+ return thd->options & test_options;
+}
+
+extern "C"
+int thd_sql_command(const THD *thd)
+{
+ return (int) thd->lex->sql_command;
+}
+
+extern "C"
+int thd_tx_isolation(const THD *thd)
+{
+ return (int) thd->variables.tx_isolation;
+}
+
+
+/*
+ Dumps a text description of a thread, its security context
+ (user, host) and the current query.
+
+ SYNOPSIS
+ thd_security_context()
+ thd current thread context
+ buffer pointer to preferred result buffer
+ length length of buffer
+ max_query_len how many chars of query to copy (0 for all)
+
+ RETURN VALUES
+ pointer to string
+*/
+extern "C"
+char *thd_security_context(THD *thd, char *buffer, unsigned int length,
+ unsigned int max_query_len)
+{
+ String str(buffer, length, &my_charset_latin1);
+ const Security_context *sctx= &thd->main_security_ctx;
+ char header[64];
+ int len;
+
+ len= my_snprintf(header, sizeof(header),
+ "MySQL thread id %lu, query id %lu",
+ thd->thread_id, (ulong) thd->query_id);
+ str.length(0);
+ str.append(header, len);
+
+ if (sctx->host)
+ {
+ str.append(' ');
+ str.append(sctx->host);
+ }
+
+ if (sctx->ip)
+ {
+ str.append(' ');
+ str.append(sctx->ip);
+ }
+
+ if (sctx->user)
+ {
+ str.append(' ');
+ str.append(sctx->user);
+ }
+
+ if (thd->proc_info)
+ {
+ str.append(' ');
+ str.append(thd->proc_info);
+ }
+
+ if (thd->query)
+ {
+ if (max_query_len < 1)
+ len= thd->query_length;
+ else
+ len= min(thd->query_length, max_query_len);
+ str.append('\n');
+ str.append(thd->query, len);
+ }
+ if (str.c_ptr_safe() == buffer)
+ return buffer;
+ return thd->strmake(str.ptr(), str.length());
+}
+
THD::THD()
@@ -201,13 +295,16 @@ THD::THD()
user_time(0), in_sub_stmt(0),
binlog_table_maps(0),
global_read_lock(0), is_fatal_error(0),
- rand_used(0), time_zone_used(0),
arg_of_last_insert_id_function(FALSE),
first_successful_insert_id_in_prev_stmt(0),
first_successful_insert_id_in_prev_stmt_for_binlog(0),
first_successful_insert_id_in_cur_stmt(0),
- in_lock_tables(0), bootstrap(0), derived_tables_processing(FALSE),
+ rand_used(0),
+ time_zone_used(0),
+ in_lock_tables(0),
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
+ bootstrap(0),
+ derived_tables_processing(FALSE),
spcont(NULL)
{
ulong tmp;
@@ -356,6 +453,8 @@ void THD::init(void)
{
pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables;
+ variables.table_plugin= NULL;
+ plugin_thdvar_init(this);
variables.time_format= date_time_format_copy((THD*) 0,
variables.time_format);
variables.date_format= date_time_format_copy((THD*) 0,
@@ -502,6 +601,7 @@ THD::~THD()
cleanup();
ha_close_connection(this);
+ plugin_thdvar_cleanup(this);
DBUG_PRINT("info", ("freeing security context"));
main_security_ctx.destroy();
@@ -1731,12 +1831,12 @@ void Query_arena::cleanup_stmt()
}
/*
- Statement functions
+ Statement functions
*/
Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
enum enum_state state_arg, ulong id_arg)
- :Query_arena(mem_root_arg, state_arg),
+ :Query_arena(mem_root_arg, state_arg), main_lex(),
id(id_arg),
mark_used_columns(MARK_COLUMNS_READ),
lex(lex_arg),
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 66914bdf908..2d7cf5ba90a 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -180,6 +180,20 @@ class Time_zone;
struct system_variables
{
+ /*
+ How dynamically allocated system variables are handled:
+
+ The global_system_variables and max_system_variables are "authoritative"
+ 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_head; /* largest valid variable offset */
+ uint dynamic_variables_size; /* how many bytes are in use */
+
ulonglong myisam_max_extra_sort_file_size;
ulonglong myisam_max_sort_file_size;
ulonglong max_heap_table_size;
@@ -250,8 +264,6 @@ struct system_variables
my_bool old_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;
@@ -261,7 +273,7 @@ struct system_variables
my_bool old_alter_table;
my_bool old_passwords;
- handlerton *table_type;
+ plugin_ref table_plugin;
/* Only charset part of these variables is sensible */
CHARSET_INFO *character_set_filesystem;
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 09ee4962235..3ed32c28c7e 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -966,6 +966,7 @@ bool login_connection(THD *thd)
void end_connection(THD *thd)
{
NET *net= &thd->net;
+ plugin_thdvar_cleanup(thd);
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
if (net->error && net->vio != 0 && net->report_error)
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 4e865a12b66..7f83a8df717 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -903,7 +903,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* If it is a temporary table, close and regenerate it */
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
{
- handlerton *table_type= table->s->db_type;
+ handlerton *table_type= table->s->db_type();
TABLE_SHARE *share= table->s;
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 9852c71e2b4..9ded59b2ea6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3363,7 +3363,7 @@ void select_create::abort()
{
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
- handlerton *table_type=table->s->db_type;
+ handlerton *table_type=table->s->db_type();
if (!table->s->tmp_table)
{
ulong version= table->s->version;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 26955c18342..bd81aa2d5c1 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -193,6 +193,7 @@ void lex_start(THD *thd, const char *buf, uint length)
lex->spcont= NULL;
lex->proc_list.first= 0;
lex->escape_used= FALSE;
+ lex->query_tables= 0;
lex->reset_query_tables_list(FALSE);
lex->expr_allows_subselect= TRUE;
@@ -232,6 +233,12 @@ void lex_end(LEX *lex)
lex->yacc_yyss= 0;
lex->yacc_yyvs= 0;
}
+
+ /* release used plugins */
+ plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer,
+ lex->plugins.elements);
+ reset_dynamic(&lex->plugins);
+
DBUG_VOID_RETURN;
}
@@ -1700,6 +1707,17 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd)
void Query_tables_list::reset_query_tables_list(bool init)
{
+ if (!init && query_tables)
+ {
+ TABLE_LIST *table= query_tables;
+ for (;;)
+ {
+ delete table->view;
+ if (query_tables_last == &table->next_global ||
+ !(table= table->next_global))
+ break;
+ }
+ }
query_tables= 0;
query_tables_last= &query_tables;
query_tables_own_last= 0;
@@ -1754,6 +1772,13 @@ st_lex::st_lex()
:result(0), yacc_yyss(0), yacc_yyvs(0),
sql_command(SQLCOM_END)
{
+ /* Check that plugins_static_buffer is declared immediately after plugins */
+ compile_time_assert((&plugins + 1) == (DYNAMIC_ARRAY*)plugins_static_buffer);
+
+ my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
+ plugins_static_buffer,
+ INITIAL_LEX_PLUGIN_LIST_SIZE,
+ INITIAL_LEX_PLUGIN_LIST_SIZE);
reset_query_tables_list(TRUE);
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 850586c6098..0dd8ab3a28b 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1019,6 +1019,11 @@ typedef struct st_lex : public Query_tables_list
XID *xid;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
+
+ /* maintain a list of used plugins for this LEX */
+ DYNAMIC_ARRAY plugins;
+ plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE];
+
CHARSET_INFO *charset, *underscore_charset;
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
@@ -1217,6 +1222,8 @@ typedef struct st_lex : public Query_tables_list
virtual ~st_lex()
{
destroy_query_tables_list();
+ plugin_unlock_list(NULL, (plugin_ref *)plugins.buffer, plugins.elements);
+ delete_dynamic(&plugins);
}
inline void uncacheable(uint8 cause)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 9d02053ec00..1d0df64fd64 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -43,37 +43,37 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
const char *any_db="*any*"; // Special symbol for check_access
const LEX_STRING command_name[]={
- C_STRING_WITH_LEN("Sleep"),
- C_STRING_WITH_LEN("Quit"),
- C_STRING_WITH_LEN("Init DB"),
- C_STRING_WITH_LEN("Query"),
- C_STRING_WITH_LEN("Field List"),
- C_STRING_WITH_LEN("Create DB"),
- C_STRING_WITH_LEN("Drop DB"),
- C_STRING_WITH_LEN("Refresh"),
- C_STRING_WITH_LEN("Shutdown"),
- C_STRING_WITH_LEN("Statistics"),
- C_STRING_WITH_LEN("Processlist"),
- C_STRING_WITH_LEN("Connect"),
- C_STRING_WITH_LEN("Kill"),
- C_STRING_WITH_LEN("Debug"),
- C_STRING_WITH_LEN("Ping"),
- C_STRING_WITH_LEN("Time"),
- C_STRING_WITH_LEN("Delayed insert"),
- C_STRING_WITH_LEN("Change user"),
- C_STRING_WITH_LEN("Binlog Dump"),
- C_STRING_WITH_LEN("Table Dump"),
- C_STRING_WITH_LEN("Connect Out"),
- C_STRING_WITH_LEN("Register Slave"),
- C_STRING_WITH_LEN("Prepare"),
- C_STRING_WITH_LEN("Execute"),
- C_STRING_WITH_LEN("Long Data"),
- C_STRING_WITH_LEN("Close stmt"),
- C_STRING_WITH_LEN("Reset stmt"),
- C_STRING_WITH_LEN("Set option"),
- C_STRING_WITH_LEN("Fetch"),
- C_STRING_WITH_LEN("Daemon"),
- C_STRING_WITH_LEN("Error") // Last command number
+ { STRING_WITH_LEN("Sleep") },
+ { STRING_WITH_LEN("Quit") },
+ { STRING_WITH_LEN("Init DB") },
+ { STRING_WITH_LEN("Query") },
+ { STRING_WITH_LEN("Field List") },
+ { STRING_WITH_LEN("Create DB") },
+ { STRING_WITH_LEN("Drop DB") },
+ { STRING_WITH_LEN("Refresh") },
+ { STRING_WITH_LEN("Shutdown") },
+ { STRING_WITH_LEN("Statistics") },
+ { STRING_WITH_LEN("Processlist") },
+ { STRING_WITH_LEN("Connect") },
+ { STRING_WITH_LEN("Kill") },
+ { STRING_WITH_LEN("Debug") },
+ { STRING_WITH_LEN("Ping") },
+ { STRING_WITH_LEN("Time") },
+ { STRING_WITH_LEN("Delayed insert") },
+ { STRING_WITH_LEN("Change user") },
+ { STRING_WITH_LEN("Binlog Dump") },
+ { STRING_WITH_LEN("Table Dump") },
+ { STRING_WITH_LEN("Connect Out") },
+ { STRING_WITH_LEN("Register Slave") },
+ { STRING_WITH_LEN("Prepare") },
+ { STRING_WITH_LEN("Execute") },
+ { STRING_WITH_LEN("Long Data") },
+ { STRING_WITH_LEN("Close stmt") },
+ { STRING_WITH_LEN("Reset stmt") },
+ { STRING_WITH_LEN("Set option") },
+ { STRING_WITH_LEN("Fetch") },
+ { STRING_WITH_LEN("Daemon") },
+ { STRING_WITH_LEN("Error") } // Last command number
};
const char *xa_state_names[]={
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index d445c8bfbe0..24c0fab7748 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -784,9 +784,9 @@ static bool handle_list_of_fields(List_iterator<char> it,
}
else
{
- if (table->s->db_type->partition_flags &&
- (table->s->db_type->partition_flags() & HA_USE_AUTO_PARTITION) &&
- (table->s->db_type->partition_flags() & HA_CAN_PARTITION))
+ if (table->s->db_type()->partition_flags &&
+ (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) &&
+ (table->s->db_type()->partition_flags() & HA_CAN_PARTITION))
{
/*
This engine can handle automatic partitioning and there is no
@@ -1664,8 +1664,8 @@ bool fix_partition_func(THD *thd, TABLE *table,
goto end;
if (unlikely(check_primary_key(table)))
goto end;
- if (unlikely((!(table->s->db_type->partition_flags &&
- (table->s->db_type->partition_flags() & HA_CAN_PARTITION_UNIQUE))) &&
+ if (unlikely((!(table->s->db_type()->partition_flags &&
+ (table->s->db_type()->partition_flags() & HA_CAN_PARTITION_UNIQUE))) &&
check_unique_keys(table)))
goto end;
if (unlikely(set_up_partition_bitmap(thd, part_info)))
@@ -1872,7 +1872,7 @@ static int add_keyword_int(File fptr, const char *keyword, longlong num)
static int add_engine(File fptr, handlerton *engine_type)
{
- const char *engine_str= hton2plugin[engine_type->slot]->name.str;
+ const char *engine_str= ha_resolve_storage_engine_name(engine_type);
DBUG_PRINT("info", ("ENGINE: %s", engine_str));
int err= add_string(fptr, "ENGINE = ");
return err + add_string(fptr, engine_str);
@@ -2188,8 +2188,8 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields)
if (!part_info)
DBUG_RETURN(FALSE);
- if (table->s->db_type->partition_flags &&
- (table->s->db_type->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
+ if (table->s->db_type()->partition_flags &&
+ (table->s->db_type()->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
DBUG_RETURN(FALSE);
for (fld= part_info->full_part_field_array; *fld; fld++)
if (bitmap_is_set(fields, (*fld)->field_index))
@@ -4204,8 +4204,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
alter_info->no_parts= curr_part_no - new_part_no;
}
}
- if (table->s->db_type->alter_table_flags &&
- (!(flags= table->s->db_type->alter_table_flags(alter_info->flags))))
+ if (table->s->db_type()->alter_table_flags &&
+ (!(flags= table->s->db_type()->alter_table_flags(alter_info->flags))))
{
my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
DBUG_RETURN(1);
@@ -4951,7 +4951,7 @@ the generated partition syntax in a correct manner.
create_info->db_type= table->part_info->default_engine_type;
}
DBUG_PRINT("info", ("New engine type: %s",
- hton2plugin[create_info->db_type->slot]->name.str));
+ ha_resolve_storage_engine_name(create_info->db_type)));
thd->work_part_info= NULL;
*partition_changed= TRUE;
}
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 46fb1568df6..34accdc6494 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -15,15 +15,25 @@
#include "mysql_priv.h"
#include <my_pthread.h>
+#include <my_getopt.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
+#ifdef DBUG_OFF
+#define plugin_ref_to_int(A) A
+#define plugin_int_to_ref(A) A
+#else
+#define plugin_ref_to_int(A) (A ? A[0] : NULL)
+#define plugin_int_to_ref(A) &(A)
+#endif
+
extern struct st_mysql_plugin *mysqld_builtins[];
+char *opt_plugin_load= NULL;
char *opt_plugin_dir_ptr;
char opt_plugin_dir[FN_REFLEN];
/*
- When you ad a new plugin type, add both a string and make sure that the
+ When you ad a new plugin type, add both a string and make sure that the
init and deinit array are correctly updated.
*/
const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
@@ -39,10 +49,10 @@ extern int initialize_schema_table(st_plugin_int *plugin);
extern int finalize_schema_table(st_plugin_int *plugin);
/*
- The number of elements in both plugin_type_initialize and
+ The number of elements in both plugin_type_initialize and
plugin_type_deinitialize should equal to the number of plugins
defined.
-*/
+*/
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{
0,ha_initialize_handlerton,0,0,initialize_schema_table
@@ -85,25 +95,186 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
static DYNAMIC_ARRAY plugin_dl_array;
static DYNAMIC_ARRAY plugin_array;
static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
-static rw_lock_t THR_LOCK_plugin;
+/* we are always manipulating ref count, so a rwlock is unneccessary */
+static pthread_mutex_t LOCK_plugin;
static bool initialized= 0;
+static bool reap_needed= false;
static int plugin_array_version=0;
+
+/*
+ write-lock on LOCK_system_variables_hash is required before modifying
+ the following variables/structures
+*/
+static MEM_ROOT plugin_mem_root;
+static uint global_variables_dynamic_size= 0;
+static HASH bookmark_hash;
+
+
+/*
+ hidden part of opaque value passed to variable check functions.
+ Used to provide a object-like structure to non C++ consumers.
+*/
+struct st_item_value_holder : public st_mysql_value
+{
+ Item *item;
+};
+
+
+/*
+ stored in bookmark_hash, this structure is never removed from the
+ hash and is used to mark a single offset for a thd local variable
+ even if plugins have been uninstalled and reinstalled, repeatedly.
+ This structure is allocated from plugin_mem_root.
+
+ The key format is as follows:
+ 1 byte - variable type code
+ name_len bytes - variable name
+ '\0' - end of key
+*/
+struct st_bookmark
+{
+ uint name_len;
+ int offset;
+ uint version;
+ char key[1];
+};
+
+
+/*
+ skeleton of a plugin variable - portion of structure common to all.
+*/
+struct st_mysql_sys_var
+{
+ MYSQL_PLUGIN_VAR_HEADER;
+};
+
+
+/*
+ sys_var class for access to all plugin variables visible to the user
+*/
+class sys_var_pluginvar: public sys_var
+{
+public:
+ struct st_plugin_int *plugin;
+ struct st_mysql_sys_var *plugin_var;
+
+ 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); }
+
+ sys_var_pluginvar(const char *name_arg,
+ struct st_mysql_sys_var *plugin_var_arg)
+ :sys_var(name_arg), plugin_var(plugin_var_arg) {}
+ sys_var_pluginvar *cast_pluginvar() { return this; }
+ bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
+ bool check_type(enum_var_type type)
+ { return !(plugin_var->flags & PLUGIN_VAR_THDLOCAL) && type != OPT_GLOBAL; }
+ bool check_update_type(Item_result type);
+ SHOW_TYPE show_type();
+ byte* real_value_ptr(THD *thd, enum_var_type type);
+ TYPELIB* plugin_var_typelib(void);
+ byte* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ bool check(THD *thd, set_var *var);
+ void set_default(THD *thd, enum_var_type type);
+ bool update(THD *thd, set_var *var);
+};
+
+
/* prototypes */
-my_bool plugin_register_builtin(struct st_mysql_plugin *plugin);
-void plugin_load(void);
+static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv);
+static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
+ const char *list);
+static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
+ int *, char **, my_bool);
+static bool register_builtin(struct st_mysql_plugin *, struct st_plugin_int *,
+ struct st_plugin_int **);
+static void unlock_variables(THD *thd, struct system_variables *vars);
+static void cleanup_variables(THD *thd, struct system_variables *vars);
+static void plugin_opt_set_limits(struct my_option *options,
+ const struct st_mysql_sys_var *opt);
+#define my_intern_plugin_lock(A,B) intern_plugin_lock(A,B CALLER_INFO)
+#define my_intern_plugin_lock_ci(A,B) intern_plugin_lock(A,B ORIG_CALLER_INFO)
+static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin
+ CALLER_INFO_PROTO);
+static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
+static void reap_plugins(void);
+
+
+/* declared in set_var.cc */
+extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error);
+
+
+/****************************************************************************
+ Value type thunks, allows the C world to play in the C++ world
+****************************************************************************/
+
+static int item_value_type(struct st_mysql_value *value)
+{
+ switch (((st_item_value_holder*)value)->item->result_type()) {
+ case INT_RESULT:
+ return MYSQL_VALUE_TYPE_INT;
+ case REAL_RESULT:
+ return MYSQL_VALUE_TYPE_REAL;
+ default:
+ return MYSQL_VALUE_TYPE_STRING;
+ }
+}
+
+static const char *item_val_str(struct st_mysql_value *value,
+ char *buffer, int *length)
+{
+ String str(buffer, *length, system_charset_info), *res;
+ if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
+ return NULL;
+ *length= res->length();
+ if (res->c_ptr_quick() == buffer)
+ return buffer;
+
+ /*
+ Lets be nice and create a temporary string since the
+ buffer was too small
+ */
+ return current_thd->strmake(res->c_ptr_quick(), res->length());
+}
+
+
+static int item_val_int(struct st_mysql_value *value, long long *buf)
+{
+ Item *item= ((st_item_value_holder*)value)->item;
+ *buf= item->val_int();
+ if (item->is_null())
+ return 1;
+ return 0;
+}
+
+
+static int item_val_real(struct st_mysql_value *value, double *buf)
+{
+ Item *item= ((st_item_value_holder*)value)->item;
+ *buf= item->val_real();
+ if (item->is_null())
+ return 1;
+ return 0;
+}
+
+
+/****************************************************************************
+ Plugin support code
+****************************************************************************/
#ifdef HAVE_DLOPEN
static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
{
uint i;
+ struct st_plugin_dl *tmp;
DBUG_ENTER("plugin_dl_find");
for (i= 0; i < plugin_dl_array.elements; i++)
{
- struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
- struct st_plugin_dl *);
+ tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
if (tmp->ref_count &&
! my_strnncoll(files_charset_info,
(const uchar *)dl->str, dl->length,
@@ -117,11 +288,11 @@ static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
{
uint i;
+ struct st_plugin_dl *tmp;
DBUG_ENTER("plugin_dl_insert_or_reuse");
for (i= 0; i < plugin_dl_array.elements; i++)
{
- struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
- struct st_plugin_dl *);
+ tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
if (! tmp->ref_count)
{
memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
@@ -147,6 +318,7 @@ static inline void free_plugin_mem(struct st_plugin_dl *p)
my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
}
+
static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
#ifdef HAVE_DLOPEN
@@ -335,6 +507,9 @@ static void plugin_dl_del(const LEX_STRING *dl)
#ifdef HAVE_DLOPEN
uint i;
DBUG_ENTER("plugin_dl_del");
+
+ safe_mutex_assert_owner(&LOCK_plugin);
+
for (i= 0; i < plugin_dl_array.elements; i++)
{
struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
@@ -364,6 +539,9 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty
DBUG_ENTER("plugin_find_internal");
if (! initialized)
DBUG_RETURN(0);
+
+ safe_mutex_assert_owner(&LOCK_plugin);
+
if (type == MYSQL_ANY_PLUGIN)
{
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
@@ -381,33 +559,109 @@ static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int ty
}
-my_bool plugin_is_ready(const LEX_STRING *name, int type)
+static SHOW_COMP_OPTION plugin_status(const LEX_STRING *name, int type)
{
- my_bool rc= FALSE;
+ SHOW_COMP_OPTION rc= SHOW_OPTION_NO;
struct st_plugin_int *plugin;
DBUG_ENTER("plugin_is_ready");
- rw_rdlock(&THR_LOCK_plugin);
- if ((plugin= plugin_find_internal(name, type)) &&
- plugin->state == PLUGIN_IS_READY)
- rc= TRUE;
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_lock(&LOCK_plugin);
+ if ((plugin= plugin_find_internal(name, type)))
+ {
+ rc= SHOW_OPTION_DISABLED;
+ if (plugin->state == PLUGIN_IS_READY)
+ rc= SHOW_OPTION_YES;
+ }
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
-struct st_plugin_int *plugin_lock(const LEX_STRING *name, int type)
+bool plugin_is_ready(const LEX_STRING *name, int type)
{
- struct st_plugin_int *rc;
- DBUG_ENTER("plugin_lock");
- rw_wrlock(&THR_LOCK_plugin);
- if ((rc= plugin_find_internal(name, type)))
+ bool rc= FALSE;
+ if (plugin_status(name, type) == SHOW_OPTION_YES)
+ rc= TRUE;
+ return rc;
+}
+
+
+SHOW_COMP_OPTION sys_var_have_plugin::get_option()
+{
+ LEX_STRING plugin_name= { (char *) plugin_name_str, plugin_name_len };
+ return plugin_status(&plugin_name, plugin_type);
+}
+
+
+static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
+{
+ st_plugin_int *pi= plugin_ref_to_int(rc);
+ DBUG_ENTER("intern_plugin_lock");
+
+ safe_mutex_assert_owner(&LOCK_plugin);
+
+ if (pi->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
{
- if (rc->state & (PLUGIN_IS_READY | PLUGIN_IS_UNINITIALIZED))
- rc->ref_count++;
- else
- rc= 0;
+ plugin_ref plugin;
+#ifdef DBUG_OFF
+ /* built-in plugins don't need ref counting */
+ if (!pi->plugin_dl)
+ DBUG_RETURN(pi);
+
+ plugin= pi;
+#else
+ /*
+ For debugging, we do an additional malloc which allows the
+ memory manager and/or valgrind to track locked references and
+ double unlocks to aid resolving reference counting.problems.
+ */
+ if (!(plugin= (plugin_ref) my_malloc_ci(sizeof(pi), MYF(MY_WME))))
+ DBUG_RETURN(NULL);
+
+ *plugin= pi;
+#endif
+ pi->ref_count++;
+ DBUG_PRINT("info",("thd: 0x%lx, plugin: \"%s\", ref_count: %d",
+ (long) current_thd, pi->name.str, pi->ref_count));
+
+ if (lex)
+ insert_dynamic(&lex->plugins, (gptr)&plugin);
+ DBUG_RETURN(plugin);
}
- rw_unlock(&THR_LOCK_plugin);
+ DBUG_RETURN(NULL);
+}
+
+
+plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
+{
+ LEX *lex= NULL;
+ plugin_ref rc;
+ DBUG_ENTER("plugin_lock");
+ /*
+ thd->lex may point to a nested LEX or a stored procedure LEX.
+ main_lex is tightly coupled to the thread.
+ */
+ if (thd)
+ lex= !thd->lex ? &thd->main_lex : thd->lex;
+ pthread_mutex_lock(&LOCK_plugin);
+ rc= my_intern_plugin_lock_ci(lex, *ptr);
+ pthread_mutex_unlock(&LOCK_plugin);
+ DBUG_RETURN(rc);
+}
+
+
+plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type
+ CALLER_INFO_PROTO)
+{
+ LEX *lex= NULL;
+ plugin_ref rc= NULL;
+ st_plugin_int *plugin;
+ DBUG_ENTER("plugin_lock");
+ if (thd)
+ lex= !thd->lex ? &thd->main_lex : thd->lex;
+ pthread_mutex_lock(&LOCK_plugin);
+ if ((plugin= plugin_find_internal(name, type)))
+ rc= my_intern_plugin_lock_ci(lex, plugin_int_to_ref(plugin));
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -432,7 +686,14 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
struct st_plugin_int *));
}
-static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int report)
+
+/*
+ NOTE
+ Requires that a write-lock is held on LOCK_system_variables_hash
+*/
+static bool plugin_add(MEM_ROOT *tmp_root,
+ const LEX_STRING *name, const LEX_STRING *dl,
+ int *argc, char **argv, int report)
{
struct st_plugin_int tmp;
struct st_mysql_plugin *plugin;
@@ -478,14 +739,24 @@ static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int repo
tmp.name.length= name_len;
tmp.ref_count= 0;
tmp.state= PLUGIN_IS_UNINITIALIZED;
- if (! (tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
- goto err;
- plugin_array_version++;
- if (my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr))
+
+ if (!test_plugin_options(tmp_root, &tmp, argc, argv, true))
{
- tmp_plugin_ptr->state= PLUGIN_IS_FREED;
+ if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
+ {
+ plugin_array_version++;
+ if (!my_hash_insert(&plugin_hash[plugin->type], (byte*)tmp_plugin_ptr))
+ {
+ init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
+ DBUG_RETURN(FALSE);
+ }
+ tmp_plugin_ptr->state= PLUGIN_IS_FREED;
+ }
+ mysql_del_sys_var_chain(tmp.system_vars);
goto err;
}
+ /* plugin was disabled */
+ plugin_dl_del(dl);
DBUG_RETURN(FALSE);
}
}
@@ -499,8 +770,14 @@ err:
}
-void plugin_deinitialize(struct st_plugin_int *plugin)
+static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
{
+ /*
+ we don't want to hold the LOCK_plugin mutex as it may cause
+ deinitialization to deadlock if plugins have worker threads
+ with plugin locks
+ */
+ safe_mutex_assert_not_owner(&LOCK_plugin);
if (plugin->plugin->status_vars)
{
@@ -528,7 +805,7 @@ void plugin_deinitialize(struct st_plugin_int *plugin)
{
sql_print_error("Plugin '%s' of type %s failed deinitialization",
plugin->name.str, plugin_type_names[plugin->plugin->type].str);
- }
+ }
}
else if (plugin->plugin->deinit)
{
@@ -540,16 +817,29 @@ void plugin_deinitialize(struct st_plugin_int *plugin)
}
}
plugin->state= PLUGIN_IS_UNINITIALIZED;
+
+ /*
+ We do the check here because NDB has a worker THD which doesn't
+ exit until NDB is shut down.
+ */
+ if (ref_check && plugin->ref_count)
+ sql_print_error("Plugin '%s' has ref_count=%d after deinitialization.",
+ plugin->name.str, plugin->ref_count);
}
static void plugin_del(struct st_plugin_int *plugin)
{
DBUG_ENTER("plugin_del(plugin)");
+ safe_mutex_assert_owner(&LOCK_plugin);
hash_delete(&plugin_hash[plugin->plugin->type], (byte*)plugin);
plugin_dl_del(&plugin->plugin_dl->dl);
plugin->state= PLUGIN_IS_FREED;
plugin_array_version++;
+ rw_wrlock(&LOCK_system_variables_hash);
+ mysql_del_sys_var_chain(plugin->system_vars);
+ rw_unlock(&LOCK_system_variables_hash);
+ free_root(&plugin->mem_root, MYF(0));
DBUG_VOID_RETURN;
}
@@ -566,18 +856,123 @@ static void plugin_del(const LEX_STRING *name)
#endif
-void plugin_unlock(struct st_plugin_int *plugin)
+static void reap_plugins(void)
{
- DBUG_ENTER("plugin_unlock");
- rw_wrlock(&THR_LOCK_plugin);
- DBUG_ASSERT(plugin && plugin->ref_count);
- plugin->ref_count--;
- if (plugin->state == PLUGIN_IS_DELETED && ! plugin->ref_count)
+ uint count, idx;
+ struct st_plugin_int *plugin, **reap, **list;
+
+ safe_mutex_assert_owner(&LOCK_plugin);
+
+ if (!reap_needed)
+ return;
+
+ reap_needed= false;
+ count= plugin_array.elements;
+ reap= (struct st_plugin_int **)my_alloca(sizeof(plugin)*(count+1));
+ *(reap++)= NULL;
+
+ for (idx= 0; idx < count; idx++)
{
- plugin_deinitialize(plugin);
+ plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+ if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count)
+ {
+ /* change the status flag to prevent reaping by another thread */
+ plugin->state= PLUGIN_IS_DYING;
+ *(reap++)= plugin;
+ }
+ }
+
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ list= reap;
+ while ((plugin= *(--list)))
+ plugin_deinitialize(plugin, true);
+
+ pthread_mutex_lock(&LOCK_plugin);
+
+ while ((plugin= *(--reap)))
plugin_del(plugin);
+
+ my_afree(reap);
+}
+
+static void intern_plugin_unlock(LEX *lex, plugin_ref plugin)
+{
+ int i;
+ st_plugin_int *pi;
+ DBUG_ENTER("intern_plugin_unlock");
+
+ safe_mutex_assert_owner(&LOCK_plugin);
+
+ if (!plugin)
+ DBUG_VOID_RETURN;
+
+ pi= plugin_ref_to_int(plugin);
+
+#ifdef DBUG_OFF
+ if (!pi->plugin_dl)
+ DBUG_VOID_RETURN;
+#else
+ my_free((gptr) plugin, MYF(MY_WME));
+#endif
+
+ DBUG_PRINT("info",("unlocking plugin, name= %s, ref_count= %d",
+ pi->name.str, pi->ref_count));
+ if (lex)
+ {
+ /*
+ Remove one instance of this plugin from the use list.
+ We are searching backwards so that plugins locked last
+ could be unlocked faster - optimizing for LIFO semantics.
+ */
+ for (i= lex->plugins.elements - 1; i >= 0; i--)
+ if (plugin == *dynamic_element(&lex->plugins, i, plugin_ref*))
+ {
+ delete_dynamic_element(&lex->plugins, i);
+ break;
+ }
+ DBUG_ASSERT(i >= 0);
}
- rw_unlock(&THR_LOCK_plugin);
+
+ DBUG_ASSERT(pi->ref_count);
+ pi->ref_count--;
+
+ if (pi->state == PLUGIN_IS_DELETED && !pi->ref_count)
+ reap_needed= true;
+
+ DBUG_VOID_RETURN;
+}
+
+
+void plugin_unlock(THD *thd, plugin_ref plugin)
+{
+ LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex) : NULL;
+ DBUG_ENTER("plugin_unlock");
+ if (!plugin)
+ DBUG_VOID_RETURN;
+#ifdef DBUG_OFF
+ /* built-in plugins don't need ref counting */
+ if (!plugin_dlib(plugin))
+ DBUG_VOID_RETURN;
+#endif
+ pthread_mutex_lock(&LOCK_plugin);
+ intern_plugin_unlock(lex, plugin);
+ reap_plugins();
+ pthread_mutex_unlock(&LOCK_plugin);
+ DBUG_VOID_RETURN;
+}
+
+
+void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
+{
+ LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex) : NULL;
+ DBUG_ENTER("plugin_unlock_list");
+ DBUG_ASSERT(list);
+ pthread_mutex_lock(&LOCK_plugin);
+ while (count--)
+ intern_plugin_unlock(lex, *list++);
+ reap_plugins();
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_VOID_RETURN;
}
@@ -586,6 +981,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
{
DBUG_ENTER("plugin_initialize");
+ safe_mutex_assert_owner(&LOCK_plugin);
+
if (plugin_type_initialize[plugin->plugin->type])
{
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
@@ -628,11 +1025,28 @@ static int plugin_initialize(struct st_plugin_int *plugin)
#endif /* FIX_LATER */
}
+ /*
+ set the plugin attribute of plugin's sys vars so they are pointing
+ to the active plugin
+ */
+ if (plugin->system_vars)
+ {
+ sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
+ for (;;)
+ {
+ var->plugin= plugin;
+ if (!var->next)
+ break;
+ var= var->next->cast_pluginvar();
+ }
+ }
+
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
}
+
static byte *get_hash_key(const byte *buff, uint *length,
my_bool not_used __attribute__((unused)))
{
@@ -642,24 +1056,44 @@ static byte *get_hash_key(const byte *buff, uint *length,
}
+static byte *get_bookmark_hash_key(const byte *buff, uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ struct st_bookmark *var= (st_bookmark *)buff;
+ *length= var->name_len + 1;
+ return (byte*) var->key;
+}
+
+
/*
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
skip this part).
- Finally we inializie everything, aka the dynamic that have yet to initialize.
+ Finally we initialize everything, aka the dynamic that have yet to initialize.
*/
-int plugin_init(int skip_dynamic_loading)
+int plugin_init(int *argc, char **argv, int flags)
{
uint i;
+ bool def_enabled, is_myisam;
struct st_mysql_plugin **builtins;
struct st_mysql_plugin *plugin;
+ struct st_plugin_int tmp, *plugin_ptr, **reap;
+ MEM_ROOT tmp_root;
DBUG_ENTER("plugin_init");
if (initialized)
DBUG_RETURN(0);
- my_rwlock_init(&THR_LOCK_plugin, NULL);
+ init_alloc_root(&plugin_mem_root, 4096, 4096);
+ init_alloc_root(&tmp_root, 4096, 4096);
+
+ if (hash_init(&bookmark_hash, &my_charset_bin, 16, 0, 0,
+ get_bookmark_hash_key, NULL, HASH_UNIQUE))
+ goto err;
+
+
+ pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&plugin_dl_array,
sizeof(struct st_plugin_dl),16,16) ||
@@ -670,10 +1104,14 @@ int plugin_init(int skip_dynamic_loading)
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
{
if (hash_init(&plugin_hash[i], system_charset_info, 16, 0, 0,
- get_hash_key, NULL, 0))
+ get_hash_key, NULL, HASH_UNIQUE))
goto err;
}
+ pthread_mutex_lock(&LOCK_plugin);
+
+ initialized= 1;
+
/*
First we register builtin plugins
*/
@@ -681,83 +1119,185 @@ int plugin_init(int skip_dynamic_loading)
{
for (plugin= *builtins; plugin->info; plugin++)
{
-// if (!(strcmp(plugin->name, "MyISAM")))
+ /* by default, only ndbcluster is disabled */
+ def_enabled=
+ my_strcasecmp(&my_charset_latin1, plugin->name, "NDBCLUSTER") != 0;
+ bzero(&tmp, sizeof(tmp));
+ tmp.plugin= plugin;
+ tmp.name.str= (char *)plugin->name;
+ tmp.name.length= strlen(plugin->name);
+
+ free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ if (test_plugin_options(&tmp_root, &tmp, argc, argv, def_enabled))
+ continue;
+
+ if (register_builtin(plugin, &tmp, &plugin_ptr))
+ goto err_unlock;
+
+ /* only initialize MyISAM and CSV at this stage */
+ if (!(is_myisam=
+ !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM")) &&
+ my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
+ continue;
+
+ if (plugin_initialize(plugin_ptr))
+ goto err_unlock;
+
+ /*
+ initialize the global default storage engine so that it may
+ not be null in any child thread.
+ */
+ if (is_myisam)
{
- if (plugin_register_builtin(plugin))
- goto err;
- struct st_plugin_int *tmp= dynamic_element(&plugin_array,
- plugin_array.elements-1,
- struct st_plugin_int *);
- if (plugin_initialize(tmp))
- goto err;
+ DBUG_ASSERT(!global_system_variables.table_plugin);
+ global_system_variables.table_plugin= (plugin_ref)
+ my_malloc(sizeof(plugin_ptr), MYF(MY_WME | MY_FAE));
+ global_system_variables.table_plugin[0]= plugin_ptr;
+ plugin_ptr->ref_count++;
+ DBUG_ASSERT(plugin_ptr->ref_count == 1);
}
}
}
+ /* should now be set to MyISAM storage engine */
+ DBUG_ASSERT(global_system_variables.table_plugin);
+
+ pthread_mutex_unlock(&LOCK_plugin);
+
/* Register all dynamic plugins */
- if (!skip_dynamic_loading)
- plugin_load();
+ if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
+ {
+ if (opt_plugin_load &&
+ plugin_load_list(&tmp_root, argc, argv, opt_plugin_load))
+ goto err;
+ if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE))
+ plugin_load(&tmp_root, argc, argv);
+ }
- initialized= 1;
+ if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
+ goto end;
/*
Now we initialize all remaining plugins
*/
+ pthread_mutex_lock(&LOCK_plugin);
+ reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
+ *(reap++)= NULL;
+
for (i= 0; i < plugin_array.elements; i++)
{
- struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
- struct st_plugin_int *);
- if (tmp->state == PLUGIN_IS_UNINITIALIZED)
+ plugin_ptr= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
{
- if (plugin_initialize(tmp))
+ if (plugin_initialize(plugin_ptr))
{
- plugin_deinitialize(tmp);
- plugin_del(tmp);
+ plugin_ptr->state= PLUGIN_IS_DYING;
+ *(reap++)= plugin_ptr;
}
}
}
+ /*
+ Check if any plugins have to be reaped
+ */
+ while ((plugin_ptr= *(--reap)))
+ {
+ pthread_mutex_unlock(&LOCK_plugin);
+ plugin_deinitialize(plugin_ptr, true);
+ pthread_mutex_lock(&LOCK_plugin);
+ plugin_del(plugin_ptr);
+ }
+
+ pthread_mutex_unlock(&LOCK_plugin);
+ my_afree(reap);
+
+end:
+ free_root(&tmp_root, MYF(0));
DBUG_RETURN(0);
+err_unlock:
+ pthread_mutex_unlock(&LOCK_plugin);
err:
+ free_root(&tmp_root, MYF(0));
DBUG_RETURN(1);
}
-my_bool plugin_register_builtin(struct st_mysql_plugin *plugin)
+static bool register_builtin(struct st_mysql_plugin *plugin,
+ struct st_plugin_int *tmp,
+ struct st_plugin_int **ptr)
{
- struct st_plugin_int tmp;
+ DBUG_ENTER("register_builtin");
+
+ tmp->state= PLUGIN_IS_UNINITIALIZED;
+ tmp->ref_count= 0;
+ tmp->plugin_dl= 0;
+
+ if (insert_dynamic(&plugin_array, (gptr)tmp))
+ DBUG_RETURN(1);
+
+ *ptr= dynamic_element(&plugin_array, plugin_array.elements - 1,
+ struct st_plugin_int *);
+
+ if (my_hash_insert(&plugin_hash[plugin->type],(byte*) *ptr))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(0);
+}
+
+
+#ifdef NOT_USED_YET
+/*
+ Register a plugin at run time. (note, this doesn't initialize a plugin)
+ Will be useful for embedded applications.
+
+ SYNOPSIS
+ plugin_register_builtin()
+ thd current thread (used to store scratch data in mem_root)
+ plugin static plugin to install
+
+ RETURN
+ false - plugin registered successfully
+*/
+bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
+{
+ struct st_plugin_int tmp, *ptr;
+ bool result= true;
+ int dummy_argc= 0;
DBUG_ENTER("plugin_register_builtin");
+ bzero(&tmp, sizeof(tmp));
tmp.plugin= plugin;
tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name);
- tmp.state= PLUGIN_IS_UNINITIALIZED;
- /* Cannot be unloaded */
- tmp.ref_count= 1;
- tmp.plugin_dl= 0;
+ pthread_mutex_lock(&LOCK_plugin);
+ rw_wrlock(&LOCK_system_variables_hash);
- if (insert_dynamic(&plugin_array, (gptr)&tmp))
- DBUG_RETURN(1);
+ if (test_plugin_options(thd->mem_root, &tmp, &dummy_argc, NULL, true))
+ goto end;
- if (my_hash_insert(&plugin_hash[plugin->type],
- (byte*)dynamic_element(&plugin_array,
- plugin_array.elements - 1,
- struct st_plugin_int *)))
- DBUG_RETURN(1);
+ if ((result= register_builtin(plugin, &tmp, &ptr)))
+ mysql_del_sys_var_chain(tmp.system_vars);
- DBUG_RETURN(0);
+end:
+ rw_unlock(&LOCK_system_variables_hash);
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ DBUG_RETURN(result);;
}
+#endif /* NOT_USED_YET */
-void plugin_load(void)
+/*
+ called only by plugin_init()
+*/
+static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
{
TABLE_LIST tables;
TABLE *table;
READ_RECORD read_record_info;
int error;
- MEM_ROOT mem;
THD *new_thd;
DBUG_ENTER("plugin_load");
@@ -767,7 +1307,6 @@ void plugin_load(void)
delete new_thd;
DBUG_VOID_RETURN;
}
- init_sql_alloc(&mem, 1024, 0);
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
new_thd->db= my_strdup("mysql", MYF(0));
@@ -785,26 +1324,34 @@ void plugin_load(void)
table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL, 1, 0);
table->use_all_columns();
+ /*
+ there're no other threads running yet, so we don't need a mutex.
+ but plugin_add() before is designed to work in multi-threaded
+ environment, and it uses safe_mutex_assert_owner(), so we lock
+ the mutex here to satisfy the assert
+ */
+ pthread_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info", ("init plugin record"));
String str_name, str_dl;
- get_field(&mem, table->field[0], &str_name);
- get_field(&mem, table->field[1], &str_dl);
-
+ get_field(tmp_root, table->field[0], &str_name);
+ get_field(tmp_root, table->field[1], &str_dl);
+
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(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
str_name.c_ptr(), str_dl.c_ptr());
+ free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
}
+ pthread_mutex_unlock(&LOCK_plugin);
if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info);
new_thd->version--; // Force close to free memory
end:
- free_root(&mem, MYF(0));
close_thread_tables(new_thd);
delete new_thd;
/* Remember that we don't have a THD */
@@ -813,46 +1360,221 @@ end:
}
+/*
+ called only by plugin_init()
+*/
+static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
+ const char *list)
+{
+ char buffer[FN_REFLEN];
+ LEX_STRING name= {buffer, 0}, dl= {NULL, 0}, *str= &name;
+ struct st_plugin_dl *plugin_dl;
+ struct st_mysql_plugin *plugin;
+ char *p= buffer;
+ DBUG_ENTER("plugin_load_list");
+ while (list)
+ {
+ if (p == buffer + sizeof(buffer) - 1)
+ break;
+ switch ((*(p++)= *(list++))) {
+ case '\0':
+ list= NULL; /* terminate the loop */
+ /* fall through */
+#ifndef __WIN__
+ case ':': /* can't use this as delimiter as it may be drive letter */
+#endif
+ case ';':
+ name.str[name.length]= '\0';
+ if (str != &dl) // load all plugins in named module
+ {
+ dl= name;
+ if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
+ {
+ for (plugin= plugin_dl->plugins; plugin->info; plugin++)
+ {
+ name.str= (char *) plugin->name;
+ name.length= strlen(name.str);
+
+ free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
+ goto error;
+ }
+ plugin_dl_del(&dl); // reduce ref count
+ }
+ }
+ else
+ {
+ free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
+ goto error;
+ }
+ name.length= dl.length= 0;
+ dl.str= NULL; name.str= p= buffer;
+ str= &name;
+ continue;
+ case '=':
+ case '#':
+ if (str == &name)
+ {
+ str= &dl;
+ str->str= p;
+ continue;
+ }
+ default:
+ str->length++;
+ continue;
+ }
+ }
+ DBUG_RETURN(FALSE);
+error:
+ sql_print_error("Couldn't load plugin named '%s' with soname '%s'.",
+ name.str, dl.str);
+ DBUG_RETURN(TRUE);
+}
+
+
void plugin_shutdown(void)
{
- uint i;
+ uint i, count= plugin_array.elements, free_slots;
+ struct st_plugin_int **plugins, *plugin;
+ struct st_plugin_dl **dl;
DBUG_ENTER("plugin_shutdown");
- /*
- We loop through all plugins and call deinit() if they have one.
- */
- for (i= 0; i < plugin_array.elements; i++)
+ if (initialized)
{
- struct st_plugin_int *tmp= dynamic_element(&plugin_array, i,
- struct st_plugin_int *);
- plugin_deinitialize(tmp);
+ pthread_mutex_lock(&LOCK_plugin);
+
+ reap_needed= true;
+
+ /*
+ We want to shut down plugins in a reasonable order, this will
+ become important when we have plugins which depend upon each other.
+ Circular references cannot be reaped so they are forced afterwards.
+ TODO: Have an additional step here to notify all active plugins that
+ shutdown is requested to allow plugins to deinitialize in parallel.
+ */
+ while (reap_needed && (count= plugin_array.elements))
+ {
+ reap_plugins();
+ for (i= free_slots= 0; i < count; i++)
+ {
+ plugin= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ switch (plugin->state) {
+ case PLUGIN_IS_READY:
+ plugin->state= PLUGIN_IS_DELETED;
+ reap_needed= true;
+ break;
+ case PLUGIN_IS_FREED:
+ case PLUGIN_IS_UNINITIALIZED:
+ free_slots++;
+ break;
+ }
+ }
+ if (!reap_needed)
+ {
+ /*
+ release any plugin references held.
+ */
+ unlock_variables(NULL, &global_system_variables);
+ unlock_variables(NULL, &max_system_variables);
+ }
+ }
+
+ if (count > free_slots)
+ sql_print_warning("Forcing shutdown of %d plugins", count - free_slots);
+
+ plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
+
+ /*
+ If we have any plugins which did not die cleanly, we force shutdown
+ */
+ for (i= 0; i < count; i++)
+ {
+ plugins[i]= dynamic_element(&plugin_array, i, struct st_plugin_int *);
+ /* change the state to ensure no reaping races */
+ if (plugins[i]->state == PLUGIN_IS_DELETED)
+ plugins[i]->state= PLUGIN_IS_DYING;
+ }
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ /*
+ We loop through all plugins and call deinit() if they have one.
+ */
+ for (i= 0; i < count; i++)
+ if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED)))
+ {
+ sql_print_information("Plugin '%s' will be forced to shutdown",
+ plugins[i]->name.str);
+ /*
+ We are forcing deinit on plugins so we don't want to do a ref_count
+ check until we have processed all the plugins.
+ */
+ plugin_deinitialize(plugins[i], false);
+ }
+
+ /*
+ It's perfectly safe not to lock LOCK_plugin, as there're no
+ concurrent threads anymore. But some functions called from here
+ use safe_mutex_assert_owner(), so we lock the mutex to satisfy it
+ */
+ pthread_mutex_lock(&LOCK_plugin);
+ /*
+ We defer checking ref_counts until after all plugins are deinitialized
+ as some may have worker threads holding on to plugin references.
+ */
+ for (i= 0; i < count; i++)
+ {
+ if (plugins[i]->ref_count)
+ sql_print_error("Plugin '%s' has ref_count=%d after shutdown.",
+ plugins[i]->name.str, plugins[i]->ref_count);
+ if (plugins[i]->state & PLUGIN_IS_UNINITIALIZED)
+ plugin_del(plugins[i]);
+ }
+
+ /*
+ Now we can deallocate all memory.
+ */
+
+ cleanup_variables(NULL, &global_system_variables);
+ cleanup_variables(NULL, &max_system_variables);
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ initialized= 0;
+ pthread_mutex_destroy(&LOCK_plugin);
+
+ my_afree(plugins);
}
+ /* Dispose of the memory */
+
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
hash_free(&plugin_hash[i]);
delete_dynamic(&plugin_array);
+
+ count= plugin_dl_array.elements;
+ dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
+ for (i= 0; i < count; i++)
+ dl[i]= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *);
for (i= 0; i < plugin_dl_array.elements; i++)
- {
- struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i,
- struct st_plugin_dl *);
- free_plugin_mem(tmp);
- }
+ free_plugin_mem(dl[i]);
+ my_afree(dl);
delete_dynamic(&plugin_dl_array);
- if (initialized)
- {
- initialized= 0;
- rwlock_destroy(&THR_LOCK_plugin);
- }
+
+ hash_free(&bookmark_hash);
+ free_root(&plugin_mem_root, MYF(0));
+
+ global_variables_dynamic_size= 0;
+
DBUG_VOID_RETURN;
}
-my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl)
+bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl)
{
TABLE_LIST tables;
TABLE *table;
- int error;
+ int error, argc=0;
struct st_plugin_int *tmp;
DBUG_ENTER("mysql_install_plugin");
@@ -862,14 +1584,17 @@ my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING
if (check_table_access(thd, INSERT_ACL, &tables, 0))
DBUG_RETURN(TRUE);
- /* need to open before acquiring THR_LOCK_plugin or it will deadlock */
+ /* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table = open_ltable(thd, &tables, TL_WRITE)))
DBUG_RETURN(TRUE);
- rw_wrlock(&THR_LOCK_plugin);
- if (plugin_add(name, dl, REPORT_TO_USER))
+ pthread_mutex_lock(&LOCK_plugin);
+ rw_wrlock(&LOCK_system_variables_hash);
+ error= plugin_add(thd->mem_root, name, dl, &argc, NULL, REPORT_TO_USER);
+ rw_unlock(&LOCK_system_variables_hash);
+
+ if (error || !(tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
goto err;
- tmp= plugin_find_internal(name, MYSQL_ANY_PLUGIN);
if (plugin_initialize(tmp))
{
@@ -889,18 +1614,19 @@ my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING
goto deinit;
}
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(FALSE);
deinit:
- plugin_deinitialize(tmp);
- plugin_del(tmp);
+ tmp->state= PLUGIN_IS_DELETED;
+ reap_needed= true;
+ reap_plugins();
err:
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(TRUE);
}
-my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
+bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
{
TABLE *table;
TABLE_LIST tables;
@@ -911,11 +1637,11 @@ my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
- /* need to open before acquiring THR_LOCK_plugin or it will deadlock */
+ /* need to open before acquiring LOCK_plugin or it will deadlock */
if (! (table= open_ltable(thd, &tables, TL_WRITE)))
DBUG_RETURN(TRUE);
- rw_wrlock(&THR_LOCK_plugin);
+ pthread_mutex_lock(&LOCK_plugin);
if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str);
@@ -929,17 +1655,14 @@ my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
goto err;
}
+ plugin->state= PLUGIN_IS_DELETED;
if (plugin->ref_count)
- {
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"Plugin is busy and will be uninstalled on shutdown");
- plugin->state= PLUGIN_IS_DELETED;
- }
else
- {
- plugin_deinitialize(plugin);
- plugin_del(plugin);
- }
+ reap_needed= true;
+ reap_plugins();
+ pthread_mutex_unlock(&LOCK_plugin);
table->use_all_columns();
table->field[0]->store(name->str, name->length, system_charset_info);
@@ -951,17 +1674,17 @@ my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
if ((error= table->file->ha_delete_row(table->record[0])))
{
table->file->print_error(error, MYF(0));
- goto err;
+ DBUG_RETURN(TRUE);
}
}
- rw_unlock(&THR_LOCK_plugin);
DBUG_RETURN(FALSE);
err:
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(TRUE);
}
-my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
+
+bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
int type, uint state_mask, void *arg)
{
uint idx, total;
@@ -969,16 +1692,19 @@ my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
int version=plugin_array_version;
DBUG_ENTER("plugin_foreach_with_mask");
+ if (!initialized)
+ DBUG_RETURN(FALSE);
+
state_mask= ~state_mask; // do it only once
- rw_rdlock(&THR_LOCK_plugin);
- total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements
+ pthread_mutex_lock(&LOCK_plugin);
+ total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements
: plugin_hash[type].records;
/*
Do the alloca out here in case we do have a working alloca:
- leaving the nested stack frame invalidates alloca allocation.
+ leaving the nested stack frame invalidates alloca allocation.
*/
- plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins));
+ plugins=(struct st_plugin_int **)my_alloca(total*sizeof(plugin));
if (type == MYSQL_ANY_PLUGIN)
{
for (idx= 0; idx < total; idx++)
@@ -996,20 +1722,20 @@ my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
}
}
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_plugin);
for (idx= 0; idx < total; idx++)
{
if (unlikely(version != plugin_array_version))
{
- rw_rdlock(&THR_LOCK_plugin);
+ pthread_mutex_lock(&LOCK_plugin);
for (uint i=idx; i < total; i++)
if (plugins[i] && plugins[i]->state & state_mask)
plugins[i]=0;
- rw_unlock(&THR_LOCK_plugin);
+ pthread_mutex_unlock(&LOCK_plugin);
}
plugin= plugins[idx];
- if (plugin && func(thd, plugin, arg))
+ if (plugin && func(thd, plugin_int_to_ref(plugin), arg))
goto err;
}
@@ -1020,3 +1746,1329 @@ err:
DBUG_RETURN(TRUE);
}
+
+/****************************************************************************
+ Internal type declarations for variables support
+****************************************************************************/
+
+#undef MYSQL_SYSVAR_NAME
+#define MYSQL_SYSVAR_NAME(name) name
+#define PLUGIN_VAR_TYPEMASK 0x007f
+
+#define EXTRA_OPTIONS 3 /* options for: 'foo', 'plugin-foo' and NULL */
+
+typedef DECLARE_MYSQL_SYSVAR_BASIC(sysvar_bool_t, my_bool);
+typedef DECLARE_MYSQL_THDVAR_BASIC(thdvar_bool_t, my_bool);
+typedef DECLARE_MYSQL_SYSVAR_BASIC(sysvar_str_t, char *);
+typedef DECLARE_MYSQL_THDVAR_BASIC(thdvar_str_t, char *);
+
+typedef DECLARE_MYSQL_SYSVAR_TYPELIB(sysvar_typelib_t);
+typedef DECLARE_MYSQL_THDVAR_TYPELIB(thdvar_typelib_t);
+
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_int_t, int);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_long_t, long);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_longlong_t, longlong);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_uint_t, uint);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulonglong_t, ulonglong);
+
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_int_t, int);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_long_t, long);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_longlong_t, longlong);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
+
+#define SET_PLUGIN_VAR_RESOLVE(opt)\
+ *(mysql_sys_var_ptr_p*)&((opt)->resolve)= mysql_sys_var_ptr
+typedef byte *(*mysql_sys_var_ptr_p)(void* a_thd, int offset);
+
+
+/****************************************************************************
+ default variable data check and update functions
+****************************************************************************/
+
+static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ const char *strvalue= "NULL", *str;
+ int result, length;
+ long long tmp;
+
+ if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
+ {
+ length= sizeof(buff);
+ if (!(str= value->val_str(value, buff, &length)) ||
+ (result= find_type(&bool_typelib, str, length, 1)-1) < 0)
+ {
+ if (str)
+ strvalue= str;
+ goto err;
+ }
+ }
+ else
+ {
+ if (value->val_int(value, &tmp) < 0)
+ goto err;
+ if (tmp > 1)
+ {
+ llstr(tmp, buff);
+ strvalue= buff;
+ goto err;
+ }
+ result= (int) tmp;
+ }
+ *(int*)save= -result;
+ return 0;
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
+ return 1;
+}
+
+
+static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ long long tmp;
+ struct my_option options;
+ value->val_int(value, &tmp);
+ plugin_opt_set_limits(&options, var);
+ *(int *)save= (int) getopt_ull_limit_value(tmp, &options);
+ return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
+ (*(int *)save != (int) tmp);
+}
+
+
+static int check_func_long(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ long long tmp;
+ struct my_option options;
+ value->val_int(value, &tmp);
+ plugin_opt_set_limits(&options, var);
+ *(long *)save= (long) getopt_ull_limit_value(tmp, &options);
+ return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
+ (*(long *)save != (long) tmp);
+}
+
+
+static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ long long tmp;
+ struct my_option options;
+ value->val_int(value, &tmp);
+ plugin_opt_set_limits(&options, var);
+ *(ulonglong *)save= getopt_ull_limit_value(tmp, &options);
+ return (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES) &&
+ (*(long long *)save != tmp);
+}
+
+static int check_func_str(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ const char *str;
+ int length;
+
+ length= sizeof(buff);
+ if ((str= value->val_str(value, buff, &length)))
+ str= thd->strmake(str, length);
+ *(const char**)save= str;
+ return 0;
+}
+
+
+static int check_func_enum(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ const char *strvalue= "NULL", *str;
+ TYPELIB *typelib;
+ long long tmp;
+ long result;
+ int length;
+
+ if (var->flags & PLUGIN_VAR_THDLOCAL)
+ typelib= ((thdvar_typelib_t*) var)->typelib;
+ else
+ typelib= ((sysvar_typelib_t*) var)->typelib;
+
+ if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
+ {
+ length= sizeof(buff);
+ if (!(str= value->val_str(value, buff, &length)))
+ goto err;
+ if ((result= find_type(typelib, str, length, 1)-1) < 0)
+ {
+ strvalue= str;
+ goto err;
+ }
+ }
+ else
+ {
+ if (value->val_int(value, &tmp))
+ goto err;
+ if (tmp >= typelib->count)
+ {
+ llstr(tmp, buff);
+ strvalue= buff;
+ goto err;
+ }
+ result= (long) tmp;
+ }
+ *(long*)save= result;
+ return 0;
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
+ return 1;
+}
+
+
+static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
+ void *save, st_mysql_value *value)
+{
+ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
+ const char *strvalue= "NULL", *str;
+ TYPELIB *typelib;
+ long result;
+ ulonglong tmp;
+ uint error_len;
+ bool not_used;
+ int length;
+
+ if (var->flags & PLUGIN_VAR_THDLOCAL)
+ typelib= ((thdvar_typelib_t*) var)->typelib;
+ else
+ typelib= ((sysvar_typelib_t*)var)->typelib;
+
+ if (value->value_type(value) == MYSQL_VALUE_TYPE_STRING)
+ {
+ length= sizeof(buff);
+ if (!(str= value->val_str(value, buff, &length)))
+ goto err;
+ result= find_set(typelib, str, length, NULL,
+ &error, &error_len, &not_used);
+ if (error_len)
+ {
+ strmake(buff, error, min(sizeof(buff), error_len));
+ strvalue= buff;
+ goto err;
+ }
+ }
+ else
+ {
+ if (value->val_int(value, (long long *)&tmp))
+ goto err;
+ if (unlikely((tmp >= (ULL(1) << typelib->count)) &&
+ (typelib->count < sizeof(long)*8)))
+ {
+ llstr(tmp, buff);
+ strvalue= buff;
+ goto err;
+ }
+ result= (long) tmp;
+ }
+ *(long*)save= result;
+ return 0;
+err:
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
+ return 1;
+}
+
+
+static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, void *save)
+{
+ *(my_bool *) tgt= *(int *) save ? 1 : 0;
+}
+
+
+static void update_func_int(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, void *save)
+{
+ *(int *)tgt= *(int *) save;
+}
+
+
+static void update_func_long(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, void *save)
+{
+ *(long *)tgt= *(long *) save;
+}
+
+
+static void update_func_longlong(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, void *save)
+{
+ *(longlong *)tgt= *(ulonglong *) save;
+}
+
+
+static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
+ void *tgt, void *save)
+{
+ char *old= *(char **) tgt;
+ *(char **)tgt= *(char **) save;
+ if (var->flags & PLUGIN_VAR_MEMALLOC)
+ {
+ *(char **)tgt= my_strdup(*(char **) save, MYF(0));
+ my_free(old, MYF(0));
+ }
+}
+
+
+/****************************************************************************
+ System Variables support
+****************************************************************************/
+
+
+sys_var *find_sys_var(THD *thd, const char *str, uint length)
+{
+ sys_var *var;
+ sys_var_pluginvar *pi= NULL;
+ plugin_ref plugin;
+ DBUG_ENTER("find_sys_var");
+
+ pthread_mutex_lock(&LOCK_plugin);
+ rw_rdlock(&LOCK_system_variables_hash);
+ if ((var= intern_find_sys_var(str, length, false)) &&
+ (pi= var->cast_pluginvar()))
+ {
+ rw_unlock(&LOCK_system_variables_hash);
+ LEX *lex= thd ? ( !thd->lex ? &thd->main_lex : thd->lex ) : NULL;
+ if (!(plugin= my_intern_plugin_lock(lex, plugin_int_to_ref(pi->plugin))))
+ var= NULL; /* failed to lock it, it must be uninstalling */
+ else
+ if (!(plugin_state(plugin) & PLUGIN_IS_READY))
+ {
+ /* initialization not completed */
+ var= NULL;
+ intern_plugin_unlock(lex, plugin);
+ }
+ }
+ else
+ rw_unlock(&LOCK_system_variables_hash);
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ /*
+ If the variable exists but the plugin it is associated with is not ready
+ then the intern_plugin_lock did not raise an error, so we do it here.
+ */
+ if (pi && !var)
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
+ DBUG_RETURN(var);
+}
+
+
+/*
+ called by register_var, construct_options and test_plugin_options.
+ Returns the 'bookmark' for the named variable.
+ LOCK_system_variables_hash should be at least read locked
+*/
+static st_bookmark *find_bookmark(const char *plugin, const char *name,
+ int flags)
+{
+ st_bookmark *result= NULL;
+ uint namelen, length, pluginlen= 0;
+ char *varname, *p;
+
+ if (!(flags & PLUGIN_VAR_THDLOCAL))
+ return NULL;
+
+ namelen= strlen(name);
+ if (plugin)
+ pluginlen= strlen(plugin) + 1;
+ length= namelen + pluginlen + 2;
+ varname= (char*) my_alloca(length);
+
+ if (plugin)
+ {
+ strxmov(varname + 1, plugin, "_", name, NullS);
+ for (p= varname + 1; *p; p++)
+ if (*p == '-')
+ *p= '_';
+ }
+ else
+ memcpy(varname + 1, name, namelen + 1);
+
+ varname[0]= flags & PLUGIN_VAR_TYPEMASK;
+
+ result= (st_bookmark*) hash_search(&bookmark_hash,
+ (const byte*) varname, length - 1);
+
+ my_afree(varname);
+ return result;
+}
+
+
+/*
+ returns a bookmark for thd-local variables, creating if neccessary.
+ returns null for non thd-local variables.
+ Requires that a write lock is obtained on LOCK_system_variables_hash
+*/
+static st_bookmark *register_var(const char *plugin, const char *name,
+ int flags)
+{
+ uint length= strlen(plugin) + strlen(name) + 3, size= 0, offset, new_size;
+ st_bookmark *result;
+ char *varname, *p;
+
+ if (!(flags & PLUGIN_VAR_THDLOCAL))
+ return NULL;
+
+ switch (flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_BOOL:
+ size= sizeof(my_bool);
+ break;
+ case PLUGIN_VAR_INT:
+ size= sizeof(int);
+ break;
+ case PLUGIN_VAR_LONG:
+ size= sizeof(long);
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ size= sizeof(ulonglong);
+ break;
+ case PLUGIN_VAR_STR:
+ size= sizeof(char*);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ return NULL;
+ };
+
+ varname= ((char*) my_alloca(length));
+ strxmov(varname + 1, plugin, "_", name, NullS);
+ for (p= varname + 1; *p; p++)
+ if (*p == '-')
+ *p= '_';
+
+ if (!(result= find_bookmark(NULL, varname + 1, flags)))
+ {
+ result= (st_bookmark*) alloc_root(&plugin_mem_root,
+ sizeof(struct st_bookmark) + length-1);
+ varname[0]= flags & PLUGIN_VAR_TYPEMASK;
+ memcpy(result->key, varname, length);
+ result->name_len= length - 2;
+ result->offset= -1;
+
+ DBUG_ASSERT(size && !(size & (size-1))); /* must be power of 2 */
+
+ offset= global_system_variables.dynamic_variables_size;
+ offset= (offset + size - 1) & ~(size - 1);
+ result->offset= (int) offset;
+
+ new_size= (offset + size + 63) & ~63;
+
+ if (new_size > global_variables_dynamic_size)
+ {
+ 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_variables_dynamic_size= new_size;
+ }
+
+ global_system_variables.dynamic_variables_head= offset;
+ max_system_variables.dynamic_variables_head= offset;
+ 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++;
+
+ result->version= global_system_variables.dynamic_variables_version;
+
+ /* this should succeed because we have already checked if a dup exists */
+ if (my_hash_insert(&bookmark_hash, (byte*) result))
+ {
+ fprintf(stderr, "failed to add placeholder to hash");
+ DBUG_ASSERT(0);
+ }
+ }
+ my_afree(varname);
+ return result;
+}
+
+
+/*
+ returns a pointer to the memory which holds the thd-local variable or
+ a pointer to the global variable if thd==null.
+ If required, will sync with global variables if the requested variable
+ has not yet been allocated in the current thread.
+*/
+static byte *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
+{
+ DBUG_ASSERT(offset >= 0);
+ DBUG_ASSERT((uint)offset <= global_system_variables.dynamic_variables_head);
+
+ if (!thd)
+ return (byte*) global_system_variables.dynamic_variables_ptr + offset;
+
+ /*
+ dynamic_variables_head points to the largest valid offset
+ */
+ if (!thd->variables.dynamic_variables_ptr ||
+ (uint)offset > thd->variables.dynamic_variables_head)
+ {
+ uint idx;
+
+ rw_rdlock(&LOCK_system_variables_hash);
+
+ thd->variables.dynamic_variables_ptr=
+ my_realloc(thd->variables.dynamic_variables_ptr,
+ global_variables_dynamic_size,
+ MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
+
+ if (global_lock)
+ pthread_mutex_lock(&LOCK_global_system_variables);
+
+ safe_mutex_assert_owner(&LOCK_global_system_variables);
+
+ 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 MEMALLOC flag, we need to strdup
+ */
+ for (idx= 0; idx < bookmark_hash.records; idx++)
+ {
+ sys_var_pluginvar *pi;
+ sys_var *var;
+ st_bookmark *v= (st_bookmark*) hash_element(&bookmark_hash,idx);
+
+ if (v->version <= thd->variables.dynamic_variables_version ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+ !(pi= var->cast_pluginvar()) ||
+ v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
+ continue;
+
+ /* Here we do anything special that may be required of the data types */
+
+ if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
+ pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
+ {
+ char **pp= (char**) (thd->variables.dynamic_variables_ptr +
+ *(int*)(pi->plugin_var + 1));
+ if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
+ *(int*)(pi->plugin_var + 1))))
+ *pp= my_strdup(*pp, MYF(MY_WME|MY_FAE));
+ }
+ }
+
+ if (global_lock)
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+
+ thd->variables.dynamic_variables_version=
+ global_system_variables.dynamic_variables_version;
+ thd->variables.dynamic_variables_head=
+ global_system_variables.dynamic_variables_head;
+ thd->variables.dynamic_variables_size=
+ global_system_variables.dynamic_variables_size;
+
+ rw_unlock(&LOCK_system_variables_hash);
+ }
+ return (byte*)thd->variables.dynamic_variables_ptr + offset;
+}
+
+static byte *mysql_sys_var_ptr(void* a_thd, int offset)
+{
+ return intern_sys_var_ptr((THD *)a_thd, offset, true);
+}
+
+
+void plugin_thdvar_init(THD *thd)
+{
+ /* we are going to allocate these lazily */
+ thd->variables.dynamic_variables_version= 0;
+ thd->variables.dynamic_variables_size= 0;
+ thd->variables.dynamic_variables_ptr= 0;
+
+ DBUG_ASSERT(!(thd->variables.table_plugin));
+ thd->variables.table_plugin=
+ my_plugin_lock(NULL, &global_system_variables.table_plugin);
+}
+
+
+/*
+ Unlocks all system variables which hold a reference
+*/
+static void unlock_variables(THD *thd, struct system_variables *vars)
+{
+ intern_plugin_unlock(NULL, vars->table_plugin);
+ vars->table_plugin= NULL;
+}
+
+
+/*
+ Frees memory used by system variables
+*/
+static void cleanup_variables(THD *thd, struct system_variables *vars)
+{
+ st_bookmark *v;
+ sys_var_pluginvar *pivar;
+ sys_var *var;
+ int flags;
+ uint idx;
+
+ rw_rdlock(&LOCK_system_variables_hash);
+ for (idx= 0; idx < bookmark_hash.records; idx++)
+ {
+ v= (st_bookmark*) hash_element(&bookmark_hash, idx);
+ if (v->version > vars->dynamic_variables_version ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+ !(pivar= var->cast_pluginvar()) ||
+ v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
+ continue;
+
+ flags= pivar->plugin_var->flags;
+
+ if ((flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
+ flags & PLUGIN_VAR_THDLOCAL && flags & PLUGIN_VAR_MEMALLOC)
+ {
+ char **ptr= (char**) pivar->real_value_ptr(thd, OPT_SESSION);
+ my_free(*ptr, MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
+ *ptr= NULL;
+ }
+ }
+ rw_unlock(&LOCK_system_variables_hash);
+
+ DBUG_ASSERT(vars->table_plugin == NULL);
+
+ my_free(vars->dynamic_variables_ptr, MYF(MY_ALLOW_ZERO_PTR));
+ vars->dynamic_variables_ptr= NULL;
+ vars->dynamic_variables_size= 0;
+ vars->dynamic_variables_version= 0;
+}
+
+
+void plugin_thdvar_cleanup(THD *thd)
+{
+ uint idx;
+ plugin_ref *list;
+ DBUG_ENTER("plugin_thdvar_cleanup");
+
+ pthread_mutex_lock(&LOCK_plugin);
+
+ unlock_variables(thd, &thd->variables);
+ cleanup_variables(thd, &thd->variables);
+
+ if ((idx= thd->main_lex.plugins.elements))
+ {
+ list= ((plugin_ref*) thd->main_lex.plugins.buffer) + idx - 1;
+ DBUG_PRINT("info",("unlocking %d plugins", idx));
+ while ((char*) list >= thd->main_lex.plugins.buffer)
+ intern_plugin_unlock(NULL, *list--);
+ }
+
+ reap_plugins();
+ pthread_mutex_unlock(&LOCK_plugin);
+
+ reset_dynamic(&thd->main_lex.plugins);
+
+ DBUG_VOID_RETURN;
+}
+
+
+bool sys_var_pluginvar::check_update_type(Item_result type)
+{
+ if (is_readonly())
+ return 1;
+ switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_INT:
+ case PLUGIN_VAR_LONG:
+ case PLUGIN_VAR_LONGLONG:
+ return type != INT_RESULT;
+ case PLUGIN_VAR_STR:
+ return type != STRING_RESULT;
+ default:
+ return 0;
+ }
+}
+
+
+SHOW_TYPE sys_var_pluginvar::show_type()
+{
+ switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_BOOL:
+ return SHOW_MY_BOOL;
+ case PLUGIN_VAR_INT:
+ return SHOW_INT;
+ case PLUGIN_VAR_LONG:
+ return SHOW_LONG;
+ case PLUGIN_VAR_LONGLONG:
+ return SHOW_LONGLONG;
+ case PLUGIN_VAR_STR:
+ return SHOW_CHAR_PTR;
+ case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_SET:
+ return SHOW_CHAR;
+ default:
+ DBUG_ASSERT(0);
+ return SHOW_UNDEF;
+ }
+}
+
+
+byte* sys_var_pluginvar::real_value_ptr(THD *thd, enum_var_type type)
+{
+ DBUG_ASSERT(thd);
+ if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
+ {
+ if (type == OPT_GLOBAL)
+ thd= NULL;
+
+ return intern_sys_var_ptr(thd, *(int*) (plugin_var+1), false);
+ }
+ return *(byte**) (plugin_var+1);
+}
+
+
+TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
+{
+ int type= plugin_var->flags & PLUGIN_VAR_TYPEMASK;
+ if (type == PLUGIN_VAR_ENUM || type == PLUGIN_VAR_SET)
+ {
+ if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
+ return ((thdvar_typelib_t *)plugin_var)->typelib;
+ else
+ return ((sysvar_typelib_t *)plugin_var)->typelib;
+ }
+ return NULL;
+}
+
+
+byte* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ byte* result;
+
+ result= real_value_ptr(thd, type);
+
+ if ((plugin_var->flags && PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
+ result= (byte*) get_type(plugin_var_typelib(), *(ulong*)result);
+ else
+ if ((plugin_var->flags && PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_SET)
+ {
+ char buffer[STRING_BUFFER_USUAL_SIZE];
+ String str(buffer, sizeof(buffer), system_charset_info);
+ TYPELIB *typelib= plugin_var_typelib();
+ ulong mask= 1, value= *(ulong*) result;
+ uint i;
+
+ str.length(0);
+ for (i= 0; i < typelib->count; i++, mask<<=1)
+ {
+ if (!(value & mask))
+ continue;
+ str.append(typelib->type_names[i], typelib->type_lengths[i]);
+ str.append(',');
+ }
+
+ result= (byte*) "";
+ if (str.length())
+ result= (byte*) thd->strmake(str.ptr(), str.length()-1);
+ }
+ return result;
+}
+
+
+bool sys_var_pluginvar::check(THD *thd, set_var *var)
+{
+ st_item_value_holder value;
+ DBUG_ASSERT(is_readonly() || plugin_var->check);
+
+ value.value_type= item_value_type;
+ value.val_str= item_val_str;
+ value.val_int= item_val_int;
+ value.val_real= item_val_real;
+ value.item= var->value;
+
+ return is_readonly() ||
+ plugin_var->check(thd, plugin_var, &var->save_result, &value);
+}
+
+
+void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
+{
+ void *tgt, *src;
+
+ DBUG_ASSERT(is_readonly() || plugin_var->update);
+
+ if (is_readonly())
+ return;
+
+ tgt= real_value_ptr(thd, type);
+ src= ((void **) (plugin_var + 1) + 1);
+
+ if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
+ {
+ src= ((int*) (plugin_var + 1) + 1);
+ if (type != OPT_GLOBAL)
+ src= real_value_ptr(thd, OPT_GLOBAL);
+ }
+
+ /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
+ DBUG_ASSERT(!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) ||
+ thd == current_thd);
+
+ if (!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) || type == OPT_GLOBAL)
+ {
+ pthread_mutex_lock(&LOCK_plugin);
+ plugin_var->update(thd, plugin_var, tgt, src);
+ pthread_mutex_unlock(&LOCK_plugin);
+ }
+ else
+ plugin_var->update(thd, plugin_var, tgt, src);
+}
+
+
+bool sys_var_pluginvar::update(THD *thd, set_var *var)
+{
+ void *tgt;
+
+ DBUG_ASSERT(is_readonly() || plugin_var->update);
+
+ /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
+ DBUG_ASSERT(!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) ||
+ thd == current_thd);
+
+ if (is_readonly())
+ return 1;
+
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ tgt= real_value_ptr(thd, var->type);
+
+ if (!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) || var->type == OPT_GLOBAL)
+ {
+ /* variable we are updating has global scope, so we unlock after updating */
+ plugin_var->update(thd, plugin_var, tgt, &var->save_result);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ }
+ else
+ {
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ plugin_var->update(thd, plugin_var, tgt, &var->save_result);
+ }
+ return 0;
+}
+
+
+#define OPTION_SET_LIMITS(type, options, opt) \
+ options->var_type= type; \
+ options->def_value= (opt)->def_val; \
+ options->min_value= (opt)->min_val; \
+ options->max_value= (opt)->max_val; \
+ options->block_size= (opt)->blk_sz
+
+
+static void plugin_opt_set_limits(struct my_option *options,
+ const struct st_mysql_sys_var *opt)
+{
+ switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
+ PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL)) {
+ /* global system variables */
+ case PLUGIN_VAR_INT:
+ OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
+ break;
+ case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
+ OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
+ break;
+ case PLUGIN_VAR_LONG:
+ OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
+ break;
+ case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
+ OPTION_SET_LIMITS(GET_ULONG, options, (sysvar_ulong_t*) opt);
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ OPTION_SET_LIMITS(GET_LL, options, (sysvar_longlong_t*) opt);
+ break;
+ case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
+ OPTION_SET_LIMITS(GET_ULL, options, (sysvar_ulonglong_t*) opt);
+ break;
+ case PLUGIN_VAR_ENUM:
+ options->var_type= GET_ENUM;
+ options->typelib= ((sysvar_typelib_t*) opt)->typelib;
+ options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+ options->min_value= options->block_size= 0;
+ options->max_value= options->typelib->count - 1;
+ break;
+ case PLUGIN_VAR_SET:
+ options->var_type= GET_SET;
+ options->typelib= ((sysvar_typelib_t*) opt)->typelib;
+ options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+ options->min_value= options->block_size= 0;
+ options->max_value= (ULL(1) << options->typelib->count) - 1;
+ break;
+ case PLUGIN_VAR_BOOL:
+ options->var_type= GET_BOOL;
+ options->def_value= *(my_bool*) ((void**)(opt + 1) + 1);
+ break;
+ case PLUGIN_VAR_STR:
+ options->var_type= GET_STR;
+ break;
+ /* threadlocal variables */
+ case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_INT, options, (thdvar_int_t*) opt);
+ break;
+ case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_UINT, options, (thdvar_uint_t*) opt);
+ break;
+ case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_LONG, options, (thdvar_long_t*) opt);
+ break;
+ case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_ULONG, options, (thdvar_ulong_t*) opt);
+ break;
+ case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_LL, options, (thdvar_longlong_t*) opt);
+ break;
+ case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt);
+ break;
+ case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
+ options->var_type= GET_ENUM;
+ options->typelib= ((thdvar_typelib_t*) opt)->typelib;
+ options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+ options->min_value= options->block_size= 0;
+ options->max_value= options->typelib->count - 1;
+ break;
+ case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL:
+ options->var_type= GET_SET;
+ options->typelib= ((thdvar_typelib_t*) opt)->typelib;
+ options->def_value= *(ulong*) ((int*) (opt + 1) + 1);
+ options->min_value= options->block_size= 0;
+ options->max_value= (ULL(1) << options->typelib->count) - 1;
+ break;
+ case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
+ options->var_type= GET_BOOL;
+ options->def_value= *(my_bool*) ((int*) (opt + 1) + 1);
+ break;
+ case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
+ options->var_type= GET_STR;
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ options->arg_type= REQUIRED_ARG;
+ if (opt->flags & PLUGIN_VAR_NOCMDARG)
+ options->arg_type= NO_ARG;
+ if (opt->flags & PLUGIN_VAR_OPCMDARG)
+ options->arg_type= OPT_ARG;
+}
+
+
+static my_bool get_one_option(int optid __attribute__((unused)),
+ const struct my_option *opt,
+ char *argument)
+{
+ return 0;
+}
+
+
+static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
+ my_option *options, my_bool **enabled,
+ bool can_disable)
+{
+ const char *plugin_name= tmp->plugin->name;
+ uint namelen= strlen(plugin_name), optnamelen;
+ uint buffer_length= namelen * 4 + (can_disable ? 75 : 10);
+ char *name= (char*) alloc_root(mem_root, buffer_length) + 1;
+ char *optname, *p;
+ int index= 0, offset= 0;
+ st_mysql_sys_var *opt, **plugin_option;
+ st_bookmark *v;
+ 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 (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-", 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; /* must be >255. dup id ok */
+ 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;
+
+ /*
+ Two passes as the 2nd pass will take pointer addresses for use
+ by my_getopt and register_var() in the first pass uses realloc
+ */
+
+ for (plugin_option= tmp->plugin->system_vars;
+ plugin_option && *plugin_option; plugin_option++, index++)
+ {
+ opt= *plugin_option;
+ if (!(opt->flags & PLUGIN_VAR_THDLOCAL))
+ continue;
+ if (!(register_var(name, opt->name, opt->flags)))
+ continue;
+ switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_BOOL:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_bool_t *) opt);
+ break;
+ case PLUGIN_VAR_INT:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_int_t *) opt);
+ break;
+ case PLUGIN_VAR_LONG:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_long_t *) opt);
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_longlong_t *) opt);
+ break;
+ case PLUGIN_VAR_STR:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_str_t *) opt);
+ break;
+ case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_SET:
+ SET_PLUGIN_VAR_RESOLVE((thdvar_typelib_t *) opt);
+ break;
+ default:
+ sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
+ opt->flags, tmp->plugin->name);
+ DBUG_RETURN(-1);
+ };
+ }
+
+ for (plugin_option= tmp->plugin->system_vars;
+ plugin_option && *plugin_option; plugin_option++, index++)
+ {
+ switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
+ case PLUGIN_VAR_BOOL:
+ if (!opt->check)
+ opt->check= check_func_bool;
+ if (!opt->update)
+ opt->update= update_func_bool;
+ break;
+ case PLUGIN_VAR_INT:
+ if (!opt->check)
+ opt->check= check_func_int;
+ if (!opt->update)
+ opt->update= update_func_int;
+ break;
+ case PLUGIN_VAR_LONG:
+ if (!opt->check)
+ opt->check= check_func_long;
+ if (!opt->update)
+ opt->update= update_func_long;
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ if (!opt->check)
+ opt->check= check_func_longlong;
+ if (!opt->update)
+ opt->update= update_func_longlong;
+ break;
+ case PLUGIN_VAR_STR:
+ if (!opt->check)
+ opt->check= check_func_str;
+ if (!opt->update)
+ {
+ opt->update= update_func_str;
+ if (!(opt->flags & PLUGIN_VAR_MEMALLOC))
+ opt->flags |= PLUGIN_VAR_READONLY;
+ }
+ break;
+ case PLUGIN_VAR_ENUM:
+ if (!opt->check)
+ opt->check= check_func_enum;
+ if (!opt->update)
+ opt->update= update_func_long;
+ break;
+ case PLUGIN_VAR_SET:
+ if (!opt->check)
+ opt->check= check_func_set;
+ if (!opt->update)
+ opt->update= update_func_long;
+ break;
+ default:
+ sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
+ opt->flags, tmp->plugin->name);
+ DBUG_RETURN(-1);
+ }
+
+ if (opt->flags & PLUGIN_VAR_NOCMDOPT)
+ continue;
+
+ if (!opt->name)
+ {
+ sql_print_error("Missing variable name in plugin '%s'.",
+ tmp->plugin->name);
+ DBUG_RETURN(-1);
+ }
+
+ if (!(v= find_bookmark(name, opt->name, opt->flags)))
+ {
+ optnamelen= strlen(opt->name);
+ optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
+ strxmov(optname, name, "-", opt->name, NullS);
+ optnamelen= namelen + optnamelen + 1;
+ }
+ else
+ optname= memdup_root(mem_root, v->key + 1, (optnamelen= v->name_len) + 1);
+
+ /* convert '_' to '-' */
+ for (p= optname; *p; p++)
+ if (*p == '_')
+ *p= '-';
+
+ options->name= optname;
+ options->comment= opt->comment;
+ options->app_type= opt;
+ options->id= (options-1)->id + 1;
+
+ if (opt->flags & PLUGIN_VAR_THDLOCAL)
+ *(int*)(opt + 1)= offset= v->offset;
+
+ plugin_opt_set_limits(options, opt);
+
+ if ((opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_ENUM &&
+ (opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_SET)
+ {
+ if (opt->flags & PLUGIN_VAR_THDLOCAL)
+ options->value= options->u_max_value= (gptr*)
+ (global_system_variables.dynamic_variables_ptr + offset);
+ else
+ options->value= options->u_max_value= *(gptr**) (opt + 1);
+ }
+
+ options[1]= options[0];
+ options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
+ options[1].comment= 0; // hidden
+ strxmov(p, "plugin-", optname, NullS);
+
+ options+= 2;
+ }
+
+ DBUG_RETURN(0);
+}
+
+
+static my_option *construct_help_options(MEM_ROOT *mem_root,
+ struct st_plugin_int *p)
+{
+ st_mysql_sys_var **opt;
+ my_option *opts;
+ my_bool dummy, can_disable;
+ my_bool *dummy2= &dummy;
+ uint count= EXTRA_OPTIONS;
+ DBUG_ENTER("construct_help_options");
+
+ for (opt= p->plugin->system_vars; opt && *opt; opt++, count+= 2);
+
+ if (!(opts= (my_option*) alloc_root(mem_root, sizeof(my_option) * count)))
+ DBUG_RETURN(NULL);
+
+ bzero(opts, sizeof(my_option) * count);
+
+ can_disable=
+ my_strcasecmp(&my_charset_latin1, p->name.str, "MyISAM") &&
+ my_strcasecmp(&my_charset_latin1, p->name.str, "MEMORY");
+
+ if (construct_options(mem_root, p, opts, &dummy2, can_disable))
+ DBUG_RETURN(NULL);
+
+ DBUG_RETURN(opts);
+}
+
+
+/*
+ SYNOPSIS
+ test_plugin_options()
+ tmp_root temporary scratch space
+ plugin internal plugin structure
+ argc user supplied arguments
+ argv user supplied arguments
+ default_enabled default plugin enable status
+ RETURNS:
+ 0 SUCCESS - plugin should be enabled/loaded
+ NOTE:
+ Requires that a write-lock is held on LOCK_system_variables_hash
+*/
+static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
+ int *argc, char **argv, my_bool default_enabled)
+{
+ struct sys_var_chain chain= { NULL, NULL };
+ 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;
+ st_mysql_sys_var **opt;
+ my_option *opts;
+ char *p, *varname;
+ int error;
+ st_mysql_sys_var *o;
+ sys_var *v;
+ struct st_bookmark *var;
+ uint len, count= EXTRA_OPTIONS;
+ DBUG_ENTER("test_plugin_options");
+ DBUG_ASSERT(tmp->plugin && tmp->name.str);
+
+ for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
+ count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
+
+ can_disable=
+ my_strcasecmp(&my_charset_latin1, tmp->name.str, "MyISAM") &&
+ my_strcasecmp(&my_charset_latin1, tmp->name.str, "MEMORY");
+
+ if (count > EXTRA_OPTIONS || (*argc > 1))
+ {
+ if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
+ {
+ sql_print_error("Out of memory for plugin '%s'.", tmp->name.str);
+ DBUG_RETURN(-1);
+ }
+ bzero(opts, sizeof(my_option) * count);
+
+ if (construct_options(tmp_root, tmp, opts, &enabled, can_disable))
+ {
+ sql_print_error("Bad options for plugin '%s'.", tmp->name.str);
+ DBUG_RETURN(-1);
+ }
+
+ error= handle_options(argc, &argv, opts, get_one_option);
+ (*argc)++; /* add back one for the program name */
+
+ if (error)
+ {
+ sql_print_error("Parsing options for plugin '%s' failed.",
+ tmp->name.str);
+ DBUG_RETURN(error);
+ }
+ }
+
+ if (!*enabled && !can_disable)
+ {
+ sql_print_warning("Plugin '%s' cannot be disabled", tmp->name.str);
+ *enabled= TRUE;
+ }
+
+ if (*enabled)
+ {
+ for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
+ {
+ if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
+ continue;
+
+ if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
+ v= new (mem_root) sys_var_pluginvar(var->key + 1, o);
+ else
+ {
+ len= tmp->name.length + strlen(o->name) + 2;
+ varname= (char*) alloc_root(mem_root, len);
+ strxmov(varname, tmp->name.str, "-", o->name, NullS);
+ my_casedn_str(&my_charset_latin1, varname);
+
+ for (p= varname; *p; p++)
+ if (*p == '-')
+ *p= '_';
+
+ v= new (mem_root) sys_var_pluginvar(varname, o);
+ }
+ DBUG_ASSERT(v); /* check that an object was actually constructed */
+
+ /*
+ Add to the chain of variables.
+ Done like this for easier debugging so that the
+ pointer to v is not lost on optimized builds.
+ */
+ v->chain_sys_var(&chain);
+ }
+ if (chain.first)
+ {
+ chain.last->next = NULL;
+ if (mysql_add_sys_var_chain(chain.first, NULL))
+ {
+ sql_print_error("Plugin '%s' has conflicting system variables",
+ tmp->name.str);
+ 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->name.str);
+ DBUG_RETURN(1);
+}
+
+
+/****************************************************************************
+ Help Verbose text with Plugin System Variables
+****************************************************************************/
+
+static int option_cmp(my_option *a, my_option *b)
+{
+ return my_strcasecmp(&my_charset_latin1, a->name, b->name);
+}
+
+
+void my_print_help_inc_plugins(my_option *main_options, uint size)
+{
+ DYNAMIC_ARRAY all_options;
+ struct st_plugin_int *p;
+ MEM_ROOT mem_root;
+ my_option *opt;
+
+ init_alloc_root(&mem_root, 4096, 4096);
+ my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
+
+ if (initialized)
+ for (uint idx= 0; idx < plugin_array.elements; idx++)
+ {
+ p= dynamic_element(&plugin_array, idx, struct st_plugin_int *);
+
+ if (!p->plugin->system_vars ||
+ !(opt= construct_help_options(&mem_root, p)))
+ continue;
+
+ /* Only options with a non-NULL comment are displayed in help text */
+ 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);
+
+ /* main_options now points to the empty option terminator */
+ 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);
+ free_root(&mem_root, MYF(0));
+}
+
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index d86d9332a92..70ce21a64da 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -16,6 +16,17 @@
#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_PLUGIN_TABLE 2
+#define PLUGIN_INIT_SKIP_INITIALIZATION 4
+
+#define INITIAL_LEX_PLUGIN_LIST_SIZE 16
+
/*
the following #define adds server-only members to enum_mysql_show_type,
that is defined in plugin.h
@@ -41,6 +52,7 @@ typedef struct st_mysql_show_var SHOW_VAR;
#define PLUGIN_IS_DELETED 2
#define PLUGIN_IS_UNINITIALIZED 4
#define PLUGIN_IS_READY 8
+#define PLUGIN_IS_DYING 16
/* A handle for the dynamic library containing a plugin or plugins. */
@@ -63,25 +75,64 @@ struct st_plugin_int
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 plugin structures */
+ sys_var *system_vars; /* server variables for this plugin */
};
+
+/*
+ See intern_plugin_lock() for the explanation for the
+ conditionally defined plugin_ref type
+*/
+#ifdef DBUG_OFF
+typedef struct st_plugin_int *plugin_ref;
+#define plugin_decl(pi) ((pi)->plugin)
+#define plugin_dlib(pi) ((pi)->plugin_dl)
+#define plugin_data(pi,cast) ((cast)((pi)->data))
+#define plugin_name(pi) (&((pi)->name))
+#define plugin_state(pi) ((pi)->state)
+#define plugin_equals(p1,p2) ((p1) == (p2))
+#else
+typedef struct st_plugin_int **plugin_ref;
+#define plugin_decl(pi) ((pi)[0]->plugin)
+#define plugin_dlib(pi) ((pi)[0]->plugin_dl)
+#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
+#define plugin_name(pi) (&((pi)[0]->name))
+#define plugin_state(pi) ((pi)[0]->state)
+#define plugin_equals(p1,p2) ((p1) && (p2) && (p1)[0] == (p2)[0])
+#endif
+
typedef int (*plugin_type_init)(struct st_plugin_int *);
+extern char *opt_plugin_load;
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);
+
+extern int plugin_init(int *argc, char **argv, int init_flags);
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);
-extern void plugin_unlock(struct st_plugin_int *plugin);
-extern my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl);
-extern my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
+extern void my_print_help_inc_plugins(struct my_option *options, uint size);
+extern bool plugin_is_ready(const LEX_STRING *name, int type);
+#define my_plugin_lock_by_name(A,B,C) plugin_lock_by_name(A,B,C CALLER_INFO)
+#define my_plugin_lock_by_name_ci(A,B,C) plugin_lock_by_name(A,B,C ORIG_CALLER_INFO)
+#define my_plugin_lock(A,B) plugin_lock(A,B CALLER_INFO)
+#define my_plugin_lock_ci(A,B) plugin_lock(A,B ORIG_CALLER_INFO)
+extern plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO);
+extern plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name,
+ int type CALLER_INFO_PROTO);
+extern void plugin_unlock(THD *thd, plugin_ref plugin);
+extern void plugin_unlock_list(THD *thd, plugin_ref *list, uint count);
+extern bool mysql_install_plugin(THD *thd, const LEX_STRING *name,
+ const LEX_STRING *dl);
+extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
+extern bool plugin_register_builtin(struct st_mysql_plugin *plugin);
+extern void plugin_thdvar_init(THD *thd);
+extern void plugin_thdvar_cleanup(THD *thd);
typedef my_bool (plugin_foreach_func)(THD *thd,
- st_plugin_int *plugin,
+ plugin_ref plugin,
void *arg);
#define plugin_foreach(A,B,C,D) plugin_foreach_with_mask(A,B,C,PLUGIN_IS_READY,D)
-extern my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
- int type, uint state_mask, void *arg);
+extern bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
+ int type, uint state_mask, void *arg);
#endif
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 66dc1c97d56..9e7f45841d7 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1606,6 +1606,149 @@ int log_loaded_block(IO_CACHE* file)
return 0;
}
+/*
+ Replication System Variables
+*/
+
+class sys_var_slave_skip_counter :public sys_var
+{
+public:
+ sys_var_slave_skip_counter(sys_var_chain *chain, const char *name_arg)
+ :sys_var(name_arg)
+ { chain_sys_var(chain); }
+ 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; }
+ /*
+ We can't retrieve the value of this, so we don't have to define
+ type() or value_ptr()
+ */
+};
+
+class sys_var_sync_binlog_period :public sys_var_long_ptr
+{
+public:
+ 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);
+};
+
+static sys_var_chain vars = { NULL, NULL };
+
+static sys_var_bool_ptr sys_relay_log_purge(&vars, "relay_log_purge",
+ &relay_log_purge);
+static sys_var_long_ptr sys_slave_net_timeout(&vars, "slave_net_timeout",
+ &slave_net_timeout);
+static sys_var_long_ptr sys_slave_trans_retries(&vars, "slave_transaction_retries",
+ &slave_trans_retries);
+static sys_var_sync_binlog_period sys_sync_binlog_period(&vars, "sync_binlog", &sync_binlog_period);
+static sys_var_slave_skip_counter sys_slave_skip_counter(&vars, "sql_slave_skip_counter");
+
+static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff);
+
+
+static SHOW_VAR fixed_vars[]= {
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
+ {"relay_log_space_limit", (char*) &relay_log_space_limit, SHOW_LONGLONG},
+ {"slave_load_tmpdir", (char*) &slave_load_tmpdir, SHOW_CHAR_PTR},
+ {"slave_skip_errors", (char*) &show_slave_skip_errors, SHOW_FUNC},
+};
+
+static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type=SHOW_CHAR;
+ var->value= buff;
+ if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
+ {
+ var->value= const_cast<char *>("OFF");
+ }
+ else if (bitmap_is_set_all(&slave_error_mask))
+ {
+ var->value= const_cast<char *>("ALL");
+ }
+ else
+ {
+ /* 10 is enough assuming errors are max 4 digits */
+ int i;
+ var->value= buff;
+ for (i= 1;
+ i < MAX_SLAVE_ERROR &&
+ (buff - var->value) < SHOW_VAR_FUNC_BUFF_SIZE;
+ i++)
+ {
+ if (bitmap_is_set(&slave_error_mask, i))
+ {
+ buff= int10_to_str(i, buff, 10);
+ *buff++= ',';
+ }
+ }
+ if (var->value != buff)
+ buff--; // Remove last ','
+ if (i < MAX_SLAVE_ERROR)
+ buff= strmov(buff, "..."); // Couldn't show all errors
+ *buff=0;
+ }
+ return 0;
+}
+
+bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
+{
+ int result= 0;
+ pthread_mutex_lock(&LOCK_active_mi);
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ if (active_mi->rli.slave_running)
+ {
+ my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
+ result=1;
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ pthread_mutex_unlock(&LOCK_active_mi);
+ var->save_result.ulong_value= (ulong) var->value->val_int();
+ return result;
+}
+
+
+bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
+{
+ pthread_mutex_lock(&LOCK_active_mi);
+ pthread_mutex_lock(&active_mi->rli.run_lock);
+ /*
+ The following test should normally never be true as we test this
+ in the check function; To be safe against multiple
+ SQL_SLAVE_SKIP_COUNTER request, we do the check anyway
+ */
+ if (!active_mi->rli.slave_running)
+ {
+ pthread_mutex_lock(&active_mi->rli.data_lock);
+ active_mi->rli.slave_skip_counter= var->save_result.ulong_value;
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ pthread_mutex_unlock(&LOCK_active_mi);
+ return 0;
+}
+
+
+bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
+{
+ sync_binlog_period= (ulong) var->save_result.ulonglong_value;
+ return 0;
+}
+
+int init_replication_sys_vars()
+{
+ mysql_append_static_vars(fixed_vars, sizeof(fixed_vars) / sizeof(SHOW_VAR));
+
+ if (mysql_add_sys_var_chain(vars.first, my_long_options))
+ {
+ /* should not happen */
+ fprintf(stderr, "failed to initialize replication system variables");
+ unireg_abort(1);
+ }
+ return 0;
+}
+
#endif /* HAVE_REPLICATION */
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index b106391245d..da50d47c60d 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -67,6 +67,7 @@ typedef struct st_load_file_info
} LOAD_FILE_INFO;
int log_loaded_block(IO_CACHE* file);
+int init_replication_sys_vars();
#endif /* HAVE_REPLICATION */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index eb6f4efccc3..c322974eec5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9577,12 +9577,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
share->fields= field_count;
/* If result table is small; use a heap */
+ /* future: storage engine selection can be made dynamic? */
if (blob_count || using_unique_constraint ||
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
{
+ share->db_plugin= ha_lock_engine(0, myisam_hton);
table->file= get_new_handler(share, &table->mem_root,
- share->db_type= myisam_hton);
+ share->db_type());
if (group &&
(param->group_parts > table->file->max_key_parts() ||
param->group_length > table->file->max_key_length()))
@@ -9590,8 +9592,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
else
{
+ share->db_plugin= ha_lock_engine(0, heap_hton);
table->file= get_new_handler(share, &table->mem_root,
- share->db_type= heap_hton);
+ share->db_type());
}
if (!table->file)
goto err;
@@ -9753,7 +9756,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
share->max_rows= ~(ha_rows) 0;
else
- share->max_rows= (ha_rows) (((share->db_type == heap_hton) ?
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
min(thd->variables.tmp_table_size,
thd->variables.max_heap_table_size) :
thd->variables.tmp_table_size) /
@@ -9901,7 +9904,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
- if (share->db_type == myisam_hton)
+ if (share->db_type() == myisam_hton)
{
if (create_myisam_tmp_table(table,param,select_options))
goto err;
@@ -10208,6 +10211,8 @@ free_tmp_table(THD *thd, TABLE *entry)
if (entry->temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
+ plugin_unlock(0, entry->s->db_plugin);
+
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd->proc_info=save_proc_info;
@@ -10227,7 +10232,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int write_err;
DBUG_ENTER("create_myisam_from_heap");
- if (table->s->db_type != heap_hton ||
+ if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
{
table->file->print_error(error,MYF(0));
@@ -10236,9 +10241,9 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table= *table;
share= *table->s;
new_table.s= &share;
- new_table.s->db_type= myisam_hton;
+ new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
- myisam_hton)))
+ new_table.s->db_type())))
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
@@ -10296,9 +10301,12 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
(void) table->file->delete_table(table->s->table_name.str);
delete table->file;
table->file=0;
+ plugin_unlock(0, table->s->db_plugin);
+ share.db_plugin= my_plugin_lock(0, &share.db_plugin);
new_table.s= table->s; // Keep old share
*table= new_table;
*table->s= share;
+
table->file->change_table_ptr(table, table->s);
table->use_all_columns();
if (save_proc_info)
@@ -12886,7 +12894,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
free_io_cache(entry); // Safety
entry->file->info(HA_STATUS_VARIABLE);
- if (entry->s->db_type == heap_hton ||
+ if (entry->s->db_type() == heap_hton ||
(!entry->s->blob_fields &&
((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
thd->variables.sortbuff_size)))
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 0d620d33dbb..e229542c454 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -79,24 +79,24 @@ append_algorithm(TABLE_LIST *table, String *buff);
** List all table types supported
***************************************************************************/
-static my_bool show_handlerton(THD *thd, st_plugin_int *plugin,
+static my_bool show_handlerton(THD *thd, plugin_ref plugin,
void *arg)
{
handlerton *default_type= (handlerton *) arg;
Protocol *protocol= thd->protocol;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if (!(hton->flags & HTON_HIDDEN))
{
protocol->prepare_for_resend();
- protocol->store(plugin->name.str, plugin->name.length,
+ protocol->store(plugin_name(plugin)->str, plugin_name(plugin)->length,
system_charset_info);
const char *option_name= show_comp_option_name[(int) hton->state];
if (hton->state == SHOW_OPTION_YES && default_type == hton)
option_name= "DEFAULT";
protocol->store(option_name, system_charset_info);
- protocol->store(plugin->plugin->descr, system_charset_info);
+ protocol->store(plugin_decl(plugin)->descr, system_charset_info);
protocol->store(hton->commit ? "YES" : "NO", system_charset_info);
protocol->store(hton->prepare ? "YES" : "NO", system_charset_info);
protocol->store(hton->savepoint_set ? "YES" : "NO", system_charset_info);
@@ -124,7 +124,7 @@ bool mysqld_show_storage_engines(THD *thd)
DBUG_RETURN(TRUE);
if (plugin_foreach(thd, show_handlerton,
- MYSQL_STORAGE_ENGINE_PLUGIN, thd->variables.table_type))
+ MYSQL_STORAGE_ENGINE_PLUGIN, ha_default_handlerton(thd)))
DBUG_RETURN(TRUE);
send_eof(thd);
@@ -136,24 +136,26 @@ static int make_version_string(char *buf, int buf_length, uint version)
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
}
-static my_bool show_plugins(THD *thd, st_plugin_int *plugin,
+static my_bool show_plugins(THD *thd, plugin_ref plugin,
void *arg)
{
TABLE *table= (TABLE*) arg;
- struct st_mysql_plugin *plug= plugin->plugin;
+ struct st_mysql_plugin *plug= plugin_decl(plugin);
+ struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
CHARSET_INFO *cs= system_charset_info;
char version_buf[20];
restore_record(table, s->default_values);
- table->field[0]->store(plugin->name.str, plugin->name.length, cs);
+ table->field[0]->store(plugin_name(plugin)->str,
+ plugin_name(plugin)->length, cs);
table->field[1]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf), plug->version),
cs);
- switch (plugin->state) {
+ switch (plugin_state(plugin)) {
/* case PLUGIN_IS_FREED: does not happen */
case PLUGIN_IS_DELETED:
table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
@@ -175,14 +177,13 @@ static my_bool show_plugins(THD *thd, st_plugin_int *plugin,
make_version_string(version_buf, sizeof(version_buf),
*(uint *)plug->info), cs);
- if (plugin->plugin_dl)
+ if (plugin_dl)
{
- table->field[5]->store(plugin->plugin_dl->dl.str,
- plugin->plugin_dl->dl.length, cs);
+ table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
table->field[5]->set_notnull();
table->field[6]->store(version_buf,
make_version_string(version_buf, sizeof(version_buf),
- plugin->plugin_dl->version),
+ plugin_dl->version),
cs);
table->field[6]->set_notnull();
}
@@ -1239,9 +1240,9 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
store_key_options(thd, packet, table, key_info);
if (key_info->parser)
{
+ LEX_STRING *parser_name= plugin_name(key_info->parser);
packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER "));
- append_identifier(thd, packet, key_info->parser->name.str,
- key_info->parser->name.length);
+ append_identifier(thd, packet, parser_name->str, parser_name->length);
packet->append(STRING_WITH_LEN(" */ "));
}
}
@@ -1936,6 +1937,18 @@ void init_status_vars()
sort_dynamic(&all_status_vars, show_var_cmp);
}
+void reset_status_vars()
+{
+ SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
+ SHOW_VAR *last= ptr + all_status_vars.elements;
+ for (; ptr < last; ptr++)
+ {
+ /* Note that SHOW_LONG_NOFLUSH variables are not reset */
+ if (ptr->type == SHOW_LONG)
+ *(ulong*) ptr->value= 0;
+ }
+}
+
/*
catch-all cleanup function, cleans up everything no matter what
@@ -2066,6 +2079,8 @@ static bool show_status_array(THD *thd, const char *wild,
char *value=var->value;
const char *pos, *end; // We assign a lot of const's
+ pthread_mutex_lock(&LOCK_global_system_variables);
+
if (show_type == SHOW_SYS)
{
show_type= ((sys_var*) value)->show_type();
@@ -2148,6 +2163,9 @@ static bool show_status_array(THD *thd, const char *wild,
system_charset_info);
table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
table->field[1]->set_notnull();
+
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+
if (schema_table_store_record(thd, table))
DBUG_RETURN(TRUE);
}
@@ -2457,13 +2475,13 @@ struct st_add_schema_table
const char *wild;
};
-static my_bool add_schema_table(THD *thd, st_plugin_int *plugin,
+static my_bool add_schema_table(THD *thd, plugin_ref plugin,
void* p_data)
{
st_add_schema_table *data= (st_add_schema_table *)p_data;
List<char> *file_list= data->files;
const char *wild= data->wild;
- ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
+ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
DBUG_ENTER("add_schema_table");
if (schema_table->hidden)
@@ -2997,7 +3015,7 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
ha_row_type[(uint) share->row_type],
NullS);
#ifdef WITH_PARTITION_STORAGE_ENGINE
- if (show_table->s->db_type == partition_hton &&
+ if (show_table->s->db_type() == partition_hton &&
show_table->part_info != NULL &&
show_table->part_info->no_parts > 0)
ptr= strmov(ptr, " partitioned");
@@ -3272,19 +3290,20 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
}
-static my_bool iter_schema_engines(THD *thd, st_plugin_int *plugin,
+static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
void *ptable)
{
TABLE *table= (TABLE *) ptable;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
CHARSET_INFO *scs= system_charset_info;
DBUG_ENTER("iter_schema_engines");
if (!(hton->flags & HTON_HIDDEN))
{
+ LEX_STRING *name= plugin_name(plugin);
if (!(wild && wild[0] &&
- wild_case_compare(scs, plugin->name.str,wild)))
+ wild_case_compare(scs, name->str,wild)))
{
LEX_STRING state[2]= {{ C_STRING_WITH_LEN("ENABLED") },
{ C_STRING_WITH_LEN("DISABLED") }};
@@ -3293,11 +3312,11 @@ static my_bool iter_schema_engines(THD *thd, st_plugin_int *plugin,
LEX_STRING *tmp;
restore_record(table, s->default_values);
- table->field[0]->store(plugin->name.str, plugin->name.length, scs);
+ table->field[0]->store(name->str, name->length, scs);
tmp= &state[test(hton->state)];
table->field[1]->store(tmp->str, tmp->length, scs);
- table->field[2]->store(plugin->plugin->descr,
- strlen(plugin->plugin->descr), scs);
+ table->field[2]->store(plugin_decl(plugin)->descr,
+ strlen(plugin_decl(plugin)->descr), scs);
tmp= &yesno[test(hton->commit)];
table->field[3]->store(tmp->str, tmp->length, scs);
tmp= &yesno[test(hton->prepare)];
@@ -4483,10 +4502,10 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
int res= 0;
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,
+ rw_rdlock(&LOCK_system_variables_hash);
+ res= show_status_array(thd, wild, enumerate_sys_vars(thd, TRUE),
lex->option_type, 0, "", tables->table, 0);
- pthread_mutex_unlock(&LOCK_global_system_variables);
+ rw_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
}
@@ -4602,12 +4621,12 @@ struct schema_table_ref
0 table not found
1 found the schema table
*/
-static my_bool find_schema_table_in_plugin(THD *thd, st_plugin_int *plugin,
+static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
void* p_table)
{
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
const char* table_name= p_schema_table->table_name;
- ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
+ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
DBUG_ENTER("find_schema_table_in_plugin");
if (!my_strcasecmp(system_charset_info,
@@ -5150,12 +5169,12 @@ struct run_hton_fill_schema_files_args
COND *cond;
};
-static my_bool run_hton_fill_schema_files(THD *thd, st_plugin_int *plugin,
+static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin,
void *arg)
{
struct run_hton_fill_schema_files_args *args=
(run_hton_fill_schema_files_args *) arg;
- handlerton *hton= (handlerton *)plugin->data;
+ handlerton *hton= plugin_data(plugin, handlerton *);
if(hton->fill_files_table && hton->state == SHOW_OPTION_YES)
hton->fill_files_table(hton, thd, args->tables, args->cond);
return false;
@@ -5321,10 +5340,10 @@ int fill_schema_global_variables(THD *thd, TABLE_LIST *tables, COND *cond)
int res= 0;
DBUG_ENTER("fill_schema_global_variables");
- pthread_mutex_lock(&LOCK_global_system_variables);
- res= show_status_array(thd, "", init_vars, OPT_GLOBAL,
+ rw_rdlock(&LOCK_system_variables_hash);
+ res= show_status_array(thd, "", enumerate_sys_vars(thd, FALSE), OPT_GLOBAL,
NULL, "", tables->table, 1);
- pthread_mutex_unlock(&LOCK_global_system_variables);
+ rw_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
}
@@ -5334,10 +5353,10 @@ int fill_schema_session_variables(THD *thd, TABLE_LIST *tables, COND *cond)
int res= 0;
DBUG_ENTER("fill_schema_session_variables");
- pthread_mutex_lock(&LOCK_global_system_variables);
- res= show_status_array(thd, "", init_vars, OPT_SESSION,
+ rw_rdlock(&LOCK_system_variables_hash);
+ res= show_status_array(thd, "", enumerate_sys_vars(thd, FALSE), OPT_SESSION,
NULL, "", tables->table, 1);
- pthread_mutex_unlock(&LOCK_global_system_variables);
+ rw_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 0ec0a8e0f86..a994ede6bdf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -662,16 +662,14 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
frm_action= TRUE;
else
{
- TABLE_SHARE dummy;
-
- hton= ha_resolve_by_name(thd, &handler_name);
- if (!hton)
+ plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
+ if (!plugin)
{
my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
goto error;
}
- bzero(&dummy, sizeof(TABLE_SHARE));
- file= get_new_handler(&dummy, &mem_root, hton);
+ hton= plugin_data(plugin, handlerton*);
+ file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
if (!file)
{
mem_alloc_error(sizeof(handler));
@@ -1635,7 +1633,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
TABLE_SHARE *share;
table->db_type= NULL;
if ((share= get_cached_table_share(table->db, table->table_name)))
- table->db_type= share->db_type;
+ table->db_type= share->db_type();
/* Disable drop of enabled log tables */
if (share && share->log_table &&
@@ -5070,7 +5068,7 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list,
See BUG#6236.
*/
if (table->s->fields != create_list->elements ||
- table->s->db_type != create_info->db_type ||
+ table->s->db_type() != create_info->db_type ||
table->s->tmp_table ||
create_info->used_fields & HA_CREATE_USED_ENGINE ||
create_info->used_fields & HA_CREATE_USED_CHARSET ||
@@ -5529,7 +5527,7 @@ view_err:
new_name= table_name;
}
- old_db_type= table->s->db_type;
+ old_db_type= table->s->db_type();
if (!create_info->db_type)
{
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -6043,7 +6041,7 @@ view_err:
}
if (thd->variables.old_alter_table
- || (table->s->db_type != create_info->db_type)
+ || (table->s->db_type() != create_info->db_type)
#ifdef WITH_PARTITION_STORAGE_ENGINE
|| partition_changed
#endif
@@ -6081,8 +6079,8 @@ view_err:
uint *idx_p;
uint *idx_end_p;
- if (table->s->db_type->alter_table_flags)
- alter_flags= table->s->db_type->alter_table_flags(alter_info->flags);
+ if (table->s->db_type()->alter_table_flags)
+ alter_flags= table->s->db_type()->alter_table_flags(alter_info->flags);
DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
/* Check dropped indexes. */
for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
@@ -7111,7 +7109,7 @@ static bool check_engine(THD *thd, const char *table_name,
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
{
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
- hton2plugin[(*new_engine)->slot]->name.str, "TEMPORARY");
+ ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
*new_engine= 0;
return TRUE;
}
diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc
index 84391a54642..b4a03a370ba 100644
--- a/sql/sql_tablespace.cc
+++ b/sql/sql_tablespace.cc
@@ -34,7 +34,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_WARN_USING_OTHER_HANDLER,
ER(ER_WARN_USING_OTHER_HANDLER),
- hton2plugin[hton->slot]->name.str,
+ ha_resolve_storage_engine_name(hton),
ts_info->tablespace_name ? ts_info->tablespace_name
: ts_info->logfile_group_name);
}
@@ -63,7 +63,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_ILLEGAL_HA_CREATE_OPTION,
ER(ER_ILLEGAL_HA_CREATE_OPTION),
- hton2plugin[hton->slot]->name.str,
+ ha_resolve_storage_engine_name(hton),
"TABLESPACE or LOGFILE GROUP");
}
if (mysql_bin_log.is_open())
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 0c7d2fc2187..c0a8ebada43 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -49,9 +49,9 @@ const LEX_STRING null_lex_str={0,0};
#define MYSQL_YYABORT \
do \
- { \
+ { \
LEX::cleanup_lex_after_parse_error(YYTHD);\
- YYABORT; \
+ YYABORT; \
} while (0)
#define MYSQL_YYABORT_UNLESS(A) \
@@ -1591,14 +1591,26 @@ create:
lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
lex->create_info.options=$2 | $4;
- lex->create_info.db_type= lex->thd->variables.table_type;
+ lex->create_info.db_type= ha_default_handlerton(thd);
lex->create_info.default_table_charset= NULL;
lex->name.str= 0;
lex->name.length= 0;
lex->like_name= 0;
}
create2
- { Lex->current_select= &Lex->select_lex; }
+ {
+ LEX *lex= YYTHD->lex;
+ lex->current_select= &lex->select_lex;
+ if (!lex->create_info.db_type)
+ {
+ lex->create_info.db_type= ha_default_handlerton(YYTHD);
+ push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_USING_OTHER_HANDLER,
+ ER(ER_WARN_USING_OTHER_HANDLER),
+ ha_resolve_storage_engine_name(lex->create_info.db_type),
+ $5->table.str);
+ }
+ }
| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON
table_ident
{
@@ -3669,6 +3681,13 @@ partitioning:
{
#ifdef WITH_PARTITION_STORAGE_ENGINE
LEX *lex= Lex;
+ LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
+ if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
+ {
+ my_error(ER_FEATURE_DISABLED, MYF(0),
+ "partitioning", "--with-partition");
+ MYSQL_YYABORT;
+ }
lex->part_info= new partition_info();
if (!lex->part_info)
{
@@ -4384,36 +4403,48 @@ default_collation:
Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
};
-known_storage_engines:
- ident_or_text
- {
- $$ = ha_resolve_by_name(YYTHD, &$1);
- if ($$ == NULL)
- {
- my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
- MYSQL_YYABORT;
- }
- }
- ;
-
storage_engines:
ident_or_text
{
- $$ = ha_resolve_by_name(YYTHD, &$1);
- if ($$ == NULL)
+ LEX *lex= YYTHD->lex;
+ plugin_ref plugin;
+
+ if ((plugin= ha_resolve_by_name(YYTHD, &$1)))
+ $$= plugin_data(plugin, handlerton*);
+ else
{
if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
- {
- my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
- MYSQL_YYABORT;
- }
-
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_UNKNOWN_STORAGE_ENGINE,
- ER(ER_UNKNOWN_STORAGE_ENGINE), $1.str);
+ {
+ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
+ MYSQL_YYABORT;
+ }
+ if (lex->sql_command == SQLCOM_ALTER_TABLE)
+ {
+ TABLE_LIST *table= (TABLE_LIST *) lex->select_lex.table_list.first;
+ $$= ha_default_handlerton(YYTHD);
+ push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_USING_OTHER_HANDLER,
+ ER(ER_WARN_USING_OTHER_HANDLER),
+ ha_resolve_storage_engine_name($$),
+ table->table_name);
+ }
}
};
+known_storage_engines:
+ ident_or_text
+ {
+ plugin_ref plugin;
+ if ((plugin= ha_resolve_by_name(YYTHD, &$1)))
+ $$= plugin_data(plugin, handlerton*);
+ else
+ {
+ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
+ MYSQL_YYABORT;
+ }
+ }
+ ;
+
row_types:
DEFAULT { $$= ROW_TYPE_DEFAULT; }
| FIXED_SYM { $$= ROW_TYPE_FIXED; }
@@ -5155,7 +5186,7 @@ alter:
lex->spname= $3;
}
| ALTER view_algorithm definer
- {
+ {
Lex->create_view_mode= VIEW_ALTER;
}
view_tail
@@ -5169,10 +5200,10 @@ alter:
{
LEX *lex= Lex;
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
- lex->create_view_mode= VIEW_ALTER;
- }
+ lex->create_view_mode= VIEW_ALTER;
+ }
view_tail
- {}
+ {}
| ALTER definer EVENT_SYM sp_name
/*
BE CAREFUL when you add a new rule to update the block where
@@ -5982,7 +6013,7 @@ preload_keys:
;
cache_keys_spec:
- {
+ {
Lex->select_lex.alloc_index_hints(YYTHD);
Select->set_index_hint_type(INDEX_HINT_USE,
global_system_variables.old_mode ?
@@ -6089,7 +6120,7 @@ select_into:
| select_from into;
select_from:
- FROM join_table_list where_clause group_clause having_clause
+ FROM join_table_list where_clause group_clause having_clause
opt_order_clause opt_limit_clause procedure_clause
{
Select->context.table_list=
@@ -6296,8 +6327,8 @@ bool_test:
{ $$= new (YYTHD->mem_root) Item_func_isfalse($1); }
| bool_pri IS not FALSE_SYM
{ $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); }
- | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
- | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
+ | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
+ | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
| bool_pri
;
@@ -6312,11 +6343,11 @@ bool_pri:
| predicate ;
predicate:
- bit_expr IN_SYM '(' subselect ')'
+ bit_expr IN_SYM '(' subselect ')'
{
$$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
}
- | bit_expr not IN_SYM '(' subselect ')'
+ | bit_expr not IN_SYM '(' subselect ')'
{
THD *thd= YYTHD;
Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
@@ -6326,23 +6357,23 @@ predicate:
{
$$= handle_sql2003_note184_exception(YYTHD, $1, true, $4);
}
- | bit_expr IN_SYM '(' expr ',' expr_list ')'
- {
- $6->push_front($4);
- $6->push_front($1);
+ | bit_expr IN_SYM '(' expr ',' expr_list ')'
+ {
+ $6->push_front($4);
+ $6->push_front($1);
$$= new (YYTHD->mem_root) Item_func_in(*$6);
}
| bit_expr not IN_SYM '(' expr ')'
{
$$= handle_sql2003_note184_exception(YYTHD, $1, false, $5);
}
- | bit_expr not IN_SYM '(' expr ',' expr_list ')'
+ | bit_expr not IN_SYM '(' expr ',' expr_list ')'
{
- $7->push_front($5);
- $7->push_front($1);
+ $7->push_front($5);
+ $7->push_front($1);
Item_func_in *item = new (YYTHD->mem_root) Item_func_in(*$7);
- item->negate();
- $$= item;
+ item->negate();
+ $$= item;
}
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{ $$= new Item_func_between($1,$3,$5); }
@@ -7546,10 +7577,10 @@ opt_outer:
index_hint_clause:
/* empty */
- {
+ {
$$= global_system_variables.old_mode ?
INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
- }
+ }
| FOR_SYM JOIN_SYM { $$= INDEX_HINT_MASK_JOIN; }
| FOR_SYM ORDER_SYM BY { $$= INDEX_HINT_MASK_ORDER; }
| FOR_SYM GROUP_SYM BY { $$= INDEX_HINT_MASK_GROUP; }
@@ -7562,12 +7593,12 @@ index_hint_type:
index_hint_definition:
index_hint_type key_or_index index_hint_clause
- {
+ {
Select->set_index_hint_type($1, $3);
- }
+ }
'(' key_usage_list ')'
| USE_SYM key_or_index index_hint_clause
- {
+ {
Select->set_index_hint_type(INDEX_HINT_USE, $3);
}
'(' opt_key_usage_list ')'
@@ -7576,12 +7607,12 @@ index_hint_definition:
index_hints_list:
index_hint_definition
| index_hints_list index_hint_definition
- ;
+ ;
opt_index_hints_list:
/* empty */
| { Select->alloc_index_hints(YYTHD); } index_hints_list
- ;
+ ;
opt_key_definition:
{ Select->clear_index_hints(); }
@@ -7595,7 +7626,7 @@ opt_key_usage_list:
key_usage_element:
ident { Select->add_index_hint(YYTHD, $1.str, $1.length); }
- | PRIMARY_SYM
+ | PRIMARY_SYM
{
Select->add_index_hint(YYTHD, (char *)"PRIMARY", 7);
}
@@ -8632,7 +8663,7 @@ show_param:
{ Lex->create_info.db_type= NULL; }
| opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
{
- LEX *lex= Lex;
+ LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
$4->change_db($5);
@@ -10271,7 +10302,7 @@ sys_option_value:
LEX *lex=Lex;
lex->option_type= $1;
lex->var_list.push_back(new set_var(lex->option_type,
- find_sys_var("tx_isolation"),
+ find_sys_var(YYTHD, "tx_isolation"),
&null_lex_str,
new Item_int((int32) $5)));
}
@@ -10360,7 +10391,7 @@ internal_variable_name:
if (!spc || !(spv = spc->find_variable(&$1)))
{
/* Not an SP local variable */
- sys_var *tmp=find_sys_var($1.str, $1.length);
+ sys_var *tmp=find_sys_var(YYTHD, $1.str, $1.length);
if (!tmp)
MYSQL_YYABORT;
$$.var= tmp;
@@ -10415,7 +10446,7 @@ internal_variable_name:
}
else
{
- sys_var *tmp=find_sys_var($3.str, $3.length);
+ sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
if (!tmp)
MYSQL_YYABORT;
if (!tmp->is_struct())
@@ -10426,7 +10457,7 @@ internal_variable_name:
}
| DEFAULT '.' ident
{
- sys_var *tmp=find_sys_var($3.str, $3.length);
+ sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
if (!tmp)
MYSQL_YYABORT;
if (!tmp->is_struct())
diff --git a/sql/structs.h b/sql/structs.h
index 377d337dcfa..f55a9757011 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -83,7 +83,7 @@ typedef struct st_key {
*/
union
{
- struct st_plugin_int *parser; /* Fulltext [pre]parser */
+ plugin_ref parser; /* Fulltext [pre]parser */
LEX_STRING *parser_name; /* Fulltext [pre]parser name */
};
KEY_PART_INFO *key_part;
diff --git a/sql/table.cc b/sql/table.cc
index c0b04093f36..9895c54f7a9 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -237,6 +237,9 @@ void free_table_share(TABLE_SHARE *share)
pthread_cond_destroy(&share->cond);
}
hash_free(&share->name_hash);
+
+ plugin_unlock(NULL, share->db_plugin);
+ share->db_plugin= NULL;
/* We must copy mem_root from share because share is allocated through it */
memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
@@ -500,7 +503,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
DBUG_PRINT("info", ("default_part_db_type = %u", head[61]));
#endif
legacy_db_type= (enum legacy_db_type) (uint) *(head+3);
- share->db_type= ha_checktype(thd, legacy_db_type, 0, 0);
+ DBUG_ASSERT(share->db_plugin == NULL);
+ /*
+ if the storage engine is dynamic, no point in resolving it by its
+ dynamically allocated legacy_db_type. We will resolve it later by name.
+ */
+ if (legacy_db_type > DB_TYPE_UNKNOWN &&
+ legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
+ share->db_plugin= ha_lock_engine(NULL,
+ ha_checktype(thd, legacy_db_type, 0, 0));
share->db_create_options= db_create_options= uint2korr(head+30);
share->db_options_in_use= share->db_create_options;
share->mysql_version= uint4korr(head+51);
@@ -659,24 +670,47 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
uint str_db_type_length= uint2korr(next_chunk);
LEX_STRING name= { next_chunk + 2, str_db_type_length };
- handlerton *tmp_db_type= ha_resolve_by_name(thd, &name);
- if (tmp_db_type != NULL)
+ plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
+ if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
{
- share->db_type= tmp_db_type;
+ if (legacy_db_type > DB_TYPE_UNKNOWN &&
+ legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
+ legacy_db_type != ha_legacy_type(
+ plugin_data(tmp_plugin, handlerton *)))
+ {
+ /* bad file, legacy_db_type did not match the name */
+ my_free(buff, MYF(0));
+ goto err;
+ }
+ /*
+ tmp_plugin is locked with a local lock.
+ we unlock the old value of share->db_plugin before
+ replacing it with a globally locked version of tmp_plugin
+ */
+ plugin_unlock(NULL, share->db_plugin);
+ share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
- ha_legacy_type(share->db_type)));
+ ha_legacy_type(share->db_type())));
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
else
{
- if (!strncmp(next_chunk + 2, "partition", str_db_type_length))
+ LEX_STRING pname= { C_STRING_WITH_LEN( "partition" ) };
+ if (str_db_type_length == pname.length &&
+ !strncmp(next_chunk + 2, pname.str, pname.length))
{
- /* Use partition handler */
- share->db_type= partition_hton;
+ /*
+ Use partition handler
+ tmp_plugin is locked with a local lock.
+ we unlock the old value of share->db_plugin before
+ replacing it with a globally locked version of tmp_plugin
+ */
+ plugin_unlock(NULL, share->db_plugin);
+ share->db_plugin= ha_lock_engine(NULL, partition_hton);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
- ha_legacy_type(share->db_type)));
+ ha_legacy_type(share->db_type())));
}
}
#endif
@@ -742,7 +776,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
}
parser_name.str= next_chunk;
parser_name.length= strlen(next_chunk);
- keyinfo->parser= plugin_lock(&parser_name, MYSQL_FTPARSER_PLUGIN);
+ keyinfo->parser= my_plugin_lock_by_name(NULL, &parser_name,
+ MYSQL_FTPARSER_PLUGIN);
if (! keyinfo->parser)
{
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
@@ -858,7 +893,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
- share->db_type)))
+ share->db_type())))
goto err;
record= (char*) share->default_values-1; /* Fieldstart = 1 */
@@ -1392,7 +1427,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
/* Allocate handler */
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
- share->db_type)))
+ share->db_type())))
goto err;
error= 4;
@@ -1676,7 +1711,7 @@ int closefrm(register TABLE *table, bool free_share)
{
if (key_info->flags & HA_USES_PARSER)
{
- plugin_unlock(key_info->parser);
+ plugin_unlock(NULL, key_info->parser);
key_info->flags= 0;
}
}
@@ -1887,10 +1922,10 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
handler *file= 0;
const char *datext= "";
- if (share->db_type != NULL)
+ if (share->db_type() != NULL)
{
if ((file= get_new_handler(share, current_thd->mem_root,
- share->db_type)))
+ share->db_type())))
{
if (!(datext= *file->bas_ext()))
datext= "";
diff --git a/sql/table.h b/sql/table.h
index bb9ced2e450..8c2d95a92d1 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -172,7 +172,12 @@ typedef struct st_table_share
ulong timestamp_offset; /* Set to offset+1 of record */
ulong reclength; /* Recordlength */
- handlerton *db_type; /* table_type for handler */
+ plugin_ref db_plugin; /* storage engine plugin */
+ inline handlerton *db_type() const /* table_type for handler */
+ {
+ // DBUG_ASSERT(db_plugin);
+ return db_plugin ? plugin_data(db_plugin, handlerton*) : NULL;
+ }
enum row_type row_type; /* How rows are stored */
enum tmp_table_type tmp_table;
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index a4cdcafc6d0..53af99dee97 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -723,6 +723,11 @@ int ha_example::external_lock(THD *thd, int lock_type)
Called from lock.cc by get_lock_data().
+ @note
+ In this method one should NEVER rely on table->in_use, it may, in fact,
+ refer to a different thread! (this happens if get_lock_data() is called
+ from mysql_lock_abort_for_thread() function)
+
@see
get_lock_data() in lock.cc
*/
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index aa7184268f5..da8ad46f96d 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -1832,7 +1832,7 @@ int ha_federated::write_row(byte *buf)
values_string.length(0);
insert_string.length(0);
insert_field_value_string.length(0);
- statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
@@ -2299,8 +2299,7 @@ int ha_federated::index_read_idx_with_result_set(byte *buf, uint index,
*result= 0; // In case of errors
index_string.length(0);
sql_query.length(0);
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
sql_query.append(share->select_query);
@@ -2414,8 +2413,7 @@ int ha_federated::read_range_next()
int ha_federated::index_next(byte *buf)
{
DBUG_ENTER("ha_federated::index_next");
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
DBUG_RETURN(read_next(buf, stored_result));
}
@@ -2616,8 +2614,7 @@ int ha_federated::rnd_pos(byte *buf, byte *pos)
{
int result;
DBUG_ENTER("ha_federated::rnd_pos");
- statistic_increment(table->in_use->status_var.ha_read_rnd_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_count);
if (table->s->primary_key != MAX_KEY)
{
/* We have a primary key, so use index_read_idx to find row */
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 8c378f7334f..096b0f63b5e 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -181,7 +181,7 @@ void ha_heap::update_key_stats()
int ha_heap::write_row(byte * buf)
{
int res;
- statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
@@ -205,7 +205,7 @@ int ha_heap::write_row(byte * buf)
int ha_heap::update_row(const byte * old_data, byte * new_data)
{
int res;
- statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
res= heap_update(file,old_data,new_data);
@@ -224,7 +224,7 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
int ha_heap::delete_row(const byte * buf)
{
int res;
- statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_delete_count);
res= heap_delete(file,buf);
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
@@ -242,8 +242,7 @@ int ha_heap::index_read(byte * buf, const byte * key, key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -252,8 +251,7 @@ int ha_heap::index_read(byte * buf, const byte * key, key_part_map keypart_map,
int ha_heap::index_read_last(byte *buf, const byte *key, key_part_map keypart_map)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error= heap_rkey(file, buf, active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status= error ? STATUS_NOT_FOUND : 0;
@@ -264,8 +262,7 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -274,8 +271,7 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
int ha_heap::index_next(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
int error=heap_rnext(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -284,8 +280,7 @@ int ha_heap::index_next(byte * buf)
int ha_heap::index_prev(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_prev_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_prev_count);
int error=heap_rprev(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -294,8 +289,7 @@ int ha_heap::index_prev(byte * buf)
int ha_heap::index_first(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_first_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_first_count);
int error=heap_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -304,8 +298,7 @@ int ha_heap::index_first(byte * buf)
int ha_heap::index_last(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_last_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_last_count);
int error=heap_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -318,8 +311,7 @@ int ha_heap::rnd_init(bool scan)
int ha_heap::rnd_next(byte *buf)
{
- statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=heap_scan(file, buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -329,8 +321,7 @@ int ha_heap::rnd_pos(byte * buf, byte *pos)
{
int error;
HEAP_PTR heap_position;
- statistic_increment(table->in_use->status_var.ha_read_rnd_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_count);
memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR));
error=heap_rrnd(file, buf, heap_position);
table->status=error ? STATUS_NOT_FOUND: 0;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 1932f775a3d..e7bf0f94195 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -54,7 +54,7 @@ bool innodb_inited= 0;
This needs to exist until the query cache callback is removed
or learns to pass hton.
*/
-static handlerton *legacy_innodb_hton;
+static handlerton *innodb_hton_ptr;
/* Store MySQL definition of 'byte': in Linux it is char while InnoDB
uses unsigned char; the header univ.i which we include next defines
@@ -92,7 +92,6 @@ extern "C" {
#include "../storage/innobase/include/ha_prototypes.h"
}
-ulong innobase_large_page_size = 0;
/* The default values for the following, type long or longlong, start-up
parameters are declared in mysqld.cc: */
@@ -119,19 +118,29 @@ char* innobase_unix_file_flush_method = NULL;
/* Below we have boolean-valued start-up parameters, and their default
values */
+static
ulong innobase_fast_shutdown = 1;
+#ifdef UNIV_LOG_ARCHIVE
+static
my_bool innobase_log_archive = FALSE;/* unused */
+#endif /* UNIG_LOG_ARCHIVE */
+static
my_bool innobase_use_doublewrite = TRUE;
+static
my_bool innobase_use_checksums = TRUE;
-my_bool innobase_use_large_pages = FALSE;
-my_bool innobase_use_native_aio = FALSE;
+static
my_bool innobase_file_per_table = FALSE;
+static
my_bool innobase_locks_unsafe_for_binlog = FALSE;
+static
my_bool innobase_rollback_on_timeout = FALSE;
+static
my_bool innobase_create_status_file = FALSE;
+static
my_bool innobase_stats_on_metadata = TRUE;
-static char *internal_innobase_data_file_path = NULL;
+static
+char* internal_innobase_data_file_path = NULL;
/* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call
@@ -165,6 +174,17 @@ static handler *innobase_create_handler(handlerton *hton,
static const char innobase_hton_name[]= "InnoDB";
+
+static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
+ "Enable InnoDB support for the XA two-phase commit",
+ /* check_func */ NULL, /* update_func */ NULL,
+ /* default */ TRUE);
+
+static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
+ "Enable InnoDB locking in LOCK TABLES",
+ /* check_func */ NULL, /* update_func */ NULL,
+ /* default */ TRUE);
+
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root)
@@ -469,10 +489,9 @@ trx_t*&
thd_to_trx(
/*=======*/
/* out: reference to transaction pointer */
- THD* thd, /* in: MySQL thread */
- handlerton* hton) /* in: InnoDB handlerton */
+ THD* thd) /* in: MySQL thread */
{
- return(*(trx_t**) thd_ha_data(thd, hton));
+ return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
}
/************************************************************************
@@ -493,7 +512,7 @@ innobase_release_temporary_latches(
return 0;
}
- trx = thd_to_trx(thd, hton);
+ trx = thd_to_trx(thd);
if (trx) {
innobase_release_stat_resources(trx);
@@ -673,78 +692,12 @@ innobase_mysql_print_thd(
uint max_query_len) /* in: max query length to print, or 0 to
use the default max length */
{
- const THD* thd;
- const Security_context *sctx;
- const char* s;
-
- thd = (const THD*) input_thd;
- /* We probably want to have original user as part of debug output. */
- sctx = &thd->main_security_ctx;
-
-
- fprintf(f, "MySQL thread id %lu, query id %lu",
- thd->thread_id, (ulong) thd->query_id);
- if (sctx->host) {
- putc(' ', f);
- fputs(sctx->host, f);
- }
-
- if (sctx->ip) {
- putc(' ', f);
- fputs(sctx->ip, f);
- }
-
- if (sctx->user) {
- putc(' ', f);
- fputs(sctx->user, f);
- }
-
- if ((s = thd->proc_info)) {
- putc(' ', f);
- fputs(s, f);
- }
-
- if ((s = thd->query)) {
- /* 3100 is chosen because currently 3000 is the maximum
- max_query_len we ever give this. */
- char buf[3100];
- uint len;
-
- /* If buf is too small, we dynamically allocate storage
- in this. */
- char* dyn_str = NULL;
-
- /* Points to buf or dyn_str. */
- char* str = buf;
-
- if (max_query_len == 0) {
- /* ADDITIONAL SAFETY: the default is to print at
- most 300 chars to reduce the probability of a
- seg fault if there is a race in
- thd->query_length in MySQL; after May 14, 2004
- probably no race any more, but better be
- safe */
- max_query_len = 300;
- }
-
- len = min(thd->query_length, max_query_len);
-
- if (len > (sizeof(buf) - 1)) {
- dyn_str = my_malloc(len + 1, MYF(0));
- str = dyn_str;
- }
-
- /* Use strmake to reduce the timeframe for a race,
- compared to fwrite() */
- len = (uint) (strmake(str, s, len) - str);
- putc('\n', f);
- fwrite(str, 1, len, f);
-
- if (dyn_str) {
- my_free(dyn_str, MYF(0));
- }
- }
+ THD* thd;
+ char buffer[1024];
+ thd = (THD*) input_thd;
+ fputs(thd_security_context(thd, buffer, sizeof(buffer),
+ max_query_len), f);
putc('\n', f);
}
@@ -953,7 +906,7 @@ check_trx_exists(
handlerton* hton, /* in: handlerton for innodb */
THD* thd) /* in: user thread handle */
{
- trx_t*& trx = thd_to_trx(thd, hton);
+ trx_t*& trx = thd_to_trx(thd);
ut_ad(thd == current_thd);
@@ -967,7 +920,9 @@ check_trx_exists(
/* 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, support_xa);
+
+ thd_to_trx(thd) = trx;
} else {
if (trx->magic_n != TRX_MAGIC_N) {
mem_analyze_corruption(trx);
@@ -976,13 +931,13 @@ check_trx_exists(
}
}
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
trx->check_foreigns = FALSE;
} else {
trx->check_foreigns = TRUE;
}
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
trx->check_unique_secondary = FALSE;
} else {
trx->check_unique_secondary = TRUE;
@@ -1069,7 +1024,7 @@ innobase_register_trx_and_stmt(
innobase_register_stmt(hton, thd);
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
+ if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
/* No autocommit mode, register for a transaction */
trans_register_ha(thd, TRUE, hton);
@@ -1161,14 +1116,15 @@ innobase_query_caching_of_table_permitted(
ut_a(full_name_len < 999);
- if (thd->variables.tx_isolation == ISO_SERIALIZABLE) {
+ trx = check_trx_exists(innodb_hton_ptr, thd);
+
+ if (trx->isolation_level == TRX_ISO_SERIALIZABLE) {
/* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every
plain SELECT if AUTOCOMMIT is not on. */
return((my_bool)FALSE);
}
- trx = check_trx_exists(legacy_innodb_hton, thd);
if (trx->has_search_latch) {
ut_print_timestamp(stderr);
sql_print_error("The calling thread is holding the adaptive "
@@ -1182,7 +1138,7 @@ innobase_query_caching_of_table_permitted(
innobase_release_stat_resources(trx);
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+ if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
is_autocommit = TRUE;
} else {
@@ -1227,7 +1183,7 @@ innobase_query_caching_of_table_permitted(
if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(legacy_innodb_hton, thd);
+ innobase_register_trx_and_stmt(innodb_hton_ptr, thd);
trx->active_trans = 1;
}
@@ -1367,7 +1323,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
one. Update the trx pointers in the prebuilt struct. Normally
this operation is done in external_lock. */
- update_thd(current_thd);
+ update_thd(ha_thd());
/* Initialize the prebuilt struct much like it would be inited in
external_lock */
@@ -1386,7 +1342,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
if (prebuilt->trx->active_trans == 0) {
- innobase_register_trx_and_stmt(ht, current_thd);
+ innobase_register_trx_and_stmt(ht, ha_thd());
prebuilt->trx->active_trans = 1;
}
@@ -1430,9 +1386,9 @@ innobase_init(void *p)
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p;
- legacy_innodb_hton= innobase_hton;
+ innodb_hton_ptr= innobase_hton;
- innobase_hton->state=have_innodb;
+ innobase_hton->state= SHOW_OPTION_YES;
innobase_hton->db_type= DB_TYPE_INNODB;
innobase_hton->savepoint_offset=sizeof(trx_named_savept_t);
innobase_hton->close_connection=innobase_close_connection;
@@ -1457,9 +1413,6 @@ innobase_init(void *p)
innobase_hton->flags=HTON_NO_FLAGS;
innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
- if (have_innodb != SHOW_OPTION_YES)
- DBUG_RETURN(0); // nothing else to do
-
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
#ifdef UNIV_DEBUG
@@ -1641,8 +1594,10 @@ innobase_init(void *p)
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
- os_use_large_pages = (ibool) innobase_use_large_pages;
- os_large_page_size = (ulint) innobase_large_page_size;
+#ifdef HAVE_LARGE_PAGES
+ if ((os_use_large_pages = (ibool) my_use_large_pages))
+ os_large_page_size = (ulint) opt_large_page_size;
+#endif
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
@@ -1701,7 +1656,6 @@ innobase_init(void *p)
DBUG_RETURN(FALSE);
error:
- have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
DBUG_RETURN(TRUE);
}
@@ -1844,7 +1798,7 @@ innobase_commit(
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, support_xa);
/* Since we will reserve the kernel mutex, we have to release
the search system latch first to obey the latching order. */
@@ -1875,7 +1829,7 @@ innobase_commit(
" trx->conc_state != TRX_NOT_STARTED");
}
if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* We were instructed to commit the whole transaction, or
this is an SQL statement end and autocommit is on */
@@ -2037,7 +1991,7 @@ innobase_commit_complete(
{
trx_t* trx;
- trx = thd_to_trx(thd, hton);
+ trx = thd_to_trx(thd);
if (trx && trx->active_trans) {
@@ -2077,7 +2031,7 @@ innobase_rollback(
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, support_xa);
/* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch
@@ -2094,7 +2048,7 @@ innobase_rollback(
}
if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
error = trx_rollback_for_mysql(trx);
trx->active_trans = 0;
@@ -2226,7 +2180,7 @@ innobase_savepoint(
(unless we are in sub-statement), so SQL layer ensures that
this method is never called in such situation.
*/
- DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+ DBUG_ASSERT(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
thd->in_sub_stmt);
trx = check_trx_exists(hton, thd);
@@ -2262,7 +2216,7 @@ innobase_close_connection(
{
trx_t* trx;
- trx = thd_to_trx(thd, hton);
+ trx = thd_to_trx(thd);
ut_a(trx);
@@ -2397,7 +2351,7 @@ ha_innobase::open(
UT_NOT_USED(mode);
UT_NOT_USED(test_if_locked);
- thd = current_thd;
+ thd = ha_thd();
normalize_table_name(norm_name, name);
user_thd = NULL;
@@ -3349,8 +3303,8 @@ ha_innobase::write_row(
longlong auto_inc;
longlong dummy;
ibool auto_inc_used= FALSE;
- THD* thd = current_thd;
- trx_t* trx = thd_to_trx(thd, ht);
+ THD *thd= ha_thd();
+ trx_t* trx = thd_to_trx(thd);
DBUG_ENTER("ha_innobase::write_row");
@@ -3374,10 +3328,10 @@ ha_innobase::write_row(
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
- if ((user_thd->lex->sql_command == SQLCOM_ALTER_TABLE
- || user_thd->lex->sql_command == SQLCOM_OPTIMIZE
- || user_thd->lex->sql_command == SQLCOM_CREATE_INDEX
- || user_thd->lex->sql_command == SQLCOM_DROP_INDEX)
+ if ((thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_OPTIMIZE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX
+ || thd_sql_command(thd) == SQLCOM_DROP_INDEX)
&& num_write_row >= 10000) {
/* ALTER TABLE is COMMITted at every 10000 copied rows.
The IX table lock for the original table has to be re-issued.
@@ -3529,10 +3483,11 @@ no_commit:
performing those statements. */
if (error == DB_DUPLICATE_KEY && auto_inc_used
- && (user_thd->lex->sql_command == SQLCOM_REPLACE
- || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
- || (user_thd->lex->sql_command == SQLCOM_LOAD
- && user_thd->lex->duplicates == DUP_REPLACE))) {
+ && (thd_sql_command(thd) == SQLCOM_REPLACE
+ || thd_sql_command(thd) == SQLCOM_REPLACE_SELECT
+ || (thd_sql_command(thd) == SQLCOM_LOAD
+ && prebuilt->trx->allow_duplicates
+ && prebuilt->trx->replace_duplicates))) {
auto_inc = table->next_number_field->val_int();
@@ -3720,7 +3675,7 @@ ha_innobase::update_row(
{
upd_t* uvect;
int error = 0;
- trx_t* trx = thd_to_trx(current_thd, ht);
+ trx_t* trx = thd_to_trx(ha_thd());
DBUG_ENTER("ha_innobase::update_row");
@@ -3773,7 +3728,7 @@ ha_innobase::delete_row(
const mysql_byte* record) /* in: a row in MySQL format */
{
int error = 0;
- trx_t* trx = thd_to_trx(current_thd, ht);
+ trx_t* trx = thd_to_trx(ha_thd());
DBUG_ENTER("ha_innobase::delete_row");
@@ -3852,7 +3807,7 @@ void
ha_innobase::try_semi_consistent_read(bool yes)
/*===========================================*/
{
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
/* Row read type is set to semi consistent read if this was
requested by the MySQL and either innodb_locks_unsafe_for_binlog
@@ -4017,7 +3972,7 @@ ha_innobase::index_read(
DBUG_ENTER("index_read");
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
ha_statistic_increment(&SSV::ha_read_key_count);
@@ -4117,11 +4072,11 @@ ha_innobase::change_active_index(
InnoDB */
{
KEY* key=0;
- ha_statistic_increment(&SSV::ha_read_key_count);
DBUG_ENTER("change_active_index");
+ ha_statistic_increment(&SSV::ha_read_key_count);
- ut_ad(user_thd == current_thd);
- ut_a(prebuilt->trx == thd_to_trx(user_thd, ht));
+ ut_ad(user_thd == ha_thd());
+ ut_a(prebuilt->trx == thd_to_trx(user_thd));
active_index = keynr;
@@ -4209,7 +4164,7 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -4434,7 +4389,7 @@ ha_innobase::rnd_pos(
ha_statistic_increment(&SSV::ha_read_rnd_count);
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4482,7 +4437,7 @@ ha_innobase::position(
{
uint len;
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4791,7 +4746,7 @@ ha_innobase::create(
uint i;
char name2[FN_REFLEN];
char norm_name[FN_REFLEN];
- THD *thd= current_thd;
+ THD *thd= ha_thd();
ib_longlong auto_inc_value;
ulint flags;
@@ -4821,11 +4776,11 @@ ha_innobase::create(
trx->mysql_thd = thd;
trx->mysql_query_str = &((*thd).query);
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
trx->check_foreigns = FALSE;
}
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
+ if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
trx->check_unique_secondary = FALSE;
}
@@ -4981,7 +4936,7 @@ ha_innobase::discard_or_import_tablespace(
ut_a(prebuilt->trx);
ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
dict_table = prebuilt->table;
trx = prebuilt->trx;
@@ -5006,33 +4961,33 @@ ha_innobase::delete_all_rows(void)
/* out: error number */
{
int error;
- THD* thd = current_thd;
+ THD* thd = ha_thd();
DBUG_ENTER("ha_innobase::delete_all_rows");
- if (thd->lex->sql_command != SQLCOM_TRUNCATE) {
- fallback:
- /* We only handle TRUNCATE TABLE t as a special case.
- DELETE FROM t will have to use ha_innobase::delete_row(). */
- DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
- }
-
/* Get the transaction associated with the current thd, or create one
if not yet created, and update prebuilt->trx */
update_thd(thd);
- /* Truncate the table in InnoDB */
+ if (thd_sql_command(thd) == SQLCOM_TRUNCATE) {
+ /* Truncate the table in InnoDB */
- error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
- if (error == DB_ERROR) {
- /* Cannot truncate; resort to ha_innobase::delete_row() */
- goto fallback;
- }
+ error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
+ if (error == DB_ERROR) {
+ /* Cannot truncate; resort to ha_innobase::delete_row() */
+ goto fallback;
+ }
- error = convert_error_code_to_mysql(error, NULL);
+ error = convert_error_code_to_mysql(error, NULL);
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
+ }
+
+fallback:
+ /* We only handle TRUNCATE TABLE t as a special case.
+ DELETE FROM t will have to use ha_innobase::delete_row(). */
+ DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
}
/*********************************************************************
@@ -5052,7 +5007,7 @@ ha_innobase::delete_table(
int error;
trx_t* parent_trx;
trx_t* trx;
- THD *thd= current_thd;
+ THD *thd= ha_thd();
char norm_name[1000];
DBUG_ENTER("ha_innobase::delete_table");
@@ -5075,75 +5030,75 @@ ha_innobase::delete_table(
trx = trx_allocate_for_mysql();
- trx->mysql_thd = current_thd;
- trx->mysql_query_str = &((*current_thd).query);
+ trx->mysql_thd = ha_thd();
+ trx->mysql_query_str = &(ha_thd()->query);
- if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
- trx->check_foreigns = FALSE;
- }
+ if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
+ trx->check_foreigns = FALSE;
+ }
- if (thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
- trx->check_unique_secondary = FALSE;
- }
+ if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
+ trx->check_unique_secondary = FALSE;
+ }
- name_len = strlen(name);
+ name_len = strlen(name);
- assert(name_len < 1000);
+ assert(name_len < 1000);
- /* Strangely, MySQL passes the table name without the '.frm'
- extension, in contrast to ::create */
+ /* Strangely, MySQL passes the table name without the '.frm'
+ extension, in contrast to ::create */
- normalize_table_name(norm_name, name);
+ normalize_table_name(norm_name, name);
- /* Drop the table in InnoDB */
+ /* Drop the table in InnoDB */
- error = row_drop_table_for_mysql(norm_name, trx,
- thd->lex->sql_command == SQLCOM_DROP_DB);
+ error = row_drop_table_for_mysql(norm_name, trx,
+ thd_sql_command(thd) == SQLCOM_DROP_DB);
- /* Flush the log to reduce probability that the .frm files and
- the InnoDB data dictionary get out-of-sync if the user runs
- with innodb_flush_log_at_trx_commit = 0 */
+ /* Flush the log to reduce probability that the .frm files and
+ the InnoDB data dictionary get out-of-sync if the user runs
+ with innodb_flush_log_at_trx_commit = 0 */
- log_buffer_flush_to_disk();
+ log_buffer_flush_to_disk();
- /* Tell the InnoDB server that there might be work for
- utility threads: */
+ /* Tell the InnoDB server that there might be work for
+ utility threads: */
- srv_active_wake_master_thread();
+ srv_active_wake_master_thread();
- innobase_commit_low(trx);
+ innobase_commit_low(trx);
- trx_free_for_mysql(trx);
+ trx_free_for_mysql(trx);
- error = convert_error_code_to_mysql(error, NULL);
+ error = convert_error_code_to_mysql(error, NULL);
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/*********************************************************************
-Removes all tables in the named database inside InnoDB. */
+ Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
-/*===================*/
- /* out: error number */
- handlerton *hton, /* in: handlerton of Innodb */
- char* path) /* in: database path; inside InnoDB the name
- of the last directory in the path is used as
- the database name: for example, in 'mysql/data/test'
- the database name is 'test' */
-{
- ulint len = 0;
- trx_t* parent_trx;
- trx_t* trx;
- char* ptr;
- int error;
- char* namebuf;
-
- /* Get the transaction associated with the current thd, or create one
- if not yet created */
-
- parent_trx = check_trx_exists(hton, current_thd);
+ /*===================*/
+ /* out: error number */
+ handlerton *hton, /* in: handlerton of Innodb */
+ char* path) /* in: database path; inside InnoDB the name
+ of the last directory in the path is used as
+ the database name: for example, in 'mysql/data/test'
+ the database name is 'test' */
+{
+ ulint len = 0;
+ trx_t* parent_trx;
+ trx_t* trx;
+ char* ptr;
+ int error;
+ char* namebuf;
+
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(hton, ha_thd());
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5170,7 +5125,7 @@ innobase_drop_database(
trx->mysql_thd = current_thd;
trx->mysql_query_str = &((*current_thd).query);
- if (current_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ if (thd_test_options(current_thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
trx->check_foreigns = FALSE;
}
@@ -5222,7 +5177,7 @@ ha_innobase::rename_table(
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(ht, current_thd);
+ parent_trx = check_trx_exists(ht, ha_thd());
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5236,10 +5191,10 @@ ha_innobase::rename_table(
}
trx = trx_allocate_for_mysql();
- trx->mysql_thd = current_thd;
- trx->mysql_query_str = &((*current_thd).query);
+ trx->mysql_thd = ha_thd();
+ trx->mysql_query_str = &((*ha_thd()).query);
- if (current_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
+ if (thd_test_options(ha_thd(), OPTION_NO_FOREIGN_KEY_CHECKS)) {
trx->check_foreigns = FALSE;
}
@@ -5307,7 +5262,7 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range");
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
prebuilt->trx->op_info = (char*)"estimating records in index range";
@@ -5391,7 +5346,7 @@ ha_innobase::estimate_rows_upper_bound(void)
external_lock(). To be safe, update the thd of the current table
handle. */
- update_thd(current_thd);
+ update_thd(ha_thd());
prebuilt->trx->op_info = (char*)
"calculating upper bound for table rows";
@@ -5508,7 +5463,7 @@ ha_innobase::info(
external_lock(). To be safe, update the thd of the current table
handle. */
- update_thd(current_thd);
+ update_thd(ha_thd());
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5739,7 +5694,7 @@ ha_innobase::check(
ulint ret;
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template
@@ -5781,7 +5736,7 @@ ha_innobase::update_table_comment(
return((char*)comment); /* string too long */
}
- update_thd(current_thd);
+ update_thd(ha_thd());
prebuilt->trx->op_info = (char*)"returning table comment";
@@ -5852,7 +5807,7 @@ ha_innobase::get_foreign_key_create_info(void)
external_lock(). To be safe, update the thd of the current table
handle. */
- update_thd(current_thd);
+ update_thd(ha_thd());
prebuilt->trx->op_info = (char*)"getting info on foreign keys";
@@ -5901,7 +5856,7 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
DBUG_ENTER("get_foreign_key_list");
ut_a(prebuilt != NULL);
- update_thd(current_thd);
+ update_thd(ha_thd());
prebuilt->trx->op_info = (char*)"getting list of foreign keys";
trx_search_latch_release_if_reserved(prebuilt->trx);
mutex_enter_noninline(&(dict_sys->mutex));
@@ -6036,7 +5991,7 @@ ha_innobase::can_switch_engines(void)
DBUG_ENTER("ha_innobase::can_switch_engines");
- ut_a(prebuilt->trx == thd_to_trx(current_thd, ht));
+ ut_a(prebuilt->trx == thd_to_trx(ha_thd()));
prebuilt->trx->op_info =
"determining if there are foreign key constraints";
@@ -6117,6 +6072,19 @@ ha_innobase::extra(
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
prebuilt->keep_other_fields_on_keyread = 1;
break;
+ case HA_EXTRA_IGNORE_DUP_KEY:
+ prebuilt->trx->allow_duplicates= TRUE;
+ break;
+ case HA_EXTRA_WRITE_CAN_REPLACE:
+ prebuilt->trx->replace_duplicates= TRUE;
+ break;
+ case HA_EXTRA_WRITE_CANNOT_REPLACE:
+ prebuilt->trx->replace_duplicates= FALSE;
+ break;
+ case HA_EXTRA_NO_IGNORE_DUP_KEY:
+ prebuilt->trx->allow_duplicates= FALSE;
+ prebuilt->trx->replace_duplicates= FALSE;
+ break;
default:/* Do nothing */
;
}
@@ -6183,7 +6151,7 @@ ha_innobase::start_stmt(
prebuilt->select_lock_type = LOCK_X;
} else {
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
- && thd->lex->sql_command == SQLCOM_SELECT
+ && thd_sql_command(thd) == SQLCOM_SELECT
&& lock_type == TL_READ) {
/* For other than temporary tables, we obtain
@@ -6295,8 +6263,8 @@ ha_innobase::external_lock(
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
&& prebuilt->select_lock_type == LOCK_NONE
- && (thd->options
- & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+ && thd_test_options(thd,
+ OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
/* To get serializable execution, we let InnoDB
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
@@ -6323,10 +6291,10 @@ ha_innobase::external_lock(
if (prebuilt->select_lock_type != LOCK_NONE) {
- if (thd->lex->sql_command == SQLCOM_LOCK_TABLES
- && thd->variables.innodb_table_locks
- && (thd->options & OPTION_NOT_AUTOCOMMIT)
- && thd_in_lock_tables(thd)) {
+ if (thd_in_lock_tables(thd) &&
+ thd_sql_command(thd) == SQLCOM_LOCK_TABLES &&
+ THDVAR(thd, table_locks) &&
+ thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)) {
ulint error = row_lock_table_for_mysql(
prebuilt, NULL, 0);
@@ -6363,7 +6331,7 @@ ha_innobase::external_lock(
innobase_release_stat_resources(trx);
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+ if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
if (trx->active_trans != 0) {
innobase_commit(ht, thd, TRUE);
}
@@ -6405,7 +6373,7 @@ ha_innobase::transactional_table_lock(
update_thd(thd);
if (prebuilt->table->ibd_file_missing
- && !thd_tablespace_op(current_thd)) {
+ && !thd_tablespace_op(ha_thd())) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB error:\n"
"MySQL is trying to use a table handle but the .ibd file for\n"
@@ -6450,7 +6418,7 @@ ha_innobase::transactional_table_lock(
trx->active_trans = 1;
}
- if (thd->variables.innodb_table_locks && thd_in_lock_tables(thd)) {
+ if (thd_in_lock_tables(thd) && THDVAR(thd, table_locks)) {
ulint error = DB_SUCCESS;
error = row_lock_table_for_mysql(prebuilt, NULL, 0);
@@ -6460,7 +6428,7 @@ ha_innobase::transactional_table_lock(
DBUG_RETURN((int) error);
}
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
+ if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
/* Store the current undo_no of the transaction
so that we know where to roll back if we have
@@ -6506,10 +6474,6 @@ innodb_show_status(
DBUG_ENTER("innodb_show_status");
- if (have_innodb != SHOW_OPTION_YES) {
- DBUG_RETURN(FALSE);
- }
-
trx = check_trx_exists(hton, thd);
innobase_release_stat_resources(trx);
@@ -6800,8 +6764,7 @@ ha_innobase::store_lock(
if (lock_type != TL_IGNORE
&& trx->n_mysql_tables_in_use == 0) {
trx->isolation_level = innobase_map_isolation_level(
- (enum_tx_isolation)
- thd->variables.tx_isolation);
+ (enum_tx_isolation)thd_tx_isolation(thd));
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
&& trx->global_read_view) {
@@ -6811,12 +6774,13 @@ ha_innobase::store_lock(
read_view_close_for_mysql(trx);
}
-
}
+ DBUG_ASSERT(thd == current_thd);
const bool in_lock_tables = thd_in_lock_tables(thd);
+ const uint sql_command = thd_sql_command(thd);
- if (thd->lex->sql_command == SQLCOM_DROP_TABLE) {
+ if (sql_command == SQLCOM_DROP_TABLE) {
/* MySQL calls this function in DROP TABLE though this table
handle may belong to another thd that is running a query. Let
@@ -6826,7 +6790,7 @@ ha_innobase::store_lock(
(lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) ||
lock_type == TL_READ_WITH_SHARED_LOCKS ||
lock_type == TL_READ_NO_INSERT ||
- (thd->lex->sql_command != SQLCOM_SELECT
+ (sql_command != SQLCOM_SELECT
&& lock_type != TL_IGNORE)) {
/* The OR cases above are in this order:
@@ -6855,9 +6819,9 @@ ha_innobase::store_lock(
|| isolation_level == TRX_ISO_READ_COMMITTED)
&& isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
- && (thd->lex->sql_command == SQLCOM_INSERT_SELECT
- || thd->lex->sql_command == SQLCOM_UPDATE
- || thd->lex->sql_command == SQLCOM_CREATE_TABLE)) {
+ && (sql_command == SQLCOM_INSERT_SELECT
+ || sql_command == SQLCOM_UPDATE
+ || sql_command == SQLCOM_CREATE_TABLE)) {
/* If we either have innobase_locks_unsafe_for_binlog
option set or this session is using READ COMMITTED
@@ -6870,7 +6834,7 @@ ha_innobase::store_lock(
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE;
- } else if (thd->lex->sql_command == SQLCOM_CHECKSUM) {
+ } else if (sql_command == SQLCOM_CHECKSUM) {
/* Use consistent read for checksum table */
prebuilt->select_lock_type = LOCK_NONE;
@@ -6900,7 +6864,7 @@ ha_innobase::store_lock(
(if it does not use a consistent read). */
if (lock_type == TL_READ
- && thd->lex->sql_command == SQLCOM_LOCK_TABLES) {
+ && sql_command == SQLCOM_LOCK_TABLES) {
/* We come here if MySQL is processing LOCK TABLES
... READ LOCAL. MyISAM under that table lock type
reads the table as it was at the time the lock was
@@ -6928,22 +6892,22 @@ ha_innobase::store_lock(
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
&& lock_type <= TL_WRITE)
&& !(in_lock_tables
- && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
+ && sql_command == SQLCOM_LOCK_TABLES)
&& !thd_tablespace_op(thd)
- && thd->lex->sql_command != SQLCOM_TRUNCATE
- && thd->lex->sql_command != SQLCOM_OPTIMIZE
+ && sql_command != SQLCOM_TRUNCATE
+ && sql_command != SQLCOM_OPTIMIZE
#ifdef __WIN__
- /* For alter table on win32 for succesful operation
- completion it is used TL_WRITE(=10) lock instead of
- TL_WRITE_ALLOW_READ(=6), however here in innodb handler
- TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes
- race condition when several clients do alter table
- simultaneously (bug #17264). This fix avoids the problem. */
- && thd->lex->sql_command != SQLCOM_ALTER_TABLE
+ /* For alter table on win32 for succesful operation
+ completion it is used TL_WRITE(=10) lock instead of
+ TL_WRITE_ALLOW_READ(=6), however here in innodb handler
+ TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes
+ race condition when several clients do alter table
+ simultaneously (bug #17264). This fix avoids the problem. */
+ && sql_command != SQLCOM_ALTER_TABLE
#endif
- && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
+ && sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE;
}
@@ -6956,10 +6920,10 @@ ha_innobase::store_lock(
We especially allow concurrent inserts if MySQL is at the
start of a stored procedure call (SQLCOM_CALL)
- (MySQL does have in_lock_tables TRUE there). */
+ (MySQL does have thd_in_lock_tables() TRUE there). */
if (lock_type == TL_READ_NO_INSERT
- && thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
+ && sql_command != SQLCOM_LOCK_TABLES) {
lock_type = TL_READ;
}
@@ -6994,7 +6958,7 @@ ha_innobase::innobase_read_and_init_auto_inc(
ut_a(prebuilt->table);
/* Prepare prebuilt->trx in the table handle */
- update_thd(current_thd);
+ update_thd(ha_thd());
if (prebuilt->trx->conc_state == TRX_NOT_STARTED) {
trx_was_not_started = TRUE;
@@ -7137,7 +7101,7 @@ void ha_innobase::get_auto_increment(
int error;
/* Prepare prebuilt->trx in the table handle */
- update_thd(current_thd);
+ update_thd(ha_thd());
error = innobase_read_and_init_auto_inc(&nr);
@@ -7166,7 +7130,7 @@ ha_innobase::reset_auto_increment(ulonglong value)
int error;
- update_thd(current_thd);
+ update_thd(ha_thd());
error = row_lock_table_autoinc_for_mysql(prebuilt);
@@ -7185,7 +7149,7 @@ ha_innobase::reset_auto_increment(ulonglong value)
bool
ha_innobase::get_error_message(int error, String *buf)
{
- trx_t* trx = check_trx_exists(ht, current_thd);
+ trx_t* trx = check_trx_exists(ht, ha_thd());
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
system_charset_info);
@@ -7401,6 +7365,7 @@ innobase_query_is_update(void)
/*==========================*/
{
THD* thd = current_thd;
+ trx_t* trx;
if (!thd) {
/* InnoDB's internal threads may run InnoDB stored procedures
@@ -7410,17 +7375,9 @@ innobase_query_is_update(void)
return(FALSE);
}
- switch (thd->lex->sql_command) {
- case SQLCOM_REPLACE:
- case SQLCOM_REPLACE_SELECT:
- return(TRUE);
- case SQLCOM_LOAD:
- return(thd->lex->duplicates == DUP_REPLACE);
- case SQLCOM_INSERT:
- return(thd->lex->duplicates == DUP_UPDATE);
- default:
- return(FALSE);
- }
+ trx = check_trx_exists(innodb_hton_ptr, thd);
+
+ return(trx->allow_duplicates);
}
/***********************************************************************
@@ -7439,8 +7396,8 @@ innobase_xa_prepare(
int error = 0;
trx_t* trx = check_trx_exists(hton, thd);
- if (thd->lex->sql_command != SQLCOM_XA_PREPARE &&
- (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))
+ if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
+ (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
/* For ibbackup to work the order of transactions in binlog
@@ -7466,7 +7423,7 @@ innobase_xa_prepare(
trx->active_trans = 2;
}
- if (!thd->variables.innodb_support_xa) {
+ if (!THDVAR(thd, support_xa)) {
return(0);
}
@@ -7486,7 +7443,7 @@ innobase_xa_prepare(
}
if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* We were instructed to prepare the whole transaction, or
this is an SQL statement end and autocommit is on */
@@ -7678,6 +7635,223 @@ static SHOW_VAR innodb_status_variables_export[]= {
static struct st_mysql_storage_engine innobase_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+/* plugin options */
+static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Enable InnoDB checksums validation (enabled by default). "
+ "Disable with --skip-innodb-checksums.",
+ NULL, NULL, TRUE);
+
+static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
+ PLUGIN_VAR_READONLY,
+ "The common part for InnoDB table spaces.",
+ NULL, NULL, NULL);
+
+static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Enable InnoDB doublewrite buffer (enabled by default). "
+ "Disable with --skip-innodb-doublewrite.",
+ NULL, NULL, TRUE);
+
+static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
+ PLUGIN_VAR_OPCMDARG,
+ "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, NULL, 1, 0, IF_NETWARE(1,2), 0);
+
+static MYSQL_SYSVAR_BOOL(file_per_table, innobase_file_per_table,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Stores each InnoDB table to an .ibd file in the database dir.",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
+ PLUGIN_VAR_OPCMDARG,
+ "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, NULL, 1, 0, 2, 0);
+
+static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "With which method to flush data.", NULL, NULL, NULL);
+
+static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Force InnoDB to not use next-key locking, to use only row-level locking.",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Where full logs should be archived.", NULL, NULL, NULL);
+
+#ifdef UNIV_LOG_ARCHIVE
+static MYSQL_SYSVAR_BOOL(log_archive, innobase_log_archive,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+ "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
+#endif /* UNIV_LOG_ARCHIVE */
+
+static MYSQL_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Path to InnoDB log files.", NULL, NULL, NULL);
+
+static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
+ PLUGIN_VAR_RQCMDARG,
+ "Percentage of dirty pages allowed in bufferpool.",
+ NULL, NULL, 90, 0, 100, 0);
+
+static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
+ PLUGIN_VAR_RQCMDARG,
+ "Desired maximum length of the purge queue (0 = no limit)",
+ NULL, NULL, 0, 0, ~0L, 0);
+
+static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
+ "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_BOOL(status_file, innobase_create_status_file,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
+ "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
+ NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
+ PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
+ "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
+ NULL, NULL, TRUE);
+
+static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
+ NULL, NULL, 1*1024*1024L, 512*1024L, ~0L, 1024);
+
+static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
+ PLUGIN_VAR_RQCMDARG,
+ "Data file autoextend increment in megabytes",
+ NULL, NULL, 8L, 1L, 1000L, 0);
+
+static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
+ NULL, NULL, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 1024*1024L);
+
+static MYSQL_SYSVAR_ULONG(commit_concurrency, srv_commit_concurrency,
+ PLUGIN_VAR_RQCMDARG,
+ "Helps in performance tuning in heavily concurrent environments.",
+ NULL, NULL, 0, 0, 1000, 0);
+
+static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
+ NULL, NULL, 500L, 1L, ~0L, 0);
+
+static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of file I/O threads in InnoDB.",
+ NULL, NULL, 4, 4, 64, 0);
+
+static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Helps to save your data in case the disk image of the database becomes corrupt.",
+ NULL, NULL, 0, 0, 6, 0);
+
+static MYSQL_SYSVAR_LONG(lock_wait_timeout, innobase_lock_wait_timeout,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.",
+ NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
+
+static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "The size of the buffer which InnoDB uses to write log to the log files on disk.",
+ NULL, NULL, 1024*1024L, 256*1024L, ~0L, 1024);
+
+static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Size of each log file in a log group.",
+ NULL, NULL, 5*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 1024*1024L);
+
+static MYSQL_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
+ NULL, NULL, 2, 2, 100, 0);
+
+static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
+ NULL, NULL, 1, 1, 10, 0);
+
+static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "How many files at the maximum InnoDB keeps open at the same time.",
+ NULL, NULL, 300L, 10L, ~0L, 0);
+
+static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
+ PLUGIN_VAR_RQCMDARG,
+ "Count of spin-loop rounds in InnoDB mutexes",
+ NULL, NULL, 20L, 0L, ~0L, 0);
+
+static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
+ PLUGIN_VAR_RQCMDARG,
+ "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, NULL, 8, 0, 1000, 0);
+
+static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
+ PLUGIN_VAR_RQCMDARG,
+ "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
+ NULL, NULL, 10000L, 0L, ~0L, 0);
+
+static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Path to individual files and their sizes.",
+ NULL, NULL, NULL);
+
+static struct st_mysql_sys_var* innobase_system_variables[]= {
+ MYSQL_SYSVAR(additional_mem_pool_size),
+ MYSQL_SYSVAR(autoextend_increment),
+ MYSQL_SYSVAR(buffer_pool_size),
+ MYSQL_SYSVAR(checksums),
+ MYSQL_SYSVAR(commit_concurrency),
+ MYSQL_SYSVAR(concurrency_tickets),
+ MYSQL_SYSVAR(data_file_path),
+ MYSQL_SYSVAR(data_home_dir),
+ MYSQL_SYSVAR(doublewrite),
+ MYSQL_SYSVAR(fast_shutdown),
+ MYSQL_SYSVAR(file_io_threads),
+ MYSQL_SYSVAR(file_per_table),
+ MYSQL_SYSVAR(flush_log_at_trx_commit),
+ MYSQL_SYSVAR(flush_method),
+ MYSQL_SYSVAR(force_recovery),
+ MYSQL_SYSVAR(locks_unsafe_for_binlog),
+ MYSQL_SYSVAR(lock_wait_timeout),
+ MYSQL_SYSVAR(log_arch_dir),
+#ifdef UNIV_LOG_ARCHIVE
+ MYSQL_SYSVAR(log_archive),
+#endif /* UNIV_LOG_ARCHIVE */
+ MYSQL_SYSVAR(log_buffer_size),
+ MYSQL_SYSVAR(log_file_size),
+ MYSQL_SYSVAR(log_files_in_group),
+ MYSQL_SYSVAR(log_group_home_dir),
+ MYSQL_SYSVAR(max_dirty_pages_pct),
+ MYSQL_SYSVAR(max_purge_lag),
+ MYSQL_SYSVAR(mirrored_log_groups),
+ MYSQL_SYSVAR(open_files),
+ MYSQL_SYSVAR(rollback_on_timeout),
+ MYSQL_SYSVAR(stats_on_metadata),
+ MYSQL_SYSVAR(status_file),
+ MYSQL_SYSVAR(support_xa),
+ MYSQL_SYSVAR(sync_spin_loops),
+ MYSQL_SYSVAR(table_locks),
+ MYSQL_SYSVAR(thread_concurrency),
+ MYSQL_SYSVAR(thread_sleep_delay),
+ NULL
+};
+
mysql_declare_plugin(innobase)
{
MYSQL_STORAGE_ENGINE_PLUGIN,
@@ -7690,8 +7864,8 @@ mysql_declare_plugin(innobase)
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
innodb_status_variables_export,/* status variables */
- NULL, /* system variables */
- NULL /* config options */
+ innobase_system_variables, /* system variables */
+ NULL /* reserved */
}
mysql_declare_plugin_end;
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f5df362b490..f2c01f71399 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -189,8 +189,6 @@ class ha_innobase: public handler
uint table_changes);
};
-extern ulong innobase_fast_shutdown;
-extern ulong innobase_large_page_size;
extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
extern longlong innobase_buffer_pool_size, innobase_log_file_size;
extern long innobase_log_buffer_size;
@@ -202,16 +200,6 @@ 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_rollback_on_timeout,
- innobase_create_status_file,
- innobase_stats_on_metadata;
extern "C" {
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index fe36b0d1a01..e75c200cc3a 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -499,6 +499,14 @@ struct trx_struct{
ulint mysql_process_no;/* since in Linux, 'top' reports
process id's and not thread id's, we
store the process number too */
+ ibool allow_duplicates;/* normally FALSE, but if the user
+ wants to update duplicate rows,
+ (in table inserts, for example) we
+ set this TRUE */
+ ibool replace_duplicates;/* normally FALSE, but if the user
+ wants to replace duplicate rows,
+ (in table inserts, for example) we
+ set this TRUE */
/*------------------------------*/
ulint n_mysql_tables_in_use; /* number of Innobase tables
used in the processing of the current
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index d31f5b7e792..298e3e6c433 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -694,10 +694,10 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
for (i= 0; i < table->s->keys; i++)
{
- struct st_plugin_int *parser= table->key_info[i].parser;
+ plugin_ref parser= table->key_info[i].parser;
if (table->key_info[i].flags & HA_USES_PARSER)
file->s->keyinfo[i].parser=
- (struct st_mysql_ftparser *)parser->plugin->info;
+ (struct st_mysql_ftparser *)plugin_decl(parser)->info;
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
}
my_errno= 0;
@@ -723,7 +723,7 @@ int ha_myisam::close(void)
int ha_myisam::write_row(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
/* If we have a timestamp column, update it to the current time */
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
@@ -1596,7 +1596,7 @@ bool ha_myisam::is_crashed() const
int ha_myisam::update_row(const byte * old_data, byte * new_data)
{
- statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
return mi_update(file,old_data,new_data);
@@ -1604,7 +1604,7 @@ int ha_myisam::update_row(const byte * old_data, byte * new_data)
int ha_myisam::delete_row(const byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_delete_count);
return mi_delete(file,buf);
}
@@ -1612,8 +1612,7 @@ int ha_myisam::index_read(byte *buf, const byte *key, key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1623,8 +1622,7 @@ int ha_myisam::index_read_idx(byte *buf, uint index, const byte *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1635,8 +1633,7 @@ int ha_myisam::index_read_last(byte *buf, const byte *key,
{
DBUG_ENTER("ha_myisam::index_read_last");
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=mi_rkey(file, buf, active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1646,8 +1643,7 @@ int ha_myisam::index_read_last(byte *buf, const byte *key,
int ha_myisam::index_next(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
int error=mi_rnext(file,buf,active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1656,8 +1652,7 @@ int ha_myisam::index_next(byte * buf)
int ha_myisam::index_prev(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_prev_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_prev_count);
int error=mi_rprev(file,buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1666,8 +1661,7 @@ int ha_myisam::index_prev(byte * buf)
int ha_myisam::index_first(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_first_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_first_count);
int error=mi_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1676,8 +1670,7 @@ int ha_myisam::index_first(byte * buf)
int ha_myisam::index_last(byte * buf)
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_last_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_last_count);
int error=mi_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1688,8 +1681,7 @@ int ha_myisam::index_next_same(byte * buf,
uint length __attribute__((unused)))
{
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
int error=mi_rnext_same(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1705,8 +1697,7 @@ int ha_myisam::rnd_init(bool scan)
int ha_myisam::rnd_next(byte *buf)
{
- statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=mi_scan(file, buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -1719,8 +1710,7 @@ int ha_myisam::restart_rnd_next(byte *buf, byte *pos)
int ha_myisam::rnd_pos(byte * buf, byte *pos)
{
- statistic_increment(table->in_use->status_var.ha_read_rnd_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_count);
int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 96f7db6e633..5df3e7799d0 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -148,7 +148,7 @@ int ha_myisammrg::close(void)
int ha_myisammrg::write_row(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_write_count);
if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
return (HA_ERR_TABLE_READONLY);
@@ -166,7 +166,7 @@ int ha_myisammrg::write_row(byte * buf)
int ha_myisammrg::update_row(const byte * old_data, byte * new_data)
{
- statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
return myrg_update(file,old_data,new_data);
@@ -174,7 +174,7 @@ int ha_myisammrg::update_row(const byte * old_data, byte * new_data)
int ha_myisammrg::delete_row(const byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
+ ha_statistic_increment(&SSV::ha_delete_count);
return myrg_delete(file,buf);
}
@@ -182,8 +182,7 @@ int ha_myisammrg::index_read(byte * buf, const byte * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=myrg_rkey(file,buf,active_index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -193,8 +192,7 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=myrg_rkey(file,buf,index, key, keypart_map, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -203,8 +201,7 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key,
int ha_myisammrg::index_read_last(byte * buf, const byte * key,
key_part_map keypart_map)
{
- statistic_increment(table->in_use->status_var.ha_read_key_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_key_count);
int error=myrg_rkey(file,buf,active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -213,8 +210,7 @@ int ha_myisammrg::index_read_last(byte * buf, const byte * key,
int ha_myisammrg::index_next(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
int error=myrg_rnext(file,buf,active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -222,8 +218,7 @@ int ha_myisammrg::index_next(byte * buf)
int ha_myisammrg::index_prev(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_read_prev_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_prev_count);
int error=myrg_rprev(file,buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -231,8 +226,7 @@ int ha_myisammrg::index_prev(byte * buf)
int ha_myisammrg::index_first(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_read_first_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_first_count);
int error=myrg_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -240,8 +234,7 @@ int ha_myisammrg::index_first(byte * buf)
int ha_myisammrg::index_last(byte * buf)
{
- statistic_increment(table->in_use->status_var.ha_read_last_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_last_count);
int error=myrg_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -251,8 +244,7 @@ int ha_myisammrg::index_next_same(byte * buf,
const byte *key __attribute__((unused)),
uint length __attribute__((unused)))
{
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_next_count);
int error=myrg_rnext_same(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -267,8 +259,7 @@ int ha_myisammrg::rnd_init(bool scan)
int ha_myisammrg::rnd_next(byte *buf)
{
- statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=myrg_rrnd(file, buf, HA_OFFSET_ERROR);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -277,8 +268,7 @@ int ha_myisammrg::rnd_next(byte *buf)
int ha_myisammrg::rnd_pos(byte * buf, byte *pos)
{
- statistic_increment(table->in_use->status_var.ha_read_rnd_count,
- &LOCK_status);
+ ha_statistic_increment(&SSV::ha_read_rnd_count);
int error=myrg_rrnd(file, buf, my_get_ptr(pos,ref_length));
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -615,7 +605,6 @@ static int myisammrg_init(void *p)
myisammrg_hton= (handlerton *)p;
- myisammrg_hton->state= SHOW_OPTION_YES;
myisammrg_hton->db_type= DB_TYPE_MRG_MYISAM;
myisammrg_hton->create= myisammrg_create_handler;
myisammrg_hton->panic= myisammrg_panic;
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
index 94768e6ae52..c1bfdee9342 100644
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -612,10 +612,11 @@ static
my_bool
parse_mycnf_opt(int, const struct my_option * opt, char * value)
{
+ long *app_type= (long*) &opt->app_type;
if(opt->comment)
- ((struct my_option *)opt)->app_type++;
+ (*app_type)++;
else
- ((struct my_option *)opt)->app_type = order++;
+ *app_type = order++;
return 0;
}
@@ -948,22 +949,6 @@ end:
template class Vector<struct my_option>;
-#if 0
-struct my_option
-{
- const char *name; /* Name of the option */
- int id; /* unique id or short option */
- const char *comment; /* option comment, for autom. --help */
- gptr *value; /* The variable value */
- gptr *u_max_value; /* The user def. max variable value */
- const char **str_values; /* Pointer to possible values */
- ulong var_type;
- enum get_opt_arg_type arg_type;
- longlong def_value; /* Default value */
- longlong min_value; /* Min allowed value */
- 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 */
-};
-#endif
+/*
+ See include/my_getopt.h for the declaration of struct my_option
+*/