summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mysql.com>2009-12-22 10:35:56 +0100
committerSergei Golubchik <serg@mysql.com>2009-12-22 10:35:56 +0100
commit1ad5bb1a69656808312efc40ca12c4897f8ea128 (patch)
treeffef2f9db240392c7f322d05058dfd7ea8c01a9d /sql
parent22c65346986d63c906e1d5a57941cadc367c2a9f (diff)
downloadmariadb-git-1ad5bb1a69656808312efc40ca12c4897f8ea128.tar.gz
WL#4738 streamline/simplify @@variable creation process
Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables Bug#20415 Output of mysqld --help --verbose is incomplete Bug#25430 variable not found in SELECT @@global.ft_max_word_len; Bug#32902 plugin variables don't know their names Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#34829 No default value for variable and setting default does not raise error Bug#34834 ? Is accepted as a valid sql mode Bug#34878 Few variables have default value according to documentation but error occurs Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var. Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status Bug#40988 log_output_basic.test succeeded though syntactically false. Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails) Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#44797 plugins w/o command-line options have no disabling option in --help Bug#46314 string system variables don't support expressions Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds Bug#49417 some complaints about mysqld --help --verbose output Bug#49540 DEFAULT value of binlog_format isn't the default value Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters Bug#49646 mysql --show-warnings crashes when server dies CMakeLists.txt: Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled client/mysql.cc: don't crash with --show-warnings when mysqld dies config/ac-macros/plugins.m4: Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled include/my_getopt.h: comments include/my_pthread.h: fix double #define mysql-test/mysql-test-run.pl: run sys_vars suite by default properly recognize envirinment variables (e.g. MTR_MAX_SAVE_CORE) set to 0 escape gdb command line arguments mysql-test/suite/sys_vars/r/rpl_init_slave_func.result: init_slave+utf8 bug mysql-test/suite/sys_vars/t/rpl_init_slave_func.test: init_slave+utf8 bug mysys/my_getopt.c: Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) mysys/typelib.c: support for flagset sql/ha_ndbcluster.cc: backport from telco tree sql/item_func.cc: Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters sql/sql_builtin.cc.in: Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled sql/sql_plugin.cc: Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#32902 plugin variables don't know their names Bug#44797 plugins w/o command-line options have no disabling option in --help sql/sys_vars.cc: all server variables are defined here storage/myisam/ft_parser.c: remove unnecessary updates of param->quot storage/myisam/ha_myisam.cc: myisam_* variables belong here strings/my_vsnprintf.c: %o and %llx unittest/mysys/my_vsnprintf-t.c: %o and %llx tests vio/viosocket.c: bugfix: fix @@wait_timeout to work with socket timeouts (vs. alarm thread)
Diffstat (limited to 'sql')
-rw-r--r--[-rwxr-xr-x]sql/CMakeLists.txt4
-rw-r--r--sql/Makefile.am8
-rw-r--r--sql/debug_sync.cc84
-rw-r--r--sql/event_scheduler.cc2
-rw-r--r--sql/events.cc159
-rw-r--r--sql/events.h36
-rw-r--r--sql/ha_ndbcluster.cc407
-rw-r--r--sql/ha_ndbcluster.h6
-rw-r--r--sql/ha_ndbcluster_binlog.cc80
-rw-r--r--sql/ha_ndbcluster_binlog.h2
-rw-r--r--sql/ha_partition.cc6
-rw-r--r--sql/handler.cc13
-rw-r--r--sql/handler.h7
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/item_func.cc63
-rw-r--r--sql/item_sum.cc6
-rw-r--r--sql/item_timefunc.h2
-rw-r--r--sql/keycaches.cc163
-rw-r--r--sql/keycaches.h41
-rw-r--r--sql/log.cc58
-rw-r--r--sql/log.h21
-rw-r--r--sql/log_event.cc66
-rw-r--r--sql/log_event_old.cc30
-rw-r--r--sql/mysql_priv.h195
-rw-r--r--sql/mysqld.cc2332
-rw-r--r--sql/opt_range.cc16
-rw-r--r--sql/repl_failsafe.cc7
-rw-r--r--sql/repl_failsafe.h4
-rw-r--r--sql/rpl_record.cc1
-rw-r--r--sql/rpl_rli.cc8
-rw-r--r--sql/rpl_rli.h3
-rw-r--r--sql/set_var.cc4231
-rw-r--r--sql/set_var.h1499
-rw-r--r--sql/share/errmsg-utf8.txt8
-rw-r--r--sql/share/errmsg.txt8
-rw-r--r--sql/slave.cc19
-rw-r--r--sql/slave.h1
-rw-r--r--sql/sp_head.cc20
-rw-r--r--sql/sql_acl.cc25
-rw-r--r--sql/sql_acl.h1
-rw-r--r--sql/sql_base.cc22
-rw-r--r--sql/sql_builtin.cc.in12
-rw-r--r--sql/sql_cache.cc23
-rw-r--r--sql/sql_cache.h1
-rw-r--r--sql/sql_class.cc60
-rw-r--r--sql/sql_class.h61
-rw-r--r--sql/sql_connect.cc15
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_derived.cc4
-rw-r--r--sql/sql_insert.cc6
-rw-r--r--sql/sql_lex.h14
-rw-r--r--sql/sql_parse.cc96
-rw-r--r--sql/sql_partition.cc12
-rw-r--r--sql/sql_plugin.cc649
-rw-r--r--sql/sql_plugin.h7
-rw-r--r--sql/sql_prepare.cc1
-rw-r--r--sql/sql_profile.cc4
-rw-r--r--sql/sql_repl.cc151
-rw-r--r--sql/sql_select.cc48
-rw-r--r--sql/sql_select.h4
-rw-r--r--sql/sql_show.cc26
-rw-r--r--sql/sql_table.cc44
-rw-r--r--sql/sql_test.cc7
-rw-r--r--sql/sql_union.cc8
-rw-r--r--sql/sql_update.cc19
-rw-r--r--sql/sql_view.cc9
-rw-r--r--sql/sql_yacc.yy11
-rw-r--r--sql/strfunc.cc263
-rw-r--r--sql/structs.h2
-rw-r--r--sql/sys_vars.cc2738
-rw-r--r--sql/sys_vars.h1600
-rw-r--r--sql/sys_vars_shared.h81
-rw-r--r--sql/table.cc6
-rw-r--r--sql/tztime.cc4
-rw-r--r--sql/unireg.h4
77 files changed, 6782 insertions, 8882 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 15c2d950ff9..82a94b64365 100755..100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -53,7 +53,7 @@ SET (SQL_SOURCE
log_event.cc rpl_record.cc rpl_reporting.cc
log_event_old.cc rpl_record_old.cc
message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
- mysqld.cc net_serv.cc
+ mysqld.cc net_serv.cc keycaches.cc
nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc
../sql-common/pack.c parse_file.cc password.c procedure.cc
protocol.cc records.cc repl_failsafe.cc rpl_filter.cc set_var.cc
@@ -76,7 +76,7 @@ SET (SQL_SOURCE
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc
- sql_signal.cc rpl_handler.cc
+ sql_signal.cc rpl_handler.cc sys_vars.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 15ee0d588c4..5f8bc8ef112 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -101,9 +101,9 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_repl.h slave.h rpl_filter.h rpl_injector.h \
log_event.h rpl_record.h \
log_event_old.h rpl_record_old.h \
- sql_sort.h sql_cache.h set_var.h \
+ sql_sort.h sql_cache.h set_var.h sys_vars_shared.h \
spatial.h gstream.h client_settings.h tzfile.h \
- tztime.h my_decimal.h\
+ tztime.h my_decimal.h keycaches.h \
sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
parse_file.h sql_view.h sql_trigger.h \
sql_array.h sql_cursor.h events.h scheduler.h \
@@ -112,7 +112,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
contributors.h sql_servers.h sql_signal.h records.h \
- sql_prepare.h rpl_handler.h replication.h
+ sql_prepare.h rpl_handler.h replication.h sys_vars.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -125,7 +125,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
sql_string.cc sql_manager.cc sql_map.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \
sql_connect.cc scheduler.cc sql_parse.cc \
- set_var.cc sql_yacc.yy \
+ keycaches.cc set_var.cc sql_yacc.yy sys_vars.cc \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
sql_profile.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 3c8e24f6901..517aab93707 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1561,56 +1561,6 @@ static bool debug_sync_eval_action(THD *thd, char *action_str)
DBUG_RETURN(FALSE);
}
-
-/**
- Check if the system variable 'debug_sync' can be set.
-
- @param[in] thd thread handle
- @param[in] var set variable request
-
- @return status
- @retval FALSE ok, variable can be set
- @retval TRUE error, variable cannot be set
-*/
-
-bool sys_var_debug_sync::check(THD *thd, set_var *var)
-{
- DBUG_ENTER("sys_var_debug_sync::check");
- DBUG_ASSERT(thd);
- DBUG_ASSERT(var);
-
- /*
- Variable can be set for the session only.
-
- This could be changed later. Then we need to have a global array of
- actions in addition to the thread local ones. SET GLOBAL would
- manage the global array, SET [SESSION] the local array. A sync point
- would need to look for a local and a global action. Setting and
- executing of global actions need to be protected by a mutex.
-
- The purpose of global actions could be to allow synchronizing with
- connectionless threads that cannot execute SET statements.
- */
- if (var->type == OPT_GLOBAL)
- {
- my_error(ER_LOCAL_VARIABLE, MYF(0), name);
- DBUG_RETURN(TRUE);
- }
-
- /*
- Do not check for disabled facility. Test result should not
- unnecessarily differ from enabled facility.
- */
-
- /*
- Facility requires SUPER privilege. Sync points could be inside
- global mutexes (e.g. LOCK_open). Waiting there forever would
- stall the whole server.
- */
- DBUG_RETURN(check_global_access(thd, SUPER_ACL));
-}
-
-
/**
Set the system variable 'debug_sync'.
@@ -1631,28 +1581,9 @@ bool sys_var_debug_sync::check(THD *thd, set_var *var)
terminators in the string. So we need to take a copy here.
*/
-bool sys_var_debug_sync::update(THD *thd, set_var *var)
+bool debug_sync_update(THD *thd, char *val_str)
{
- char *val_str;
- String *val_ptr;
- String val_buf;
- DBUG_ENTER("sys_var_debug_sync::update");
- DBUG_ASSERT(thd);
-
- /*
- Depending on the value type (string literal, user variable, ...)
- val_buf receives a copy of the value or not. But we always need
- a copy. So we take a copy, if it is not done by val_str().
- If val_str() puts a copy into val_buf, then it returns &val_buf,
- otherwise it returns a pointer to the string object that we need
- to copy.
- */
- val_ptr= var ? var->value->val_str(&val_buf) : &val_buf;
- if (val_ptr != &val_buf)
- {
- val_buf.copy(*val_ptr);
- }
- val_str= val_buf.c_ptr();
+ DBUG_ENTER("debug_sync_update");
DBUG_PRINT("debug_sync", ("set action: '%s'", val_str));
/*
@@ -1669,8 +1600,6 @@ bool sys_var_debug_sync::update(THD *thd, set_var *var)
Retrieve the value of the system variable 'debug_sync'.
@param[in] thd thread handle
- @param[in] type variable type, unused
- @param[in] base variable base, unused
@return string
@retval != NULL ok, string pointer
@@ -1683,13 +1612,10 @@ bool sys_var_debug_sync::update(THD *thd, set_var *var)
When "ON", the current signal is added.
*/
-uchar *sys_var_debug_sync::value_ptr(THD *thd,
- enum_var_type type __attribute__((unused)),
- LEX_STRING *base __attribute__((unused)))
+uchar *debug_sync_value_ptr(THD *thd)
{
char *value;
- DBUG_ENTER("sys_var_debug_sync::value_ptr");
- DBUG_ASSERT(thd);
+ DBUG_ENTER("debug_sync_value_ptr");
if (opt_debug_sync_timeout)
{
@@ -1718,7 +1644,7 @@ uchar *sys_var_debug_sync::value_ptr(THD *thd,
else
{
/* purecov: begin tested */
- value= strmake_root(thd->mem_root, STRING_WITH_LEN("OFF"));
+ value= const_cast<char*>("OFF");
/* purecov: end */
}
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 31bb3d39b85..00d03e04b70 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -188,7 +188,7 @@ pre_init_event_thread(THD* thd)
thd->security_ctx->set_user((char*)"event_scheduler");
thd->net.read_timeout= slave_net_timeout;
thd->slave_thread= 0;
- thd->options|= OPTION_AUTO_IS_NULL;
+ thd->variables.option_bits|= OPTION_AUTO_IS_NULL;
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
diff --git a/sql/events.cc b/sql/events.cc
index f5f837930c0..b0803ab57d0 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -20,6 +20,7 @@
#include "event_queue.h"
#include "event_scheduler.h"
#include "sp_head.h" // for Stored_program_creation_ctx
+#include "set_var.h"
/**
@addtogroup Event_Scheduler
@@ -63,43 +64,10 @@
eligible for execution.
*/
-/*
- Keep the order of the first to as in var_typelib
- sys_var_event_scheduler::value_ptr() references this array. Keep in
- mind!
-*/
-static const char *opt_event_scheduler_state_names[]=
- { "OFF", "ON", "0", "1", "DISABLED", NullS };
-
-const TYPELIB Events::opt_typelib=
-{
- array_elements(opt_event_scheduler_state_names)-1,
- "",
- opt_event_scheduler_state_names,
- NULL
-};
-
-
-/*
- The order should not be changed. We consider OFF to be equivalent of INT 0
- And ON of 1. If OFF & ON are interchanged the logic in
- sys_var_event_scheduler::update() will be broken!
-*/
-static const char *var_event_scheduler_state_names[]= { "OFF", "ON", NullS };
-
-const TYPELIB Events::var_typelib=
-{
- array_elements(var_event_scheduler_state_names)-1,
- "",
- var_event_scheduler_state_names,
- NULL
-};
-
Event_queue *Events::event_queue;
Event_scheduler *Events::scheduler;
Event_db_repository *Events::db_repository;
-enum Events::enum_opt_event_scheduler
-Events::opt_event_scheduler= Events::EVENTS_OFF;
+uint Events::opt_event_scheduler= Events::EVENTS_OFF;
pthread_mutex_t Events::LOCK_event_metadata;
bool Events::check_system_tables_error= FALSE;
@@ -127,69 +95,6 @@ int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
/**
- @brief Initialize the start up option of the Events scheduler.
-
- Do not initialize the scheduler subsystem yet - the initialization
- is split into steps as it has to fit into the common MySQL
- initialization framework.
- No locking as this is called only at start up.
-
- @param[in,out] argument The value of the argument. If this value
- is found in the typelib, the argument is
- updated.
-
- @retval TRUE unknown option value
- @retval FALSE success
-*/
-
-bool
-Events::set_opt_event_scheduler(char *argument)
-{
- if (argument == NULL)
- opt_event_scheduler= Events::EVENTS_ON;
- else
- {
- int type;
- /*
- type= 1 2 3 4 5
- (OFF | ON) - (0 | 1) (DISABLE )
- */
- const static enum enum_opt_event_scheduler type2state[]=
- { EVENTS_OFF, EVENTS_ON, EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED };
-
- type= find_type(argument, &opt_typelib, 1);
-
- DBUG_ASSERT(type >= 0 && type <= 5); /* guaranteed by find_type */
-
- if (type == 0)
- {
- fprintf(stderr, "Unknown option to event-scheduler: %s\n", argument);
- return TRUE;
- }
- opt_event_scheduler= type2state[type-1];
- }
- return FALSE;
-}
-
-
-/**
- Return a string representation of the current scheduler mode.
-*/
-
-const char *
-Events::get_opt_event_scheduler_str()
-{
- const char *str;
-
- pthread_mutex_lock(&LOCK_event_metadata);
- str= opt_typelib.type_names[(int) opt_event_scheduler];
- pthread_mutex_unlock(&LOCK_event_metadata);
-
- return str;
-}
-
-
-/**
Push an error into the error stack if the system tables are
not up to date.
*/
@@ -734,8 +639,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol)
field_list.push_back(new Item_empty_string("Event", NAME_CHAR_LEN));
- if (sys_var_thd_sql_mode::symbolic_mode_representation(thd, et->sql_mode,
- &sql_mode))
+ if (sql_mode_string_representation(thd, et->sql_mode, &sql_mode))
DBUG_RETURN(TRUE);
field_list.push_back(new Item_empty_string("sql_mode", (uint) sql_mode.length));
@@ -1091,60 +995,15 @@ Events::dump_internal_status()
DBUG_VOID_RETURN;
}
-
-/**
- Starts or stops the event scheduler thread.
-
- @retval FALSE success
- @retval TRUE error
-*/
-
-bool
-Events::switch_event_scheduler_state(enum_opt_event_scheduler new_state)
+bool Events::start()
{
- bool ret= FALSE;
-
- DBUG_ENTER("Events::switch_event_scheduler_state");
-
- DBUG_ASSERT(new_state == Events::EVENTS_ON ||
- new_state == Events::EVENTS_OFF);
-
- /*
- If the scheduler was disabled because there are no/bad
- system tables, produce a more meaningful error message
- than ER_OPTION_PREVENTS_STATEMENT
- */
- if (check_if_system_tables_error())
- DBUG_RETURN(TRUE);
-
- pthread_mutex_lock(&LOCK_event_metadata);
-
- if (opt_event_scheduler == EVENTS_DISABLED)
- {
- my_error(ER_OPTION_PREVENTS_STATEMENT,
- MYF(0), "--event-scheduler=DISABLED or --skip-grant-tables");
- ret= TRUE;
- goto end;
- }
-
- if (new_state == EVENTS_ON)
- ret= scheduler->start();
- else
- ret= scheduler->stop();
-
- if (ret)
- {
- my_error(ER_EVENT_SET_VAR_ERROR, MYF(0));
- goto end;
- }
-
- opt_event_scheduler= new_state;
-
-end:
- pthread_mutex_unlock(&LOCK_event_metadata);
- DBUG_RETURN(ret);
+ return scheduler->start();
}
+bool Events::stop()
+{
+ return scheduler->stop();
+}
/**
Loads all ENABLED events from mysql.event into a prioritized
diff --git a/sql/events.h b/sql/events.h
index 2bc87517748..8f68d5a8029 100644
--- a/sql/events.h
+++ b/sql/events.h
@@ -56,7 +56,7 @@ sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
The life cycle of the Events module is the following:
At server start up:
- set_opt_event_scheduler() -> init_mutexes() -> init()
+ init_mutexes() -> init()
When the server is running:
create_event(), drop_event(), start_or_stop_event_scheduler(), etc
At shutdown:
@@ -70,23 +70,19 @@ sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
class Events
{
public:
- /* The order should match the order in opt_typelib */
- enum enum_opt_event_scheduler
- {
- EVENTS_OFF= 0,
- EVENTS_ON= 1,
- EVENTS_DISABLED= 4
- };
-
- /* Possible values of @@event_scheduler variable */
- static const TYPELIB var_typelib;
-
- static bool
- set_opt_event_scheduler(char *argument);
-
- static const char *
- get_opt_event_scheduler_str();
+ /*
+ the following block is to support --event-scheduler command line option
+ and the @@global.event_scheduler SQL variable.
+ See sys_var.cc
+ */
+ enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED };
+ static uint opt_event_scheduler;
+ static pthread_mutex_t LOCK_event_metadata;
+ static bool check_if_system_tables_error();
+ static bool start();
+ static bool stop();
+public:
/* A hack needed for Event_queue_element */
static Event_db_repository *
get_db_repository() { return db_repository; }
@@ -134,20 +130,14 @@ public:
dump_internal_status();
private:
- static bool check_if_system_tables_error();
static bool
load_events_from_db(THD *thd);
private:
- /* Command line option names */
- static const TYPELIB opt_typelib;
- static pthread_mutex_t LOCK_event_metadata;
static Event_queue *event_queue;
static Event_scheduler *scheduler;
static Event_db_repository *db_repository;
- /* Current state of Event Scheduler */
- static enum enum_opt_event_scheduler opt_event_scheduler;
/* Set to TRUE if an error at start up */
static bool check_system_tables_error;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 1103683b56c..b820b6d939d 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -56,26 +56,125 @@ int ha_ndb_dummy;
#define assert(x) do { if(x) break; ::printf("%s %d: assert failed: %s\n", __FILE__, __LINE__, #x); ::fflush(stdout); ::signal(SIGABRT,SIG_DFL); ::abort(); ::kill(::getpid(),6); ::kill(::getpid(),9); } while (0)
#endif
-// options from from mysqld.cc
-extern my_bool opt_ndb_optimized_node_selection;
-extern const char *opt_ndbcluster_connectstring;
-extern ulong opt_ndb_cache_check_time;
-
-// ndb interface initialization/cleanup
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern void ndb_init_internal();
-extern void ndb_end_internal();
-#ifdef __cplusplus
-}
-#endif
-
-const char *ndb_distribution_names[]= {"KEYHASH", "LINHASH", NullS};
-TYPELIB ndb_distribution_typelib= { array_elements(ndb_distribution_names)-1,
- "", ndb_distribution_names, NULL };
-const char *opt_ndb_distribution= ndb_distribution_names[ND_KEYHASH];
-enum ndb_distribution opt_ndb_distribution_id= ND_KEYHASH;
+// ndb interface initialization/cleanup functions
+extern "C" void ndb_init_internal();
+extern "C" void ndb_end_internal();
+
+static const int DEFAULT_PARALLELISM= 0;
+static const ha_rows DEFAULT_AUTO_PREFETCH= 32;
+static const ulong ONE_YEAR_IN_SECONDS= (ulong) 3600L*24L*365L;
+
+ulong opt_ndb_extra_logging;
+static ulong opt_ndb_cache_check_time;
+static char* opt_ndb_connectstring;
+static char* opt_ndb_mgmd_host;
+static uint opt_ndb_nodeid;
+
+
+static MYSQL_THDVAR_UINT(
+ autoincrement_prefetch_sz, /* name */
+ PLUGIN_VAR_RQCMDARG,
+ "Specify number of autoincrement values that are prefetched.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 1, /* default */
+ 1, /* min */
+ 256, /* max */
+ 0 /* block */
+);
+
+
+static MYSQL_THDVAR_BOOL(
+ force_send, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Force send of buffers to ndb immediately without waiting for "
+ "other threads.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 1 /* default */
+);
+
+
+static MYSQL_THDVAR_BOOL(
+ use_exact_count, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Use exact records count during query planning and for fast "
+ "select count(*), disable for faster queries.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 1 /* default */
+);
+
+
+static MYSQL_THDVAR_BOOL(
+ use_transactions, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Use transactions for large inserts, if enabled then large "
+ "inserts will be split into several smaller transactions",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 1 /* default */
+);
+
+
+static MYSQL_THDVAR_BOOL(
+ use_copying_alter_table, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Force ndbcluster to always copy tables at alter table (should "
+ "only be used if on-line alter table fails).",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 0 /* default */
+);
+
+
+static MYSQL_THDVAR_UINT(
+ optimized_node_selection, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Select nodes for transactions in a more optimal way.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 3, /* default */
+ 0, /* min */
+ 3, /* max */
+ 0 /* block */
+);
+
+
+static MYSQL_THDVAR_BOOL(
+ index_stat_enable, /* name */
+ PLUGIN_VAR_OPCMDARG,
+ "Use ndb index statistics in query optimization.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ FALSE /* default */
+);
+
+
+static MYSQL_THDVAR_ULONG(
+ index_stat_cache_entries, /* name */
+ PLUGIN_VAR_NOCMDARG,
+ "",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 32, /* default */
+ 0, /* min */
+ ULONG_MAX, /* max */
+ 0 /* block */
+);
+
+
+static MYSQL_THDVAR_ULONG(
+ index_stat_update_freq, /* name */
+ PLUGIN_VAR_NOCMDARG,
+ "",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 20, /* default */
+ 0, /* min */
+ ULONG_MAX, /* max */
+ 0 /* block */
+);
// Default value for parallelism
static const int parallelism= 0;
@@ -186,7 +285,6 @@ pthread_mutex_t LOCK_ndb_util_thread;
pthread_cond_t COND_ndb_util_thread;
pthread_cond_t COND_ndb_util_ready;
pthread_handler_t ndb_util_thread_func(void *arg);
-ulong ndb_cache_check_time;
/**
Dummy buffer to read zero pack_length fields
@@ -321,7 +419,7 @@ int execute_commit(THD *thd, NdbTransaction *trans)
{
return trans->execute(NdbTransaction::Commit,
NdbOperation::AbortOnError,
- thd->variables.ndb_force_send);
+ THDVAR(thd, force_send));
}
inline
@@ -1250,11 +1348,11 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
NDB_INDEX_DATA& d=m_index[index_no];
delete d.index_stat;
d.index_stat=NULL;
- if (thd->variables.ndb_index_stat_enable)
+ if (THDVAR(thd, index_stat_enable))
{
d.index_stat=new NdbIndexStat(index);
- d.index_stat_cache_entries=thd->variables.ndb_index_stat_cache_entries;
- d.index_stat_update_freq=thd->variables.ndb_index_stat_update_freq;
+ d.index_stat_cache_entries=THDVAR(thd, index_stat_cache_entries);
+ d.index_stat_update_freq=THDVAR(thd, index_stat_update_freq);
d.index_stat_query_count=0;
d.index_stat->alloc_cache(d.index_stat_cache_entries);
DBUG_PRINT("info", ("index %s stat=on cache_entries=%u update_freq=%u",
@@ -1314,10 +1412,12 @@ int ha_ndbcluster::open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error)
for (i= 0; i < tab->s->keys; i++, key_info++, key_name++)
{
if ((error= add_index_handle(thd, dict, key_info, *key_name, i)))
+ {
if (ignore_error)
m_index[i].index= m_index[i].unique_index= NULL;
else
break;
+ }
m_index[i].null_in_unique_index= FALSE;
if (check_index_fields_not_null(key_info))
m_index[i].null_in_unique_index= TRUE;
@@ -4082,7 +4182,7 @@ int ha_ndbcluster::info(uint flag)
{
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
}
- if (current_thd->variables.ndb_use_exact_count &&
+ if (THDVAR(current_thd, use_exact_count) &&
(result= ndb_get_table_statistics(this, TRUE, ndb, m_table, &stat))
== 0)
{
@@ -4412,12 +4512,12 @@ THR_LOCK_DATA **ha_ndbcluster::store_lock(THD *thd,
#ifndef DBUG_OFF
#define PRINT_OPTION_FLAGS(t) { \
- if (t->options & OPTION_NOT_AUTOCOMMIT) \
- DBUG_PRINT("thd->options", ("OPTION_NOT_AUTOCOMMIT")); \
- if (t->options & OPTION_BEGIN) \
- DBUG_PRINT("thd->options", ("OPTION_BEGIN")); \
- if (t->options & OPTION_TABLE_LOCK) \
- DBUG_PRINT("thd->options", ("OPTION_TABLE_LOCK")); \
+ if (t->variables.option_bits & OPTION_NOT_AUTOCOMMIT) \
+ DBUG_PRINT("thd->variables.option_bits", ("OPTION_NOT_AUTOCOMMIT")); \
+ if (t->variables.option_bits & OPTION_BEGIN) \
+ DBUG_PRINT("thd->variables.option_bits", ("OPTION_BEGIN")); \
+ if (t->variables.option_bits & OPTION_TABLE_LOCK) \
+ DBUG_PRINT("thd->variables.option_bits", ("OPTION_TABLE_LOCK")); \
}
#else
#define PRINT_OPTION_FLAGS(t)
@@ -4504,7 +4604,7 @@ void ha_ndbcluster::transaction_checks(THD *thd)
else if (!thd->transaction.on)
m_transaction_on= FALSE;
else
- m_transaction_on= thd->variables.ndb_use_transactions;
+ m_transaction_on= THDVAR(thd, use_transactions);
}
int ha_ndbcluster::start_statement(THD *thd,
@@ -4517,7 +4617,7 @@ int ha_ndbcluster::start_statement(THD *thd,
trans_register_ha(thd, FALSE, ndbcluster_hton);
if (!thd_ndb->trans)
{
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ if (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(thd, TRUE, ndbcluster_hton);
DBUG_PRINT("trans",("Starting transaction"));
thd_ndb->trans= ndb->startTransaction();
@@ -4527,7 +4627,7 @@ int ha_ndbcluster::start_statement(THD *thd,
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
- if (!(thd->options & OPTION_BIN_LOG) ||
+ if (!(thd->variables.option_bits & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
@@ -4542,7 +4642,7 @@ int ha_ndbcluster::start_statement(THD *thd,
Check if it should be read or write lock
*/
- if (thd->options & (OPTION_TABLE_LOCK))
+ if (thd->variables.option_bits & OPTION_TABLE_LOCK)
{
//lockThisTable();
DBUG_PRINT("info", ("Locking the table..." ));
@@ -4566,13 +4666,13 @@ int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb)
DBUG_ENTER("ha_ndbcluster::init_handler_for_statement");
// store thread specific data first to set the right context
- m_force_send= thd->variables.ndb_force_send;
- m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
+ m_force_send= THDVAR(thd, force_send);
+ m_ha_not_exact_count= !THDVAR(thd, use_exact_count);
m_autoincrement_prefetch=
- (thd->variables.ndb_autoincrement_prefetch_sz >
- NDB_DEFAULT_AUTO_PREFETCH) ?
- (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz
- : (ha_rows) NDB_DEFAULT_AUTO_PREFETCH;
+ (THDVAR(thd, autoincrement_prefetch_sz) >
+ DEFAULT_AUTO_PREFETCH) ?
+ (ha_rows) THDVAR(thd, autoincrement_prefetch_sz)
+ : (ha_rows) DEFAULT_AUTO_PREFETCH;
m_active_trans= thd_ndb->trans;
DBUG_ASSERT(m_active_trans);
// Start of transaction
@@ -4587,7 +4687,7 @@ int ha_ndbcluster::init_handler_for_statement(THD *thd, Thd_ndb *thd_ndb)
}
#endif
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ if (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
const void *key= m_table;
HASH_SEARCH_STATE state;
@@ -4668,10 +4768,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{
DBUG_PRINT("info", ("lock_type == F_UNLCK"));
- if (ndb_cache_check_time && m_rows_changed)
+ if (opt_ndb_cache_check_time && m_rows_changed)
{
DBUG_PRINT("info", ("Rows has changed and util thread is running"));
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ if (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
DBUG_PRINT("info", ("Add share to list of tables to be invalidated"));
/* NOTE push_back allocates memory using transactions mem_root! */
@@ -4690,7 +4790,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("trans", ("Last external_lock"));
PRINT_OPTION_FLAGS(thd);
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ if (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
if (thd_ndb->trans)
{
@@ -4801,7 +4901,7 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
DBUG_PRINT("enter", ("Commit %s", (all ? "all" : "stmt")));
thd_ndb->start_stmt_count= 0;
if (trans == NULL || (!all &&
- thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
/*
An odditity in the handler interface is that commit on handlerton
@@ -4871,7 +4971,7 @@ static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
DBUG_ASSERT(ndb);
thd_ndb->start_stmt_count= 0;
if (trans == NULL || (!all &&
- thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
/* Ignore end-of-statement until real rollback or commit is called */
DBUG_PRINT("info", ("Rollback before start or end-of-statement only"));
@@ -5567,7 +5667,7 @@ int ha_ndbcluster::create(const char *name,
if (!ndbcluster_create_event(ndb, m_table, event_name.c_ptr(), share,
share && do_event_op ? 2 : 1/* push warning */))
{
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: CREATE TABLE Event: %s",
event_name.c_ptr());
if (share &&
@@ -6010,7 +6110,7 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
if (!ndbcluster_create_event(ndb, ndbtab, event_name.c_ptr(), share,
share && ndb_binlog_running ? 2 : 1/* push warning */))
{
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: RENAME Event: %s",
event_name.c_ptr());
if (share &&
@@ -6313,10 +6413,9 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
m_rows_to_insert+= m_autoincrement_prefetch;
}
uint remaining= m_rows_to_insert - m_rows_inserted;
+ ha_rows prefetch= THDVAR(thd, autoincrement_prefetch_sz);
uint min_prefetch=
- (remaining < thd->variables.ndb_autoincrement_prefetch_sz) ?
- thd->variables.ndb_autoincrement_prefetch_sz
- : remaining;
+ (remaining < prefetch) ? prefetch : remaining;
cache_size= ((remaining < m_autoincrement_prefetch) ?
min_prefetch
: remaining);
@@ -6406,7 +6505,7 @@ ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
m_dupkey((uint) -1),
m_ha_not_exact_count(FALSE),
m_force_send(TRUE),
- m_autoincrement_prefetch((ha_rows) NDB_DEFAULT_AUTO_PREFETCH),
+ m_autoincrement_prefetch(DEFAULT_AUTO_PREFETCH),
m_transaction_on(TRUE),
m_cond(NULL),
m_multi_cursor(NULL)
@@ -7417,17 +7516,31 @@ static int ndbcluster_init(void *p)
h->table_exists_in_engine= ndbcluster_table_exists_in_engine;
}
+ // Format the connect string to be used for connecting to the cluster
+ int pos= 0;
+ char connectstring_buf[1024] = {0};
+ if (opt_ndb_nodeid != 0)
+ pos+= my_snprintf(connectstring_buf, sizeof(connectstring_buf),
+ "nodeid=%u", opt_ndb_nodeid);
+ if (opt_ndb_mgmd_host)
+ pos+= my_snprintf(connectstring_buf+pos, sizeof(connectstring_buf)-pos,
+ "%s%s", pos ? "," : "", opt_ndb_mgmd_host);
+ if (opt_ndb_connectstring)
+ pos+= my_snprintf(connectstring_buf+pos, sizeof(connectstring_buf)-pos,
+ "%s%s", pos ? "," : "", opt_ndb_connectstring);
+
+
// Initialize ndb interface
ndb_init_internal();
// Set connectstring if specified
- if (opt_ndbcluster_connectstring != 0)
- DBUG_PRINT("connectstring", ("%s", opt_ndbcluster_connectstring));
+ if (opt_ndb_connectstring != 0)
+ DBUG_PRINT("connectstring", ("%s", opt_ndb_connectstring));
if ((g_ndb_cluster_connection=
- new Ndb_cluster_connection(opt_ndbcluster_connectstring)) == 0)
+ new Ndb_cluster_connection(opt_ndb_connectstring)) == 0)
{
DBUG_PRINT("error",("Ndb_cluster_connection(%s)",
- opt_ndbcluster_connectstring));
+ opt_ndb_connectstring));
my_errno= HA_ERR_OUT_OF_MEM;
goto ndbcluster_init_error;
}
@@ -7437,7 +7550,7 @@ static int ndbcluster_init(void *p)
g_ndb_cluster_connection->set_name(buf);
}
g_ndb_cluster_connection->set_optimized_node_selection
- (opt_ndb_optimized_node_selection);
+ (THDVAR(0, optimized_node_selection));
// Create a Ndb object to open the connection to NDB
if ( (g_ndb= new Ndb(g_ndb_cluster_connection, "sys")) == 0 )
@@ -7493,7 +7606,6 @@ static int ndbcluster_init(void *p)
goto ndbcluster_init_error;
#endif /* HAVE_NDB_BINLOG */
- ndb_cache_check_time = opt_ndb_cache_check_time;
// Create utility thread
pthread_t tmp;
if (pthread_create(&tmp, &connection_attrib, ndb_util_thread_func, 0))
@@ -7953,7 +8065,7 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
pthread_mutex_unlock(&ndbcluster_mutex);
pthread_mutex_lock(&share->mutex);
- if (ndb_cache_check_time > 0)
+ if (opt_ndb_cache_check_time > 0)
{
if (share->commit_count != 0)
{
@@ -8056,7 +8168,7 @@ ndbcluster_cache_retrieval_allowed(THD *thd,
ulonglong *engine_data)
{
Uint64 commit_count;
- bool is_autocommit= !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ bool is_autocommit= !(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
char *dbname= full_name;
char *tabname= dbname+strlen(dbname)+1;
#ifndef DBUG_OFF
@@ -8131,7 +8243,7 @@ ha_ndbcluster::register_query_cache_table(THD *thd,
#ifndef DBUG_OFF
char buff[22];
#endif
- bool is_autocommit= !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ bool is_autocommit= !(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
DBUG_ENTER("ha_ndbcluster::register_query_cache_table");
DBUG_PRINT("enter",("dbname: %s, tabname: %s, is_autocommit: %d",
m_dbname, m_tabname, is_autocommit));
@@ -8255,7 +8367,7 @@ int handle_trailing_share(NDB_SHARE *share)
share->key, share->use_count));
if (!--share->use_count)
{
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB_SHARE: trailing share "
"%s(connect_count: %u) "
"released by close_cached_tables at "
@@ -8281,7 +8393,7 @@ int handle_trailing_share(NDB_SHARE *share)
if (share->use_count == 0)
{
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB_SHARE: trailing share "
"%s(connect_count: %u) "
"released after NSS_DROPPED check "
@@ -9287,7 +9399,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
my_thread_init();
DBUG_ENTER("ndb_util_thread");
- DBUG_PRINT("enter", ("ndb_cache_check_time: %lu", ndb_cache_check_time));
+ DBUG_PRINT("enter", ("cache_check_time: %lu", opt_ndb_cache_check_time));
pthread_mutex_lock(&LOCK_ndb_util_thread);
@@ -9367,7 +9479,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
thd_ndb->options|= TNO_NO_LOG_SCHEMA_OP;
#ifdef HAVE_NDB_BINLOG
- if (ndb_extra_logging && ndb_binlog_running)
+ if (opt_ndb_extra_logging && ndb_binlog_running)
sql_print_information("NDB Binlog: Ndb tables initially read only.");
/* create tables needed by the replication */
ndbcluster_setup_binlog_table_shares(thd);
@@ -9390,8 +9502,8 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
goto ndb_util_thread_end;
pthread_mutex_unlock(&LOCK_ndb_util_thread);
#ifdef NDB_EXTRA_DEBUG_UTIL_THREAD
- DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %lu",
- ndb_cache_check_time));
+ DBUG_PRINT("ndb_util_thread", ("Started, opt_ndb_cache_check_time: %lu",
+ opt_ndb_cache_check_time));
#endif
#ifdef HAVE_NDB_BINLOG
@@ -9404,7 +9516,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
ndbcluster_setup_binlog_table_shares(thd);
#endif
- if (ndb_cache_check_time == 0)
+ if (opt_ndb_cache_check_time == 0)
{
/* Wake up in 1 second to check if value has changed */
set_timespec(abstime, 1);
@@ -9520,7 +9632,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
next:
/* Calculate new time to wake up */
int secs= 0;
- int msecs= ndb_cache_check_time;
+ int msecs= opt_ndb_cache_check_time;
struct timeval tick_time;
gettimeofday(&tick_time, 0);
@@ -9796,12 +9908,33 @@ int ha_ndbcluster::get_default_no_partitions(HA_CREATE_INFO *create_info)
and partition by hidden key otherwise.
*/
+
+enum ndb_distribution_enum { ND_KEYHASH= 0, ND_LINHASH= 1 };
+static const char* distribution_names[]= { "KEYHASH", "LINHASH", NullS };
+static ulong default_ndb_distribution= ND_KEYHASH;
+static TYPELIB distribution_typelib= {
+ array_elements(distribution_names) - 1,
+ "",
+ distribution_names,
+ NULL
+};
+static MYSQL_SYSVAR_ENUM(
+ distribution, /* name */
+ default_ndb_distribution, /* var */
+ PLUGIN_VAR_RQCMDARG,
+ "Default distribution for new tables in ndb",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ ND_KEYHASH, /* default */
+ &distribution_typelib /* typelib */
+);
+
void ha_ndbcluster::set_auto_partitions(partition_info *part_info)
{
DBUG_ENTER("ha_ndbcluster::set_auto_partitions");
part_info->list_of_part_fields= TRUE;
part_info->part_type= HASH_PARTITION;
- switch (opt_ndb_distribution_id)
+ switch (default_ndb_distribution)
{
case ND_KEYHASH:
part_info->linear_hash_ind= FALSE;
@@ -10037,7 +10170,7 @@ bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint i;
const NDBTAB *tab= (const NDBTAB *) m_table;
- if (current_thd->variables.ndb_use_copying_alter_table)
+ if (THDVAR(current_thd, use_copying_alter_table))
{
DBUG_PRINT("info", ("On-line alter table disabled"));
DBUG_RETURN(COMPATIBLE_DATA_NO);
@@ -10669,6 +10802,132 @@ SHOW_VAR ndb_status_variables_export[]= {
{NullS, NullS, SHOW_LONG}
};
+static MYSQL_SYSVAR_ULONG(
+ cache_check_time, /* name */
+ opt_ndb_cache_check_time, /* var */
+ PLUGIN_VAR_RQCMDARG,
+ "A dedicated thread is created to, at the given "
+ "millisecond interval, invalidate the query cache "
+ "if another MySQL server in the cluster has changed "
+ "the data in the database.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 0, /* default */
+ 0, /* min */
+ ONE_YEAR_IN_SECONDS, /* max */
+ 0 /* block */
+);
+
+
+static MYSQL_SYSVAR_ULONG(
+ extra_logging, /* name */
+ opt_ndb_extra_logging, /* var */
+ PLUGIN_VAR_OPCMDARG,
+ "Turn on more logging in the error log.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 1, /* default */
+ 0, /* min */
+ 0, /* max */
+ 0 /* block */
+);
+
+
+ulong opt_ndb_report_thresh_binlog_epoch_slip;
+static MYSQL_SYSVAR_ULONG(
+ report_thresh_binlog_epoch_slip, /* name */
+ opt_ndb_report_thresh_binlog_epoch_slip,/* var */
+ PLUGIN_VAR_RQCMDARG,
+ "Threshold on number of epochs to be behind before reporting binlog "
+ "status. E.g. 3 means that if the difference between what epoch has "
+ "been received from the storage nodes and what has been applied to "
+ "the binlog is 3 or more, a status message will be sent to the cluster "
+ "log.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 3, /* default */
+ 0, /* min */
+ 256, /* max */
+ 0 /* block */
+);
+
+
+ulong opt_ndb_report_thresh_binlog_mem_usage;
+static MYSQL_SYSVAR_ULONG(
+ report_thresh_binlog_mem_usage, /* name */
+ opt_ndb_report_thresh_binlog_mem_usage,/* var */
+ PLUGIN_VAR_RQCMDARG,
+ "Threshold on percentage of free memory before reporting binlog "
+ "status. E.g. 10 means that if amount of available memory for "
+ "receiving binlog data from the storage nodes goes below 10%, "
+ "a status message will be sent to the cluster log.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 10, /* default */
+ 0, /* min */
+ 100, /* max */
+ 0 /* block */
+);
+
+
+static MYSQL_SYSVAR_STR(
+ connectstring, /* name */
+ opt_ndb_connectstring, /* var */
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Connect string for ndbcluster.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ NULL /* default */
+);
+
+
+static MYSQL_SYSVAR_STR(
+ mgmd_host, /* name */
+ opt_ndb_mgmd_host, /* var */
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ NULL /* default */
+);
+
+
+static MYSQL_SYSVAR_UINT(
+ nodeid, /* name */
+ opt_ndb_nodeid, /* var */
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Nodeid for this mysqld in the cluster.",
+ NULL, /* check func. */
+ NULL, /* update func. */
+ 0, /* default */
+ 0, /* min */
+ 255, /* max */
+ 0 /* block */
+);
+
+static struct st_mysql_sys_var* system_variables[]= {
+ MYSQL_SYSVAR(cache_check_time),
+ MYSQL_SYSVAR(extra_logging),
+ MYSQL_SYSVAR(report_thresh_binlog_mem_usage),
+ MYSQL_SYSVAR(report_thresh_binlog_epoch_slip),
+ MYSQL_SYSVAR(distribution),
+ MYSQL_SYSVAR(autoincrement_prefetch_sz),
+ MYSQL_SYSVAR(force_send),
+ MYSQL_SYSVAR(use_exact_count),
+ MYSQL_SYSVAR(use_transactions),
+ MYSQL_SYSVAR(use_copying_alter_table),
+ MYSQL_SYSVAR(optimized_node_selection),
+ MYSQL_SYSVAR(index_stat_enable),
+ MYSQL_SYSVAR(index_stat_cache_entries),
+ MYSQL_SYSVAR(index_stat_update_freq),
+ MYSQL_SYSVAR(connectstring),
+ MYSQL_SYSVAR(mgmd_host),
+ MYSQL_SYSVAR(nodeid),
+
+ NULL
+};
+
+
struct st_mysql_storage_engine ndbcluster_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
@@ -10684,7 +10943,7 @@ mysql_declare_plugin(ndbcluster)
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
ndb_status_variables_export,/* status variables */
- NULL, /* system variables */
+ system_variables, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index ac3e7329136..a51dc38bf93 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -34,7 +34,6 @@
#include <ndbapi_limits.h>
#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8
-#define NDB_DEFAULT_AUTO_PREFETCH 32
class Ndb; // Forward declaration
@@ -50,11 +49,6 @@ class ha_ndbcluster_cond;
// connectstring to cluster if given by mysqld
extern const char *ndbcluster_connectstring;
-extern ulong ndb_cache_check_time;
-#ifdef HAVE_NDB_BINLOG
-extern ulong ndb_report_thresh_binlog_epoch_slip;
-extern ulong ndb_report_thresh_binlog_mem_usage;
-#endif
typedef enum ndb_index_type {
UNDEFINED_INDEX = 0,
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index bdbb57224b0..b59e686d131 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -33,6 +33,8 @@
#define assert(x) do { if(x) break; ::printf("%s %d: assert failed: %s\n", __FILE__, __LINE__, #x); ::fflush(stdout); ::signal(SIGABRT,SIG_DFL); ::abort(); ::kill(::getpid(),6); ::kill(::getpid(),9); } while (0)
#endif
+extern my_bool opt_ndb_log_binlog_index;
+extern ulong opt_ndb_extra_logging;
/*
defines for cluster replication table names
*/
@@ -44,14 +46,16 @@
Timeout for syncing schema events between
mysql servers, and between mysql server and the binlog
*/
-const int opt_ndb_sync_timeout= 120;
+static const int DEFAULT_SYNC_TIMEOUT= 120;
+
/*
Flag showing if the ndb injector thread is running, if so == 1
-1 if it was started but later stopped for some reason
0 if never started
*/
-int ndb_binlog_thread_running= 0;
+static int ndb_binlog_thread_running= 0;
+
/*
Flag showing if the ndb binlog should be created, if so == TRUE
FALSE if not
@@ -247,8 +251,8 @@ static void run_query(THD *thd, char *buf, char *end,
struct system_status_var save_thd_status_var= thd->status_var;
THD_TRANS save_thd_transaction_all= thd->transaction.all;
THD_TRANS save_thd_transaction_stmt= thd->transaction.stmt;
- ulonglong save_thd_options= thd->options;
- DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->options));
+ ulonglong save_thd_options= thd->variables.option_bits;
+ DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->variables.option_bits));
NET save_thd_net= thd->net;
const char* found_semicolon= NULL;
@@ -257,7 +261,7 @@ static void run_query(THD *thd, char *buf, char *end,
thd->variables.pseudo_thread_id= thread_id;
thd->transaction.stmt.modified_non_trans_table= FALSE;
if (disable_binlog)
- thd->options&= ~OPTION_BIN_LOG;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
DBUG_PRINT("query", ("%s", thd->query()));
@@ -295,7 +299,7 @@ static void run_query(THD *thd, char *buf, char *end,
*/
thd->stmt_da->reset_diagnostics_area();
- thd->options= save_thd_options;
+ thd->variables.option_bits= save_thd_options;
thd->set_query(save_thd_query, save_thd_query_length);
thd->variables.pseudo_thread_id= save_thread_id;
thd->status_var= save_thd_status_var;
@@ -788,7 +792,7 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd)
char buf[1024 + 1], *end;
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB: Creating " NDB_REP_DB "." NDB_APPLY_TABLE);
/*
@@ -846,7 +850,7 @@ static int ndbcluster_create_schema_table(THD *thd)
char buf[1024 + 1], *end;
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB: Creating " NDB_REP_DB "." NDB_SCHEMA_TABLE);
/*
@@ -919,7 +923,7 @@ int ndbcluster_setup_binlog_table_shares(THD *thd)
{
mysql_mutex_lock(&LOCK_open);
ndb_binlog_tables_inited= TRUE;
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: ndb tables writable");
close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE);
mysql_mutex_unlock(&LOCK_open);
@@ -1498,7 +1502,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share,
r|= op->setValue(SCHEMA_TYPE_I, log_type);
DBUG_ASSERT(r == 0);
/* any value */
- if (!(thd->options & OPTION_BIN_LOG))
+ if (!(thd->variables.option_bits & OPTION_BIN_LOG))
r|= op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
else
r|= op->setAnyValue(thd->server_id);
@@ -1561,7 +1565,7 @@ end:
else
dict->forceGCPWait();
- int max_timeout= opt_ndb_sync_timeout;
+ int max_timeout= DEFAULT_SYNC_TIMEOUT;
(void) pthread_mutex_lock(&ndb_schema_object->mutex);
if (have_lock_open)
{
@@ -1618,7 +1622,7 @@ end:
type_str, ndb_schema_object->key);
break;
}
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
ndb_report_waiting(type_str, max_timeout,
"distributing", ndb_schema_object->key);
}
@@ -1767,7 +1771,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
DBUG_PRINT("info", ("Detected name change of table %s.%s",
share->db, share->table_name));
/* ToDo: remove printout */
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: rename table %s%s/%s -> %s.",
share_prefix, share->table->s->db.str,
share->table->s->table_name.str,
@@ -2057,12 +2061,12 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
// skip
break;
case NDBEVENT::TE_CLUSTER_FAILURE:
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: cluster failure for %s at epoch %u.",
ndb_schema_share->key, (unsigned) pOp->getGCI());
// fall through
case NDBEVENT::TE_DROP:
- if (ndb_extra_logging &&
+ if (opt_ndb_extra_logging &&
ndb_binlog_tables_inited && ndb_binlog_running)
sql_print_information("NDB Binlog: ndb tables initially "
"read only on reconnect.");
@@ -2091,7 +2095,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
(void) pthread_mutex_lock(&tmp_share->mutex);
bitmap_clear_all(&tmp_share->subscriber_bitmap[node_id]);
DBUG_PRINT("info",("NODE_FAILURE UNSUBSCRIBE[%d]", node_id));
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
{
sql_print_information("NDB Binlog: Node: %d, down,"
" Subscriber bitmask %x%x",
@@ -2111,7 +2115,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
(void) pthread_mutex_lock(&tmp_share->mutex);
bitmap_set_bit(&tmp_share->subscriber_bitmap[node_id], req_id);
DBUG_PRINT("info",("SUBSCRIBE[%d] %d", node_id, req_id));
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
{
sql_print_information("NDB Binlog: Node: %d, subscribe from node %d,"
" Subscriber bitmask %x%x",
@@ -2132,7 +2136,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
(void) pthread_mutex_lock(&tmp_share->mutex);
bitmap_clear_bit(&tmp_share->subscriber_bitmap[node_id], req_id);
DBUG_PRINT("info",("UNSUBSCRIBE[%d] %d", node_id, req_id));
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
{
sql_print_information("NDB Binlog: Node: %d, unsubscribe from node %d,"
" Subscriber bitmask %x%x",
@@ -2369,8 +2373,8 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
Turn of binlogging to prevent the table changes to be written to
the binary log.
*/
- ulong saved_options= thd->options;
- thd->options&= ~(OPTION_BIN_LOG);
+ ulong saved_options= thd->variables.option_bits;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
for ( ; ; ) /* loop for need_reopen */
{
@@ -2420,12 +2424,12 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
- thd->options= saved_options;
+ thd->variables.option_bits= saved_options;
return 0;
add_ndb_binlog_index_err:
close_thread_tables(thd);
ndb_binlog_index= 0;
- thd->options= saved_options;
+ thd->variables.option_bits= saved_options;
return error;
}
@@ -2655,7 +2659,7 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
const NDBTAB *ndbtab= ndbtab_g.get_table();
if (ndbtab == 0)
{
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: Failed to get table %s from ndb: "
"%s, %d", key, dict->getNdbError().message,
dict->getNdbError().code);
@@ -2677,7 +2681,7 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
event_name.c_ptr());
break; // error
}
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: "
"CREATE (DISCOVER) TABLE Event: %s",
event_name.c_ptr());
@@ -2685,7 +2689,7 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
else
{
delete ev;
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: DISCOVER TABLE Event: %s",
event_name.c_ptr());
}
@@ -3089,7 +3093,7 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
DBUG_PRINT("info",("%s share->op: 0x%lx share->use_count: %u",
share->key, (long) share->op, share->use_count));
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: logging %s", share->key);
DBUG_RETURN(0);
}
@@ -3157,7 +3161,7 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name,
(void) pthread_mutex_lock(&share->mutex);
mysql_mutex_assert_owner(&LOCK_open);
mysql_mutex_unlock(&LOCK_open);
- int max_timeout= opt_ndb_sync_timeout;
+ int max_timeout= DEFAULT_SYNC_TIMEOUT;
while (share->op)
{
struct timespec abstime;
@@ -3177,7 +3181,7 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name,
type_str, share->key);
break;
}
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
ndb_report_waiting(type_str, max_timeout,
type_str, share->key);
}
@@ -3255,12 +3259,12 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
switch (type)
{
case NDBEVENT::TE_CLUSTER_FAILURE:
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: cluster failure for %s at epoch %u.",
share->key, (unsigned) pOp->getGCI());
if (ndb_apply_status_share == share)
{
- if (ndb_extra_logging &&
+ if (opt_ndb_extra_logging &&
ndb_binlog_tables_inited && ndb_binlog_running)
sql_print_information("NDB Binlog: ndb tables initially "
"read only on reconnect.");
@@ -3280,7 +3284,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
case NDBEVENT::TE_DROP:
if (ndb_apply_status_share == share)
{
- if (ndb_extra_logging &&
+ if (opt_ndb_extra_logging &&
ndb_binlog_tables_inited && ndb_binlog_running)
sql_print_information("NDB Binlog: ndb tables initially "
"read only on reconnect.");
@@ -3292,7 +3296,7 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
ndb_binlog_tables_inited= 0;
}
/* ToDo: remove printout */
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
sql_print_information("NDB Binlog: drop table %s.", share->key);
// fall through
case NDBEVENT::TE_ALTER:
@@ -3623,6 +3627,8 @@ static void ndb_free_schema_object(NDB_SCHEMA_OBJECT **ndb_schema_object,
DBUG_VOID_RETURN;
}
+extern ulong opt_ndb_report_thresh_binlog_epoch_slip;
+extern ulong opt_ndb_report_thresh_binlog_mem_usage;
pthread_handler_t ndb_binlog_thread_func(void *arg)
{
@@ -3881,7 +3887,7 @@ restart:
"Changes to the database that occured while "
"disconnected will not be in the binlog");
}
- if (ndb_extra_logging)
+ if (opt_ndb_extra_logging)
{
sql_print_information("NDB Binlog: starting log at epoch %u",
(unsigned)schema_gci);
@@ -3983,9 +3989,9 @@ restart:
{
thd->proc_info= "Processing events from schema table";
s_ndb->
- setReportThreshEventGCISlip(ndb_report_thresh_binlog_epoch_slip);
+ setReportThreshEventGCISlip(opt_ndb_report_thresh_binlog_epoch_slip);
s_ndb->
- setReportThreshEventFreeMem(ndb_report_thresh_binlog_mem_usage);
+ setReportThreshEventFreeMem(opt_ndb_report_thresh_binlog_mem_usage);
NdbEventOperation *pOp= s_ndb->nextEvent();
while (pOp != NULL)
{
@@ -4048,8 +4054,8 @@ restart:
/* initialize some variables for this epoch */
g_ndb_log_slave_updates= opt_log_slave_updates;
i_ndb->
- setReportThreshEventGCISlip(ndb_report_thresh_binlog_epoch_slip);
- i_ndb->setReportThreshEventFreeMem(ndb_report_thresh_binlog_mem_usage);
+ setReportThreshEventGCISlip(opt_ndb_report_thresh_binlog_epoch_slip);
+ i_ndb->setReportThreshEventFreeMem(opt_ndb_report_thresh_binlog_mem_usage);
bzero((char*) &row, sizeof(row));
thd->variables.character_set_client= &my_charset_latin1;
diff --git a/sql/ha_ndbcluster_binlog.h b/sql/ha_ndbcluster_binlog.h
index d80dfe9ee74..4c64aa23c5b 100644
--- a/sql/ha_ndbcluster_binlog.h
+++ b/sql/ha_ndbcluster_binlog.h
@@ -27,8 +27,6 @@ typedef NdbDictionary::Event NDBEVENT;
#define IS_TMP_PREFIX(A) (is_prefix(A, tmp_file_prefix))
-extern ulong ndb_extra_logging;
-
#define INJECTOR_EVENT_LEN 200
#define NDB_INVALID_SCHEMA_OBJECT 241
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 2ec92173d14..d46d416e275 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1145,7 +1145,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
{
if (part_elem->part_state == PART_ADMIN)
part_elem->part_state= PART_NORMAL;
- } while (part_elem= part_it++);
+ } while ((part_elem= part_it++));
DBUG_RETURN(error);
}
} while (++j < num_subparts);
@@ -1177,7 +1177,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
{
if (part_elem->part_state == PART_ADMIN)
part_elem->part_state= PART_NORMAL;
- } while (part_elem= part_it++);
+ } while ((part_elem= part_it++));
DBUG_RETURN(error);
}
}
@@ -6483,7 +6483,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
thd->lex->sql_command != SQLCOM_INSERT &&
mysql_bin_log.is_open() &&
!thd->current_stmt_binlog_row_based &&
- (thd->options & OPTION_BIN_LOG))
+ (thd->variables.option_bits & OPTION_BIN_LOG))
{
DBUG_PRINT("info", ("locking auto_increment_safe_stmt_log_lock"));
auto_increment_safe_stmt_log_lock= TRUE;
diff --git a/sql/handler.cc b/sql/handler.cc
index dd8eb93099d..784d02d7f4c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -307,7 +307,6 @@ const char **get_handler_errmsgs()
int ha_init_errors(void)
{
#define SETMSG(nr, msg) handler_errmsgs[(nr) - HA_ERR_FIRST]= (msg)
- const char **errmsgs;
/* Allocate a pointer array for the error message strings. */
/* Zerofill it to avoid uninitialized gaps. */
@@ -3696,7 +3695,6 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
void st_ha_check_opt::init()
{
flags= sql_flags= 0;
- sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
}
@@ -3774,15 +3772,6 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache)
}
/**
- Free memory allocated by a key cache.
-*/
-int ha_end_key_cache(KEY_CACHE *key_cache)
-{
- end_key_cache(key_cache, 1); // Can never fail
- return 0;
-}
-
-/**
Move all tables from one key cache to another one.
*/
int ha_change_key_cache(KEY_CACHE *old_key_cache,
@@ -4489,7 +4478,7 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
return (thd->current_stmt_binlog_row_based &&
table->s->cached_row_logging_check &&
- (thd->options & OPTION_BIN_LOG) &&
+ (thd->variables.option_bits & OPTION_BIN_LOG) &&
mysql_bin_log.is_open());
}
diff --git a/sql/handler.h b/sql/handler.h
index e5d868dc608..6d43c56edbf 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -941,9 +941,6 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
-enum ndb_distribution { ND_KEYHASH= 0, ND_LINHASH= 1 };
-
-
typedef struct {
ulonglong data_file_length;
ulonglong max_data_file_length;
@@ -1075,7 +1072,6 @@ typedef class Item COND;
typedef struct st_ha_check_opt
{
st_ha_check_opt() {} /* Remove gcc warning */
- ulong sort_buffer_size;
uint flags; /* isam layer flags (e.g. for myisamchk) */
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
KEY_CACHE *key_cache; /* new key cache when changing key cache */
@@ -2006,7 +2002,7 @@ extern const char *ha_row_type[];
extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
extern TYPELIB tx_isolation_typelib;
-extern TYPELIB myisam_stats_method_typelib;
+extern const char *myisam_stats_method_names[];
extern ulong total_ha, total_ha_2pc;
/* Wrapper functions */
@@ -2080,7 +2076,6 @@ extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache);
int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
-int ha_end_key_cache(KEY_CACHE *key_cache);
/* report to InnoDB that control passes to the client */
int ha_release_temporary_latches(THD *thd);
diff --git a/sql/item.cc b/sql/item.cc
index f4b2e549667..8168316b187 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -975,7 +975,7 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
THD *thd= table->in_use;
enum_check_fields tmp= thd->count_cuted_fields;
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
- ulong sql_mode= thd->variables.sql_mode;
+ ulonglong sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
res= save_in_field(field, no_conversions);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ec50e6c5708..1da383ce3e9 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -404,7 +404,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
if (!(*item)->with_subselect && (*item)->const_item())
{
TABLE *table= field->table;
- ulong orig_sql_mode= thd->variables.sql_mode;
+ ulonglong orig_sql_mode= thd->variables.sql_mode;
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
my_bitmap_map *old_maps[2];
ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 6f14e69e101..ec0f76717fd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -37,6 +37,7 @@
#include "sp_head.h"
#include "sp_rcontext.h"
#include "sp.h"
+#include "set_var.h"
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define sp_restore_security_context(A,B) while (0) {}
@@ -4984,7 +4985,7 @@ void Item_func_get_system_var::fix_length_and_dec()
if (var_type != OPT_DEFAULT)
{
my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
- var->name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
+ var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
return;
}
/* As there was no local variable, return the global value */
@@ -5001,22 +5002,38 @@ void Item_func_get_system_var::fix_length_and_dec()
decimals=0;
break;
case SHOW_LONGLONG:
- unsigned_flag= FALSE;
+ unsigned_flag= TRUE;
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
decimals=0;
break;
case SHOW_CHAR:
case SHOW_CHAR_PTR:
pthread_mutex_lock(&LOCK_global_system_variables);
- cptr= var->show_type() == SHOW_CHAR_PTR ?
- *(char**) var->value_ptr(current_thd, var_type, &component) :
- (char*) var->value_ptr(current_thd, var_type, &component);
+ cptr= var->show_type() == SHOW_CHAR ?
+ (char*) var->value_ptr(current_thd, var_type, &component) :
+ *(char**) var->value_ptr(current_thd, var_type, &component);
if (cptr)
- max_length= strlen(cptr) * system_charset_info->mbmaxlen;
+ max_length= system_charset_info->cset->numchars(system_charset_info,
+ cptr,
+ cptr + strlen(cptr));
pthread_mutex_unlock(&LOCK_global_system_variables);
collation.set(system_charset_info, DERIVATION_SYSCONST);
+ max_length*= system_charset_info->mbmaxlen;
decimals=NOT_FIXED_DEC;
break;
+ case SHOW_LEX_STRING:
+ {
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ LEX_STRING *ls= ((LEX_STRING*)var->value_ptr(current_thd, var_type, &component));
+ max_length= system_charset_info->cset->numchars(system_charset_info,
+ ls->str,
+ ls->str + ls->length);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ collation.set(system_charset_info, DERIVATION_SYSCONST);
+ max_length*= system_charset_info->mbmaxlen;
+ decimals=NOT_FIXED_DEC;
+ }
+ break;
case SHOW_BOOL:
case SHOW_MY_BOOL:
unsigned_flag= FALSE;
@@ -5029,7 +5046,7 @@ void Item_func_get_system_var::fix_length_and_dec()
max_length= DBL_DIG + 6;
break;
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
break;
}
}
@@ -5054,11 +5071,12 @@ enum Item_result Item_func_get_system_var::result_type() const
return INT_RESULT;
case SHOW_CHAR:
case SHOW_CHAR_PTR:
+ case SHOW_LEX_STRING:
return STRING_RESULT;
case SHOW_DOUBLE:
return REAL_RESULT;
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
return STRING_RESULT; // keep the compiler happy
}
}
@@ -5077,11 +5095,12 @@ enum_field_types Item_func_get_system_var::field_type() const
return MYSQL_TYPE_LONGLONG;
case SHOW_CHAR:
case SHOW_CHAR_PTR:
+ case SHOW_LEX_STRING:
return MYSQL_TYPE_VARCHAR;
case SHOW_DOUBLE:
return MYSQL_TYPE_DOUBLE;
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
return MYSQL_TYPE_VARCHAR; // keep the compiler happy
}
}
@@ -5142,7 +5161,7 @@ longlong Item_func_get_system_var::val_int()
{
case SHOW_INT: get_sys_var_safe (uint);
case SHOW_LONG: get_sys_var_safe (ulong);
- case SHOW_LONGLONG: get_sys_var_safe (longlong);
+ case SHOW_LONGLONG: get_sys_var_safe (ulonglong);
case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
case SHOW_BOOL: get_sys_var_safe (bool);
case SHOW_MY_BOOL: get_sys_var_safe (my_bool);
@@ -5157,6 +5176,7 @@ longlong Item_func_get_system_var::val_int()
}
case SHOW_CHAR:
case SHOW_CHAR_PTR:
+ case SHOW_LEX_STRING:
{
String *str_val= val_str(NULL);
@@ -5176,7 +5196,7 @@ longlong Item_func_get_system_var::val_int()
}
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
return 0; // keep the compiler happy
}
}
@@ -5216,14 +5236,18 @@ String* Item_func_get_system_var::val_str(String* str)
{
case SHOW_CHAR:
case SHOW_CHAR_PTR:
+ case SHOW_LEX_STRING:
{
pthread_mutex_lock(&LOCK_global_system_variables);
- char *cptr= var->show_type() == SHOW_CHAR_PTR ?
- *(char**) var->value_ptr(thd, var_type, &component) :
- (char*) var->value_ptr(thd, var_type, &component);
+ char *cptr= var->show_type() == SHOW_CHAR ?
+ (char*) var->value_ptr(thd, var_type, &component) :
+ *(char**) var->value_ptr(thd, var_type, &component);
if (cptr)
{
- if (str->copy(cptr, strlen(cptr), collation.collation))
+ size_t len= var->show_type() == SHOW_LEX_STRING ?
+ ((LEX_STRING*)(var->value_ptr(thd, var_type, &component)))->length :
+ strlen(cptr);
+ if (str->copy(cptr, len, collation.collation))
{
null_value= TRUE;
str= NULL;
@@ -5251,7 +5275,7 @@ String* Item_func_get_system_var::val_str(String* str)
break;
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
str= NULL;
break;
}
@@ -5309,12 +5333,11 @@ double Item_func_get_system_var::val_real()
cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
return cached_dval;
case SHOW_CHAR:
+ case SHOW_LEX_STRING:
case SHOW_CHAR_PTR:
{
- char *cptr;
-
pthread_mutex_lock(&LOCK_global_system_variables);
- cptr= var->show_type() == SHOW_CHAR ?
+ char *cptr= var->show_type() == SHOW_CHAR ?
(char*) var->value_ptr(thd, var_type, &component) :
*(char**) var->value_ptr(thd, var_type, &component);
if (cptr)
@@ -5343,7 +5366,7 @@ double Item_func_get_system_var::val_real()
cached_null_value= null_value;
return cached_dval;
default:
- my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
return 0;
}
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 831f0287266..c33088e0276 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -778,8 +778,8 @@ bool Aggregator_distinct::setup(THD *thd)
}
if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
0,
- (select_lex->options | thd->options),
- HA_POS_ERROR, (char*)"")))
+ (select_lex->options | thd->variables.option_bits),
+ HA_POS_ERROR, "")))
return TRUE;
table->file->extra(HA_EXTRA_NO_ROWS); // Don't update rows
table->no_rows=1;
@@ -3324,7 +3324,7 @@ bool Item_func_group_concat::setup(THD *thd)
*/
if (!(table= create_tmp_table(thd, tmp_table_param, all_fields,
(ORDER*) 0, 0, TRUE,
- (select_lex->options | thd->options),
+ (select_lex->options | thd->variables.option_bits),
HA_POS_ERROR, (char*) "")))
DBUG_RETURN(TRUE);
table->file->extra(HA_EXTRA_NO_ROWS);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index f6c316c15c6..860bd983184 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -96,7 +96,7 @@ public:
{
int *input_version= (int*)int_arg;
/* This function was introduced in 5.5 */
- int output_version= (*input_version, 50500);
+ int output_version= max(*input_version, 50500);
*input_version= output_version;
return 0;
}
diff --git a/sql/keycaches.cc b/sql/keycaches.cc
new file mode 100644
index 00000000000..d68e2bccd96
--- /dev/null
+++ b/sql/keycaches.cc
@@ -0,0 +1,163 @@
+/* Copyright (C) 2002-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "keycaches.h"
+
+/****************************************************************************
+ Named list handling
+****************************************************************************/
+
+NAMED_ILIST key_caches;
+
+/**
+ ilink (intrusive list element) with a name
+*/
+class NAMED_ILINK :public ilink
+{
+public:
+ const char *name;
+ uint name_length;
+ uchar* data;
+
+ NAMED_ILINK(I_List<NAMED_ILINK> *links, const char *name_arg,
+ uint name_length_arg, uchar* data_arg)
+ :name_length(name_length_arg), data(data_arg)
+ {
+ name= my_strndup(name_arg, name_length, MYF(MY_WME));
+ links->push_back(this);
+ }
+ inline bool cmp(const char *name_cmp, uint length)
+ {
+ return length == name_length && !memcmp(name, name_cmp, length);
+ }
+ ~NAMED_ILINK()
+ {
+ my_free((uchar*) name, MYF(0));
+ }
+};
+
+uchar* find_named(I_List<NAMED_ILINK> *list, const char *name, uint length,
+ NAMED_ILINK **found)
+{
+ I_List_iterator<NAMED_ILINK> it(*list);
+ NAMED_ILINK *element;
+ while ((element= it++))
+ {
+ if (element->cmp(name, length))
+ {
+ if (found)
+ *found= element;
+ return element->data;
+ }
+ }
+ return 0;
+}
+
+
+void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, uchar*))
+{
+ NAMED_ILINK *element;
+ DBUG_ENTER("NAMED_ILIST::delete_elements");
+ while ((element= get()))
+ {
+ (*free_element)(element->name, element->data);
+ delete element;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/* Key cache functions */
+
+LEX_STRING default_key_cache_base= {C_STRING_WITH_LEN("default")};
+
+KEY_CACHE zero_key_cache; ///< @@nonexistent_cache.param->value_ptr() points here
+
+KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
+{
+ if (!cache_name || ! cache_name->length)
+ cache_name= &default_key_cache_base;
+ return ((KEY_CACHE*) find_named(&key_caches,
+ cache_name->str, cache_name->length, 0));
+}
+
+KEY_CACHE *create_key_cache(const char *name, uint length)
+{
+ KEY_CACHE *key_cache;
+ DBUG_ENTER("create_key_cache");
+ DBUG_PRINT("enter",("name: %.*s", length, name));
+
+ if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
+ MYF(MY_ZEROFILL | MY_WME))))
+ {
+ if (!new NAMED_ILINK(&key_caches, name, length, (uchar*) key_cache))
+ {
+ my_free((char*) key_cache, MYF(0));
+ key_cache= 0;
+ }
+ else
+ {
+ /*
+ Set default values for a key cache
+ The values in dflt_key_cache_var is set by my_getopt() at startup
+
+ We don't set 'buff_size' as this is used to enable the key cache
+ */
+ key_cache->param_block_size= dflt_key_cache_var.param_block_size;
+ key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
+ key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold;
+ }
+ }
+ DBUG_RETURN(key_cache);
+}
+
+
+KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
+{
+ LEX_STRING key_cache_name;
+ KEY_CACHE *key_cache;
+
+ key_cache_name.str= (char *) name;
+ key_cache_name.length= length;
+ if (!(key_cache= get_key_cache(&key_cache_name)))
+ key_cache= create_key_cache(name, length);
+ return key_cache;
+}
+
+
+void free_key_cache(const char *name, KEY_CACHE *key_cache)
+{
+ end_key_cache(key_cache, 1); // Can never fail
+ my_free((char*) key_cache, MYF(0));
+}
+
+
+bool process_key_caches(process_key_cache_t func)
+{
+ I_List_iterator<NAMED_ILINK> it(key_caches);
+ NAMED_ILINK *element;
+
+ while ((element= it++))
+ {
+ KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
+ func(element->name, key_cache);
+ }
+ return 0;
+}
+
+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
+template class I_List_iterator<NAMED_ILINK>;
+#endif
+
diff --git a/sql/keycaches.h b/sql/keycaches.h
new file mode 100644
index 00000000000..542a4d14c3d
--- /dev/null
+++ b/sql/keycaches.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2002-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "sql_list.h"
+#include <keycache.h>
+
+extern "C"
+{
+ typedef int (*process_key_cache_t) (const char *, KEY_CACHE *);
+}
+
+class NAMED_ILINK;
+
+class NAMED_ILIST: public I_List<NAMED_ILINK>
+{
+ public:
+ void delete_elements(void (*free_element)(const char*, uchar*));
+};
+
+extern LEX_STRING default_key_cache_base;
+extern KEY_CACHE zero_key_cache;
+extern NAMED_ILIST key_caches;
+
+KEY_CACHE *create_key_cache(const char *name, uint length);
+KEY_CACHE *get_key_cache(LEX_STRING *cache_name);
+KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
+void free_key_cache(const char *name, KEY_CACHE *key_cache);
+bool process_key_caches(process_key_cache_t func);
+
diff --git a/sql/log.cc b/sql/log.cc
index fb990d60186..74239555c88 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -138,18 +138,22 @@ sql_print_message_func sql_print_message_handlers[3] =
sql_print_error
};
-
/**
- Create the name of the default general log file
-
+ Create the name of the log specified.
+
+ This method forms a new path + file name for the
+ log specified in @c name.
+
@param[IN] buff Location for building new string.
- @param[IN] log_ext The extension for the file (e.g .log)
- @returns Pointer to a new string containing the name
+ @param[IN] name Name of the log file.
+ @param[IN] log_ext The extension for the log (e.g. .log).
+
+ @returns Pointer to new string containing the name.
*/
-char *make_default_log_name(char *buff,const char* log_ext)
+char *make_log_name(char *buff, const char *name, const char* log_ext)
{
- strmake(buff, default_logfile_name, FN_REFLEN-5);
- return fn_format(buff, buff, mysql_data_home, log_ext,
+ strmake(buff, name, FN_REFLEN-5);
+ return fn_format(buff, buff, mysql_real_data_home, log_ext,
MYF(MY_UNPACK_FILENAME|MY_REPLACE_EXT));
}
@@ -420,8 +424,8 @@ bool Log_to_csv_event_handler::
*/
save_time_zone_used= thd->time_zone_used;
- save_thd_options= thd->options;
- thd->options&= ~OPTION_BIN_LOG;
+ save_thd_options= thd->variables.option_bits;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
bzero(& table_list, sizeof(TABLE_LIST));
table_list.alias= table_list.table_name= GENERAL_LOG_NAME.str;
@@ -529,7 +533,7 @@ err:
if (need_close)
close_performance_schema_table(thd, & open_tables_backup);
- thd->options= save_thd_options;
+ thd->variables.option_bits= save_thd_options;
thd->time_zone_used= save_time_zone_used;
return result;
}
@@ -838,10 +842,10 @@ bool Log_to_file_event_handler::init()
if (!is_initialized)
{
if (opt_slow_log)
- mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);
+ mysql_slow_log.open_slow_log(opt_slow_logname);
if (opt_log)
- mysql_log.open_query_log(sys_var_general_log_path.value);
+ mysql_log.open_query_log(opt_logname);
is_initialized= TRUE;
}
@@ -1202,7 +1206,7 @@ bool LOGGER::activate_log_handler(THD* thd, uint log_type)
{
file_log= file_log_handler->get_mysql_slow_log();
- file_log->open_slow_log(sys_var_slow_log_path.value);
+ file_log->open_slow_log(opt_slow_logname);
if (table_log_handler->activate_log(thd, QUERY_LOG_SLOW))
{
/* Error printed by open table in activate_log() */
@@ -1221,7 +1225,7 @@ bool LOGGER::activate_log_handler(THD* thd, uint log_type)
{
file_log= file_log_handler->get_mysql_log();
- file_log->open_query_log(sys_var_general_log_path.value);
+ file_log->open_query_log(opt_logname);
if (table_log_handler->activate_log(thd, QUERY_LOG_GENERAL))
{
/* Error printed by open table in activate_log() */
@@ -1454,8 +1458,8 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
DBUG_PRINT("enter", ("transaction: %s end_ev: 0x%lx",
all ? "all" : "stmt", (long) end_ev));
DBUG_PRINT("info", ("thd->options={ %s%s}",
- FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
- FLAGSTR(thd->options, OPTION_BEGIN)));
+ FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->variables.option_bits, OPTION_BEGIN)));
/*
NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
@@ -1503,7 +1507,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
transaction cache to remove the statement.
*/
thd->binlog_remove_pending_rows_event(TRUE);
- if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
+ if (all || !(thd->variables.option_bits & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
{
if (trx_data->has_incident())
error= mysql_bin_log.write_incident(thd, TRUE);
@@ -1572,7 +1576,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
Otherwise, we accumulate the statement
*/
ulonglong const in_transaction=
- thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
+ thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
DBUG_PRINT("debug",
("all: %d, empty: %s, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
all,
@@ -1647,7 +1651,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
back.
*/
if ((thd->transaction.stmt.modified_non_trans_table ||
- (thd->options & OPTION_KEEP_LOG)) &&
+ (thd->variables.option_bits & OPTION_KEEP_LOG)) &&
mysql_bin_log.check_write_error(thd))
trx_data->set_incident();
error= binlog_end_trans(thd, trx_data, 0, all);
@@ -1664,11 +1668,11 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
*/
if ((all && thd->transaction.all.modified_non_trans_table) ||
(!all && thd->transaction.stmt.modified_non_trans_table &&
- !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
+ !(thd->variables.option_bits & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
(!all && thd->transaction.stmt.modified_non_trans_table &&
!trx_data->at_least_one_stmt_committed &&
thd->current_stmt_binlog_row_based) ||
- ((thd->options & OPTION_KEEP_LOG)))
+ ((thd->variables.option_bits & OPTION_KEEP_LOG)))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
error= binlog_end_trans(thd, trx_data, &qev, all);
@@ -1772,7 +1776,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
from the SAVEPOINT command.
*/
if (unlikely(thd->transaction.all.modified_non_trans_table ||
- (thd->options & OPTION_KEEP_LOG)))
+ (thd->variables.option_bits & OPTION_KEEP_LOG)))
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
int error=
@@ -1948,7 +1952,7 @@ updating the index files.", max_found);
*/
if (((strlen(ext_buf) + (end - name)) >= FN_REFLEN))
{
- sql_print_error("Log filename too large: %s%s (%lu). \
+ sql_print_error("Log filename too large: %s%s (%zu). \
Please fix this by archiving old logs and updating the \
index files.", name, ext_buf, (strlen(ext_buf) + (end - name)));
error= 1;
@@ -4118,7 +4122,7 @@ THD::binlog_start_trans_and_stmt()
trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
{
this->binlog_set_stmt_begin();
- if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ if (variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(this, TRUE, binlog_hton);
trans_register_ha(this, FALSE, binlog_hton);
/*
@@ -4380,7 +4384,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
binlog_[wild_]{do|ignore}_table?" (WL#1049)"
*/
const char *local_db= event_info->get_db();
- if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
+ if ((thd && !(thd->variables.option_bits & OPTION_BIN_LOG)) ||
(!binlog_filter->db_ok(local_db)))
{
pthread_mutex_unlock(&LOCK_log);
@@ -4549,7 +4553,7 @@ bool LOGGER::log_command(THD *thd, enum enum_server_command command)
*/
if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
{
- if ((thd->options & OPTION_LOG_OFF)
+ if ((thd->variables.option_bits & OPTION_LOG_OFF)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
&& (sctx->master_access & SUPER_ACL)
#endif
diff --git a/sql/log.h b/sql/log.h
index fa24a2c5803..847fa3db6f9 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -608,13 +608,13 @@ public:
void init_general_log(uint general_log_printer);
void deactivate_log_handler(THD* thd, uint log_type);
bool activate_log_handler(THD* thd, uint log_type);
- MYSQL_QUERY_LOG *get_slow_log_file_handler()
+ MYSQL_QUERY_LOG *get_slow_log_file_handler() const
{
if (file_log_handler)
return file_log_handler->get_mysql_slow_log();
return NULL;
}
- MYSQL_QUERY_LOG *get_log_file_handler()
+ MYSQL_QUERY_LOG *get_log_file_handler() const
{
if (file_log_handler)
return file_log_handler->get_mysql_log();
@@ -623,19 +623,10 @@ public:
};
enum enum_binlog_format {
- /*
- statement-based except for cases where only row-based can work (UUID()
- etc):
- */
- BINLOG_FORMAT_MIXED= 0,
- BINLOG_FORMAT_STMT= 1, // statement-based
- BINLOG_FORMAT_ROW= 2, // row_based
-/*
- This value is last, after the end of binlog_format_typelib: it has no
- corresponding cell in this typelib. We use this value to be able to know if
- the user has explicitely specified a binlog format at startup or not.
-*/
- BINLOG_FORMAT_UNSPEC= 3
+ BINLOG_FORMAT_MIXED= 0, ///< statement if safe, otherwise row - autodetected
+ BINLOG_FORMAT_STMT= 1, ///< statement-based
+ BINLOG_FORMAT_ROW= 2, ///< row-based
+ BINLOG_FORMAT_UNSPEC=3 ///< thd_binlog_format() returns it when binlog is closed
};
extern TYPELIB binlog_format_typelib;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 9cfa6cf1540..fa5a78917ef 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1200,15 +1200,11 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
*/
if (description_event->event_type_permutation)
{
-#ifndef DBUG_OFF
- int new_event_type=
- description_event->event_type_permutation[event_type];
- DBUG_PRINT("info",
- ("converting event type %d to %d (%s)",
- event_type, new_event_type,
- get_type_str((Log_event_type)new_event_type)));
-#endif
- event_type= description_event->event_type_permutation[event_type];
+ int new_event_type= description_event->event_type_permutation[event_type];
+ DBUG_PRINT("info", ("converting event type %d to %d (%s)",
+ event_type, new_event_type,
+ get_type_str((Log_event_type)new_event_type)));
+ event_type= new_event_type;
}
switch(event_type) {
@@ -2415,7 +2411,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
the autocommit flag as written by the master to the binlog. This
behavior may change after WL#4162 has been implemented.
*/
- flags2= (uint32) (thd_arg->options &
+ flags2= (uint32) (thd_arg->variables.option_bits &
(OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
@@ -3064,13 +3060,13 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
{
if (flags2_inited)
/*
- all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
+ all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
must take their value from flags2.
*/
- thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
+ thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
/*
else, we are in a 3.23/4.0 binlog; we previously received a
- Rotate_log_event which reset thd->options and sql_mode etc, so
+ Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
nothing to do.
*/
/*
@@ -3347,13 +3343,13 @@ Query_log_event::do_shall_skip(Relay_log_info *rli)
{
if (strcmp("BEGIN", query) == 0)
{
- thd->options|= OPTION_BEGIN;
+ thd->variables.option_bits|= OPTION_BEGIN;
DBUG_RETURN(Log_event::continue_group(rli));
}
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
{
- thd->options&= ~OPTION_BEGIN;
+ thd->variables.option_bits&= ~OPTION_BEGIN;
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
}
@@ -3609,8 +3605,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
#ifndef DBUG_OFF
// Allows us to sanity-check that all events initialized their
// events (see the end of this 'if' block).
- memset(post_header_len, 255,
- number_of_event_types*sizeof(uint8));
+ memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
#endif
/* Note: all event types must explicitly fill in their lengths here. */
@@ -4953,7 +4948,7 @@ int Rotate_log_event::do_update_pos(Relay_log_info *rli)
flush_relay_log_info(rli);
/*
- Reset thd->options and sql_mode etc, because this could be the signal of
+ Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
a master's downgrade from 5.0 to 4.0.
However, no need to reset description_event_for_exec: indeed, if the next
master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
@@ -5323,7 +5318,7 @@ Xid_log_event::do_shall_skip(Relay_log_info *rli)
{
DBUG_ENTER("Xid_log_event::do_shall_skip");
if (rli->slave_skip_counter > 0) {
- thd->options&= ~OPTION_BEGIN;
+ thd->variables.option_bits&= ~OPTION_BEGIN;
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
DBUG_RETURN(Log_event::do_shall_skip(rli));
@@ -5924,7 +5919,7 @@ int Stop_log_event::do_update_pos(Relay_log_info *rli)
could give false triggers in MASTER_POS_WAIT() that we have reached
the target position when in fact we have not.
*/
- if (thd->options & OPTION_BEGIN)
+ if (thd->variables.option_bits & OPTION_BEGIN)
rli->inc_event_relay_log_pos();
else
{
@@ -6991,9 +6986,9 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) ||
(!tbl_arg && !cols && tid == ~0UL));
- if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
+ if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
set_flags(NO_FOREIGN_KEY_CHECKS_F);
- if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
+ if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
set_flags(RELAXED_UNIQUE_CHECKS_F);
/* if bitmap_init fails, caught in is_valid() */
if (likely(!bitmap_init(&m_cols,
@@ -7282,7 +7277,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
STMT_END_F or next error.
*/
if (!thd->current_stmt_binlog_row_based &&
- mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+ mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
{
thd->set_current_stmt_binlog_row_based();
}
@@ -7294,16 +7289,16 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
the event.
*/
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
- thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
else
- thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
- thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
else
- thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
/* A small test to verify that objects have consistent types */
- DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
+ DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
if (simple_open_n_lock_tables(thd, rli->tables_to_lock))
{
@@ -7457,8 +7452,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
{
int actual_error= convert_handler_error(error, thd, table);
bool idempotent_error= (idempotent_error_code(error) &&
- ((bit_is_set(slave_exec_mode,
- SLAVE_EXEC_MODE_IDEMPOTENT)) == 1));
+ (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
bool ignored_error= (idempotent_error == 0 ?
ignored_error_code(actual_error) : 0);
@@ -7526,7 +7520,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
if (!cache_stmt)
{
DBUG_PRINT("info", ("Marked that we need to keep log"));
- thd->options|= OPTION_KEEP_LOG;
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
}
} // if (table)
@@ -8270,8 +8264,8 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
todo: to introduce a property for the event (handler?) which forces
applying the event in the replace (idempotent) fashion.
*/
- if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
- m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
+ if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
+ (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
{
/*
We are using REPLACE semantics and not INSERT IGNORE semantics
@@ -8349,7 +8343,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *
int local_error= 0;
m_table->next_number_field=0;
m_table->auto_increment_field_not_null= FALSE;
- if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 ||
+ if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
{
m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -8650,9 +8644,7 @@ int
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
{
DBUG_ASSERT(m_table != NULL);
- int error=
- write_row(rli, /* if 1 then overwrite */
- bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
+ int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
if (error && !thd->is_error())
{
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 72affd2bee9..3ebd4b1864a 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -71,7 +71,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
STMT_END_F or next error.
*/
if (!thd->current_stmt_binlog_row_based &&
- mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+ mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
{
thd->set_current_stmt_binlog_row_based();
}
@@ -166,16 +166,16 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
the event.
*/
if (ev->get_flags(Old_rows_log_event::NO_FOREIGN_KEY_CHECKS_F))
- thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
else
- thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
if (ev->get_flags(Old_rows_log_event::RELAXED_UNIQUE_CHECKS_F))
- thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
else
- thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
/* A small test to verify that objects have consistent types */
- DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
+ DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
/*
Now we are in a statement and will stay in a statement until we
@@ -232,7 +232,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
if (!ev->cache_stmt)
{
DBUG_PRINT("info", ("Marked that we need to keep log"));
- thd->options|= OPTION_KEEP_LOG;
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
}
}
@@ -1220,9 +1220,9 @@ Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) ||
(!tbl_arg && !cols && tid == ~0UL));
- if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
+ if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
set_flags(NO_FOREIGN_KEY_CHECKS_F);
- if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
+ if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
set_flags(RELAXED_UNIQUE_CHECKS_F);
/* if bitmap_init fails, caught in is_valid() */
if (likely(!bitmap_init(&m_cols,
@@ -1619,16 +1619,16 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
the event.
*/
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
- thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
else
- thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
- thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
else
- thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
/* A small test to verify that objects have consistent types */
- DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
+ DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
/*
Now we are in a statement and will stay in a statement until we
@@ -1730,7 +1730,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
if (!cache_stmt)
{
DBUG_PRINT("info", ("Marked that we need to keep log"));
- thd->options|= OPTION_KEEP_LOG;
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
}
} // if (table)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3ddaf114673..50fbf128660 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -36,7 +36,7 @@
#define SHOW_always_last SHOW_KEY_CACHE_LONG, \
SHOW_KEY_CACHE_LONGLONG, SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, \
SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, \
- SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS
+ SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_LEX_STRING
#include <my_global.h>
#include <mysql_version.h>
@@ -492,12 +492,6 @@ protected:
#define FLUSH_TIME 0 /**< Don't flush tables */
#define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
-#ifdef __NETWARE__
-#define IF_NETWARE(A,B) A
-#else
-#define IF_NETWARE(A,B) B
-#endif
-
#if defined(__WIN__)
#undef FLUSH_TIME
#define FLUSH_TIME 1800 /**< Flush every half hour */
@@ -522,7 +516,7 @@ protected:
This is included in the server and in the client.
Options for select set by the yacc parser (stored in lex->options).
- XXX:
+ NOTE
log_event.h defines OPTIONS_WRITTEN_TO_BIN_LOG to specify what THD
options list are written into binlog. These options can NOT change their
values, or it will break replication between version.
@@ -536,53 +530,52 @@ protected:
TODO: separate three contexts above, move them to separate bitfields.
*/
-#define SELECT_DISTINCT (ULL(1) << 0) // SELECT, user
-#define SELECT_STRAIGHT_JOIN (ULL(1) << 1) // SELECT, user
-#define SELECT_DESCRIBE (ULL(1) << 2) // SELECT, user
-#define SELECT_SMALL_RESULT (ULL(1) << 3) // SELECT, user
-#define SELECT_BIG_RESULT (ULL(1) << 4) // SELECT, user
-#define OPTION_FOUND_ROWS (ULL(1) << 5) // SELECT, user
-#define OPTION_TO_QUERY_CACHE (ULL(1) << 6) // SELECT, user
-#define SELECT_NO_JOIN_CACHE (ULL(1) << 7) // intern
-#define OPTION_BIG_TABLES (ULL(1) << 8) // THD, user
-#define OPTION_BIG_SELECTS (ULL(1) << 9) // THD, user
-#define OPTION_LOG_OFF (ULL(1) << 10) // THD, user
-#define OPTION_QUOTE_SHOW_CREATE (ULL(1) << 11) // THD, user, unused
-#define TMP_TABLE_ALL_COLUMNS (ULL(1) << 12) // SELECT, intern
-#define OPTION_WARNINGS (ULL(1) << 13) // THD, user
-#define OPTION_AUTO_IS_NULL (ULL(1) << 14) // THD, user, binlog
-#define OPTION_FOUND_COMMENT (ULL(1) << 15) // SELECT, intern, parser
-#define OPTION_SAFE_UPDATES (ULL(1) << 16) // THD, user
-#define OPTION_BUFFER_RESULT (ULL(1) << 17) // SELECT, user
-#define OPTION_BIN_LOG (ULL(1) << 18) // THD, user
-#define OPTION_NOT_AUTOCOMMIT (ULL(1) << 19) // THD, user
-#define OPTION_BEGIN (ULL(1) << 20) // THD, intern
-#define OPTION_TABLE_LOCK (ULL(1) << 21) // THD, intern
-#define OPTION_QUICK (ULL(1) << 22) // SELECT (for DELETE)
-#define OPTION_KEEP_LOG (ULL(1) << 23) // THD, user
+#define SELECT_DISTINCT (1ULL << 0) // SELECT, user
+#define SELECT_STRAIGHT_JOIN (1ULL << 1) // SELECT, user
+#define SELECT_DESCRIBE (1ULL << 2) // SELECT, user
+#define SELECT_SMALL_RESULT (1ULL << 3) // SELECT, user
+#define SELECT_BIG_RESULT (1ULL << 4) // SELECT, user
+#define OPTION_FOUND_ROWS (1ULL << 5) // SELECT, user
+#define OPTION_TO_QUERY_CACHE (1ULL << 6) // SELECT, user
+#define SELECT_NO_JOIN_CACHE (1ULL << 7) // intern
+/** always the opposite of OPTION_NOT_AUTOCOMMIT except when in fix_autocommit() */
+#define OPTION_AUTOCOMMIT (1ULL << 8) // THD, user
+#define OPTION_BIG_SELECTS (1ULL << 9) // THD, user
+#define OPTION_LOG_OFF (1ULL << 10) // THD, user
+#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user, unused
+#define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern
+#define OPTION_WARNINGS (1ULL << 13) // THD, user
+#define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog
+#define OPTION_FOUND_COMMENT (1ULL << 15) // SELECT, intern, parser
+#define OPTION_SAFE_UPDATES (1ULL << 16) // THD, user
+#define OPTION_BUFFER_RESULT (1ULL << 17) // SELECT, user
+#define OPTION_BIN_LOG (1ULL << 18) // THD, user
+#define OPTION_NOT_AUTOCOMMIT (1ULL << 19) // THD, user
+#define OPTION_BEGIN (1ULL << 20) // THD, intern
+#define OPTION_TABLE_LOCK (1ULL << 21) // THD, intern
+#define OPTION_QUICK (1ULL << 22) // SELECT (for DELETE)
+#define OPTION_KEEP_LOG (1ULL << 23) // THD, user
/* The following is used to detect a conflict with DISTINCT */
-#define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser
-
+#define SELECT_ALL (1ULL << 24) // SELECT, user, parser
/** The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */
-#define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog
+#define OPTION_NO_FOREIGN_KEY_CHECKS (1ULL << 26) // THD, user, binlog
/** The following speeds up inserts to InnoDB tables by suppressing unique
key checks in some cases */
-#define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog
-#define SELECT_NO_UNLOCK (ULL(1) << 28) // SELECT, intern
-#define OPTION_SCHEMA_TABLE (ULL(1) << 29) // SELECT, intern
+#define OPTION_RELAXED_UNIQUE_CHECKS (1ULL << 27) // THD, user, binlog
+#define SELECT_NO_UNLOCK (1ULL << 28) // SELECT, intern
+#define OPTION_SCHEMA_TABLE (1ULL << 29) // SELECT, intern
/** Flag set if setup_tables already done */
-#define OPTION_SETUP_TABLES_DONE (ULL(1) << 30) // intern
+#define OPTION_SETUP_TABLES_DONE (1ULL << 30) // intern
/** If not set then the thread will ignore all warnings with level notes. */
-#define OPTION_SQL_NOTES (ULL(1) << 31) // THD, user
+#define OPTION_SQL_NOTES (1ULL << 31) // THD, user
/**
Force the used temporary table to be a MyISAM table (because we will use
fulltext functions when reading from it.
*/
-#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
-#define OPTION_PROFILING (ULL(1) << 33)
-
+#define TMP_TABLE_FORCE_MYISAM (1ULL << 32)
+#define OPTION_PROFILING (1ULL << 33)
/**
@@ -1320,7 +1313,7 @@ bool wait_for_tables(THD *thd);
bool table_is_used(TABLE *table, bool wait_for_name_lock);
TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name);
void abort_locked_tables(THD *thd,const char *db, const char *table_name);
-void execute_init_command(THD *thd, sys_var_str *init_command_var,
+void execute_init_command(THD *thd, LEX_STRING *init_command,
rw_lock_t *var_mutex);
extern Field *not_found_field;
extern Field *view_ref_found;
@@ -1594,7 +1587,8 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
void remove_db_from_cache(const char *db);
void flush_tables();
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
-char *make_default_log_name(char *buff,const char* log_ext);
+char *make_log_name(char *buff, const char *name, const char* log_ext);
+extern char default_logfile_name[FN_REFLEN];
#ifdef WITH_PARTITION_STORAGE_ENGINE
uint fast_alter_partition_table(THD *thd, TABLE *table,
@@ -1860,10 +1854,6 @@ extern enum_field_types agg_field_type(Item **items, uint nitems);
/* strfunc.cc */
ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning);
-ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
- ulonglong cur_set, ulonglong default_set,
- const char *str, uint length, CHARSET_INFO *cs,
- char **err_pos, uint *err_len, bool *set_warning);
uint find_type(const TYPELIB *lib, const char *find, uint length,
bool part_match);
uint find_type2(const TYPELIB *lib, const char *find, uint length,
@@ -1873,6 +1863,10 @@ uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
CHARSET_INFO * const cs);
+char *set_to_string(THD *thd, LEX_STRING *result, ulonglong set,
+ const char *lib[]);
+char *flagset_to_string(THD *thd, LEX_STRING *result, ulonglong set,
+ const char *lib[]);
bool is_keyword(const char *name, uint len);
@@ -1897,7 +1891,9 @@ extern int creating_table; // How many mysql_create_table() are running
extern time_t server_start_time, flush_status_time;
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
-extern uint mysql_data_home_len;
+extern uint mysql_data_home_len, mysql_real_data_home_len;
+extern const char *mysql_real_data_home_ptr;
+extern uint thread_handling;
extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
extern char server_version[SERVER_VERSION_LENGTH];
@@ -1907,18 +1903,18 @@ extern char mysql_unpacked_real_data_home[];
extern CHARSET_INFO *character_set_filesystem;
#endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */
#ifdef MYSQL_SERVER
-extern char *opt_mysql_tmpdir, mysql_charsets_dir[],
- def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+extern char *opt_mysql_tmpdir, mysql_charsets_dir[];
extern int mysql_unpacked_real_data_home_len;
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
extern const LEX_STRING command_name[];
+extern LEX_STRING opt_init_connect, opt_init_slave;
+
extern const char *first_keyword, *delayed_user, *binary_keyword;
extern MYSQL_PLUGIN_IMPORT const char *my_localhost;
extern MYSQL_PLUGIN_IMPORT const char **errmesg; /* Error messages */
-extern const char *myisam_recover_options_str;
extern const char *in_left_expr_name, *in_additional_cond, *in_having_cond;
extern const char * const TRG_EXT;
extern const char * const TRN_EXT;
@@ -1929,15 +1925,16 @@ extern Lt_creator lt_creator;
extern Ge_creator ge_creator;
extern Le_creator le_creator;
extern char lc_messages_dir[FN_REFLEN];
+extern char *lc_messages_dir_ptr, *log_error_file_ptr;
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN];
extern MYSQL_PLUGIN_IMPORT uint reg_ext_length;
#endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */
#ifdef MYSQL_SERVER
+extern char *mysql_home_ptr, *pidfile_name_ptr;
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
-extern char default_logfile_name[FN_REFLEN];
extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
extern ulonglong log_10_int[20];
extern ulonglong keybuff_size;
@@ -1956,7 +1953,6 @@ extern ulong table_cache_size, table_def_size;
extern MYSQL_PLUGIN_IMPORT ulong max_connections;
extern ulong max_connect_errors, connect_timeout;
extern ulong slave_net_timeout, slave_trans_retries;
-extern uint max_user_connections;
extern ulong what_to_log,flush_time;
extern ulong query_buff_size;
extern ulong max_prepared_stmt_count, prepared_stmt_count;
@@ -1998,7 +1994,7 @@ extern MYSQL_PLUGIN_IMPORT bool mysqld_embedded;
extern bool opt_large_files, server_id_supplied;
extern bool opt_update_log, opt_bin_log, opt_error_log;
extern my_bool opt_log, opt_slow_log;
-extern ulong log_output_options;
+extern ulonglong log_output_options;
extern my_bool opt_log_queries_not_using_indexes;
extern bool opt_disable_networking, opt_skip_show_db;
extern bool opt_ignore_builtin_innodb;
@@ -2010,18 +2006,20 @@ extern uint connection_count;
extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
extern my_bool opt_slave_compressed_protocol, use_temp_pool;
-extern ulong slave_exec_mode_options;
+extern uint slave_exec_mode_options;
extern my_bool opt_readonly, lower_case_file_system;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;
extern char* opt_secure_file_priv;
extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
-extern my_bool sp_automatic_privileges, opt_noacl;
+extern my_bool sp_automatic_privileges, opt_noacl, disable_slaves;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port;
extern my_bool opt_enable_shared_memory;
extern char *default_tz_name;
+extern Time_zone *default_tz;
+extern char *default_storage_engine;
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
extern my_bool opt_large_pages;
@@ -2030,6 +2028,7 @@ extern uint opt_large_page_size;
#ifdef MYSQL_SERVER
extern char *opt_logname, *opt_slow_logname;
extern const char *log_output_str;
+extern my_bool old_mode;
extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
extern LOGGER logger;
@@ -2061,7 +2060,6 @@ extern pthread_cond_t COND_thread_count, COND_manager;
extern pthread_cond_t COND_global_read_lock;
extern pthread_attr_t connection_attrib;
extern I_List<THD> threads;
-extern I_List<NAMED_LIST> key_caches;
extern MY_BITMAP temp_pool;
extern String my_empty_string;
extern const String my_null_string;
@@ -2075,7 +2073,7 @@ extern struct system_variables max_system_variables;
extern struct system_status_var global_status_var;
extern struct rand_struct sql_rand;
-extern const char *opt_date_time_formats[];
+extern DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
extern String null_string;
@@ -2089,8 +2087,11 @@ extern TYPELIB thread_handling_typelib;
extern uint8 uc_update_queries[SQLCOM_END+1];
extern uint sql_command_flags[];
extern TYPELIB log_output_typelib;
+extern const char *log_output_names[];
/* optional things, have_* variables */
+extern SHOW_COMP_OPTION have_csv, have_innodb;
+extern SHOW_COMP_OPTION have_ndbcluster, have_partitioning;
extern SHOW_COMP_OPTION have_profiling;
extern handlerton *partition_hton;
@@ -2111,6 +2112,9 @@ extern const char *load_default_groups[];
extern pthread_t signal_thread;
#endif
+extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
+ *opt_ssl_key;
+
#ifdef HAVE_OPENSSL
extern struct st_VioSSLFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
@@ -2221,6 +2225,20 @@ bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
extern LEX_STRING interval_type_to_name[];
+
+bool parse_date_time_format(timestamp_type format_type,
+ const char *format, uint format_length,
+ DATE_TIME_FORMAT *date_time_format);
+/* convenience wrapper */
+inline bool parse_date_time_format(timestamp_type format_type,
+ DATE_TIME_FORMAT *date_time_format)
+{
+ return parse_date_time_format(format_type,
+ date_time_format->format.str,
+ date_time_format->format.length,
+ date_time_format);
+}
+
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
const char *format_str,
uint format_length);
@@ -2488,6 +2506,11 @@ inline void kill_delayed_threads(void) {}
#define check_stack_overrun(A, B, C) 0
#endif
+/* This must match the path length limit in the ER_NOT_RW_DIR error msg. */
+#define ER_NOT_RW_DIR_PATHSIZE 200
+bool is_usable_directory(THD *thd, const char *varname,
+ const char *path, const char *prefix);
+
/* Used by handlers to store things in schema tables */
#define IS_FILES_FILE_ID 0
#define IS_FILES_FILE_NAME 1
@@ -2563,6 +2586,58 @@ bool load_collation(MEM_ROOT *mem_root,
CHARSET_INFO *dflt_cl,
CHARSET_INFO **cl);
+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+
+/**
+ only options that need special treatment in get_one_option() deserve
+ to be listed below
+*/
+enum options_mysqld
+{
+ OPT_to_set_the_start_number=256,
+ OPT_BIND_ADDRESS,
+ OPT_BINLOG_DO_DB,
+ OPT_BINLOG_FORMAT,
+ OPT_BINLOG_IGNORE_DB,
+ OPT_BIN_LOG,
+ OPT_BOOTSTRAP,
+ OPT_CONSOLE,
+ OPT_DEBUG_SYNC_TIMEOUT,
+ OPT_DELAY_KEY_WRITE_ALL,
+ OPT_ISAM_LOG,
+ OPT_KEY_BUFFER_SIZE,
+ OPT_KEY_CACHE_AGE_THRESHOLD,
+ OPT_KEY_CACHE_BLOCK_SIZE,
+ OPT_KEY_CACHE_DIVISION_LIMIT,
+ OPT_LOWER_CASE_TABLE_NAMES,
+ OPT_ONE_THREAD,
+ OPT_POOL_OF_THREADS,
+ OPT_REPLICATE_DO_DB,
+ OPT_REPLICATE_DO_TABLE,
+ OPT_REPLICATE_IGNORE_DB,
+ OPT_REPLICATE_IGNORE_TABLE,
+ OPT_REPLICATE_REWRITE_DB,
+ OPT_REPLICATE_WILD_DO_TABLE,
+ OPT_REPLICATE_WILD_IGNORE_TABLE,
+ OPT_SAFE,
+ OPT_SERVER_ID,
+ OPT_SKIP_HOST_CACHE,
+ OPT_SKIP_LOCK,
+ OPT_SKIP_NEW,
+ OPT_SKIP_PRIOR,
+ OPT_SKIP_RESOLVE,
+ OPT_SKIP_STACK_TRACE,
+ OPT_SKIP_SYMLINKS,
+ OPT_SLOW_QUERY_LOG,
+ OPT_SSL_CA,
+ OPT_SSL_CAPATH,
+ OPT_SSL_CERT,
+ OPT_SSL_CIPHER,
+ OPT_SSL_KEY,
+ OPT_UPDATE_LOG,
+ OPT_WANT_CORE
+};
+
#endif /* MYSQL_SERVER */
extern "C" int test_if_data_home_dir(const char *dir);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 826e8a6c980..068a49d0ae6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -28,8 +28,9 @@
#include "events.h"
#include "probes_mysql.h"
#include "debug_sync.h"
-
+#include "keycaches.h"
#include "../storage/myisam/ha_myisam.h"
+#include "set_var.h"
#include "rpl_injector.h"
@@ -39,15 +40,6 @@
#include <sys/prctl.h>
#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-#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
-#endif
-
#include <thr_alarm.h>
#include <ft_global.h>
#include <errmsg.h>
@@ -56,18 +48,6 @@
#define mysqld_charset &my_charset_latin1
-#ifdef HAVE_purify
-#define IF_PURIFY(A,B) (A)
-#else
-#define IF_PURIFY(A,B) (B)
-#endif
-
-#if SIZEOF_CHARP == 4
-#define MAX_MEM_TABLE_SIZE ~(ulong) 0
-#else
-#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
-#endif
-
/* stack traces are only supported on linux intel */
#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
#define HAVE_STACK_TRACE_ON_SEGV
@@ -247,85 +227,6 @@ extern "C" sig_handler handle_segfault(int sig);
/* Constants */
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
-/*
- WARNING: When adding new SQL modes don't forget to update the
- tables definitions that stores it's value.
- (ie: mysql.event, mysql.proc)
-*/
-static const char *sql_mode_names[]=
-{
- "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
- "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
- "NO_DIR_IN_CREATE",
- "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
- "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
- "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
- "STRICT_ALL_TABLES",
- "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES",
- "ERROR_FOR_DIVISION_BY_ZERO",
- "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE",
- "NO_ENGINE_SUBSTITUTION",
- "PAD_CHAR_TO_FULL_LENGTH",
- NullS
-};
-
-static const unsigned int sql_mode_names_len[]=
-{
- /*REAL_AS_FLOAT*/ 13,
- /*PIPES_AS_CONCAT*/ 15,
- /*ANSI_QUOTES*/ 11,
- /*IGNORE_SPACE*/ 12,
- /*?*/ 1,
- /*ONLY_FULL_GROUP_BY*/ 18,
- /*NO_UNSIGNED_SUBTRACTION*/ 23,
- /*NO_DIR_IN_CREATE*/ 16,
- /*POSTGRESQL*/ 10,
- /*ORACLE*/ 6,
- /*MSSQL*/ 5,
- /*DB2*/ 3,
- /*MAXDB*/ 5,
- /*NO_KEY_OPTIONS*/ 14,
- /*NO_TABLE_OPTIONS*/ 16,
- /*NO_FIELD_OPTIONS*/ 16,
- /*MYSQL323*/ 8,
- /*MYSQL40*/ 7,
- /*ANSI*/ 4,
- /*NO_AUTO_VALUE_ON_ZERO*/ 21,
- /*NO_BACKSLASH_ESCAPES*/ 20,
- /*STRICT_TRANS_TABLES*/ 19,
- /*STRICT_ALL_TABLES*/ 17,
- /*NO_ZERO_IN_DATE*/ 15,
- /*NO_ZERO_DATE*/ 12,
- /*ALLOW_INVALID_DATES*/ 19,
- /*ERROR_FOR_DIVISION_BY_ZERO*/ 26,
- /*TRADITIONAL*/ 11,
- /*NO_AUTO_CREATE_USER*/ 19,
- /*HIGH_NOT_PRECEDENCE*/ 19,
- /*NO_ENGINE_SUBSTITUTION*/ 22,
- /*PAD_CHAR_TO_FULL_LENGTH*/ 23
-};
-
-TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
- sql_mode_names,
- (unsigned int *)sql_mode_names_len };
-
-static const char *optimizer_switch_names[]=
-{
- "index_merge","index_merge_union","index_merge_sort_union",
- "index_merge_intersection", "default", NullS
-};
-/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
-static const unsigned int optimizer_switch_names_len[]=
-{
- sizeof("index_merge") - 1,
- sizeof("index_merge_union") - 1,
- sizeof("index_merge_sort_union") - 1,
- sizeof("index_merge_intersection") - 1,
- sizeof("default") - 1
-};
-TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
- optimizer_switch_names,
- (unsigned int *)optimizer_switch_names_len };
static const char *tc_heuristic_recover_names[]=
{
@@ -337,26 +238,8 @@ static TYPELIB tc_heuristic_recover_typelib=
tc_heuristic_recover_names, NULL
};
-static const char *thread_handling_names[]=
-{ "one-thread-per-connection", "no-threads",
-#if HAVE_POOL_OF_THREADS == 1
- "pool-of-threads",
-#endif
- NullS};
-
-TYPELIB thread_handling_typelib=
-{
- array_elements(thread_handling_names) - 1, "",
- thread_handling_names, NULL
-};
-
const char *first_keyword= "first", *binary_keyword= "BINARY";
const char *my_localhost= "localhost", *delayed_user= "DELAYED";
-#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
-#define GET_HA_ROWS GET_ULL
-#else
-#define GET_HA_ROWS GET_ULONG
-#endif
bool opt_large_files= sizeof(my_off_t) > 4;
@@ -387,26 +270,22 @@ static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
static uint kill_cached_threads, wake_thread;
-static ulong killed_threads, thread_created;
+static ulong killed_threads;
static ulong max_used_connections;
static volatile ulong cached_thread_count= 0;
-static const char *sql_mode_str= "OFF";
-/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
-static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
- "index_merge_sort_union=on,"
- "index_merge_intersection=on";
-static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
-static char *opt_init_slave, *lc_messages_dir_ptr, *opt_init_connect;
+static char *mysqld_user, *mysqld_chroot;
static char *default_character_set_name;
static char *character_set_filesystem_name;
static char *lc_messages;
static char *lc_time_names_name;
static char *my_bind_addr_str;
-static char *default_collation_name;
-static char *default_storage_engine_str;
+static char *default_collation_name;
+char *default_storage_engine;
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
static I_List<THD> thread_cache;
-static double long_query_time;
+static bool binlog_format_used= false;
+
+LEX_STRING opt_init_connect, opt_init_slave;
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
@@ -414,7 +293,7 @@ static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
my_bool opt_log, opt_slow_log;
-ulong log_output_options;
+ulonglong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
@@ -456,6 +335,13 @@ 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;
+char *opt_slave_skip_errors;
+
+/**
+ compatibility option:
+ - index usage hints (USE INDEX without a FOR clause) behave as in 5.0
+*/
+my_bool old_mode;
/*
Legacy global handlerton. These will be removed (please do not add more).
@@ -464,38 +350,18 @@ handlerton *heap_hton;
handlerton *myisam_hton;
handlerton *partition_hton;
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-const char *opt_ndbcluster_connectstring= 0;
-const char *opt_ndb_connectstring= 0;
-char opt_ndb_constrbuf[1024]= {0};
-unsigned opt_ndb_constrbuf_len= 0;
-my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
-ulong opt_ndb_cache_check_time;
-const char *opt_ndb_mgmd;
-ulong opt_ndb_nodeid;
-ulong ndb_extra_logging;
-#ifdef HAVE_NDB_BINLOG
-ulong ndb_report_thresh_binlog_epoch_slip;
-ulong ndb_report_thresh_binlog_mem_usage;
-#endif
-
-extern const char *ndb_distribution_names[];
-extern TYPELIB ndb_distribution_typelib;
-extern const char *opt_ndb_distribution;
-extern enum ndb_distribution opt_ndb_distribution_id;
-#endif
-my_bool opt_readonly, use_temp_pool, relay_log_purge;
+my_bool opt_readonly= 0, use_temp_pool, relay_log_purge;
my_bool relay_log_recovery;
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
my_bool opt_secure_auth= 0;
-char* opt_secure_file_priv= 0;
+char* opt_secure_file_priv;
my_bool opt_log_slow_admin_statements= 0;
my_bool opt_log_slow_slave_statements= 0;
my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
my_bool opt_super_large_pages= 0;
my_bool opt_myisam_use_mmap= 0;
-uint opt_large_page_size= 0;
+uint opt_large_page_size= 0;
#if defined(ENABLED_DEBUG_SYNC)
uint opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
@@ -514,27 +380,25 @@ const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
TYPELIB binlog_format_typelib=
{ array_elements(binlog_format_names) - 1, "",
binlog_format_names, NULL };
-ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
-const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_port_timeout;
-uint delay_key_write_options, protocol_version;
+uint delay_key_write_options;
+uint protocol_version;
uint lower_case_table_names;
uint tc_heuristic_recover= 0;
uint volatile thread_count;
int32 thread_running;
-ulonglong thd_startup_options;
+ulong thread_created;
ulong back_log, connect_timeout, concurrency, server_id;
ulong table_cache_size, table_def_size;
ulong what_to_log;
ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
ulong open_files_limit, max_binlog_size, max_relay_log_size;
ulong slave_net_timeout, slave_trans_retries;
-ulong slave_exec_mode_options;
-const char *slave_exec_mode_str= "STRICT";
+uint slave_exec_mode_options;
ulong thread_cache_size=0, thread_pool_size= 0;
ulong binlog_cache_size=0;
ulonglong max_binlog_cache_size=0;
@@ -550,7 +414,6 @@ ulong delayed_insert_errors,flush_time;
ulong specialflag=0;
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections, max_connect_errors;
-uint max_user_connections= 0;
/**
Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks.
@@ -573,7 +436,6 @@ uint sync_binlog_period= 0, sync_relaylog_period= 0,
sync_relayloginfo_period= 0, sync_masterinfo_period= 0;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
-const char *log_output_str= "FILE";
time_t server_start_time, flush_status_time;
@@ -584,25 +446,26 @@ char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
char mysql_real_data_home[FN_REFLEN],
lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN],
mysql_charsets_dir[FN_REFLEN],
- *opt_init_file, *opt_tc_log_file,
- def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+ *opt_init_file, *opt_tc_log_file;
+char *lc_messages_dir_ptr, *log_error_file_ptr;
char err_shared_dir[FN_REFLEN];
char mysql_unpacked_real_data_home[FN_REFLEN];
int mysql_unpacked_real_data_home_len;
+uint mysql_real_data_home_len, mysql_data_home_len= 1;
uint reg_ext_length;
const key_map key_map_empty(0);
key_map key_map_full(0); // Will be initialized later
-const char *opt_date_time_formats[3];
+DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format;
+Time_zone *default_tz;
-uint mysql_data_home_len;
-char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
+char *mysql_data_home= const_cast<char*>(".");
+const char *mysql_real_data_home_ptr= mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
-const char *myisam_recover_options_str="OFF";
-const char *myisam_stats_method_str="nulls_unequal";
+uint thread_handling;
-/** name of reference on left espression in rewritten IN subquery */
+/** name of reference on left expression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>";
/** name of additional condition */
const char *in_additional_cond= "<IN COND>";
@@ -622,7 +485,6 @@ int bootstrap_error;
FILE *stderror_file=0;
I_List<THD> threads;
-I_List<NAMED_LIST> key_caches;
Rpl_filter* rpl_filter;
Rpl_filter* binlog_filter;
@@ -700,10 +562,9 @@ static my_bool opt_do_pstack;
#endif /* HAVE_STACK_TRACE_ON_SEGV */
static my_bool opt_bootstrap, opt_myisam_log;
static int cleanup_done;
-static ulong opt_specialflag, opt_myisam_block_size;
+static ulong opt_specialflag;
static char *opt_update_logname, *opt_binlog_index_name;
-static char *opt_tc_heuristic_recover;
-static char *mysql_home_ptr, *pidfile_name_ptr;
+char *mysql_home_ptr, *pidfile_name_ptr;
static int defaults_argc;
static char **defaults_argv;
static char *opt_bin_logname;
@@ -764,7 +625,6 @@ int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
#endif
#ifdef HAVE_QUERY_CACHE
-static ulong query_cache_limit= 0;
ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
Query_cache query_cache;
#endif
@@ -776,8 +636,10 @@ HANDLE smem_event_connect_request= 0;
scheduler_functions thread_scheduler;
-#define SSL_VARS_NOT_STATIC
-#include "sslopt-vars.h"
+my_bool opt_use_ssl = 0;
+char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
+ *opt_ssl_cipher= NULL, *opt_ssl_key= NULL;
+
#ifdef HAVE_OPENSSL
#include <openssl/crypto.h>
#ifndef HAVE_YASSL
@@ -827,9 +689,6 @@ pthread_handler_t handle_connections_namedpipes(void *arg);
pthread_handler_t handle_connections_shared_memory(void *arg);
#endif
pthread_handler_t handle_slave(void *arg);
-static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
-static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
- const char *option, int *error);
static void clean_up(bool print_message);
static int test_if_case_insensitive(const char *dir_name);
@@ -1306,7 +1165,6 @@ void clean_up(bool print_message)
item_user_lock_free();
lex_free(); /* Free some memory */
item_create_cleanup();
- set_var_free();
if (!opt_noacl)
{
#ifdef HAVE_DLOPEN
@@ -1319,30 +1177,15 @@ void clean_up(bool print_message)
tc_log->close();
delegates_destroy();
xid_cache_free();
- delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
+ key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
multi_keycache_free();
free_status_vars();
end_thr_alarm(1); /* Free allocated memory */
my_free_open_file_info();
- my_free((char*) global_system_variables.date_format,
- MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) global_system_variables.time_format,
- MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) global_system_variables.datetime_format,
- MYF(MY_ALLOW_ZERO_PTR));
if (defaults_argv)
free_defaults(defaults_argv);
- my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
- my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
- my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
- my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
free_tmpdir(&mysql_tmpdir_list);
-#ifdef HAVE_REPLICATION
- my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
-#endif
x_free(opt_bin_logname);
- x_free(opt_relay_logname);
- x_free(opt_secure_file_priv);
bitmap_free(&temp_pool);
free_max_user_conn();
#ifdef HAVE_REPLICATION
@@ -1366,7 +1209,7 @@ void clean_up(bool print_message)
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
- if (print_message && /*errmesg &&*/ server_start_time)
+ if (print_message && my_default_lc_messages && server_start_time)
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
cleanup_errmsgs();
thread_scheduler.end();
@@ -1382,6 +1225,7 @@ void clean_up(bool print_message)
/* do the broadcast inside the lock to ensure that my_end() is not called */
(void) pthread_cond_broadcast(&COND_thread_count);
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ sys_var_end();
/*
The following lines may never be executed as the main thread may have
@@ -1461,7 +1305,6 @@ static void clean_up_mutexes()
(void) pthread_cond_destroy(&COND_flush_thread_cache);
(void) pthread_cond_destroy(&COND_manager);
}
-
#endif /*EMBEDDED_LIBRARY*/
@@ -2989,10 +2832,6 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
@param format_type What kind of format should be supported
@param var_ptr Pointer to variable that should be updated
- @note
- The default value is taken from either opt_date_time_formats[] or
- the ISO format (ANSI SQL)
-
@retval
0 ok
@retval
@@ -3000,27 +2839,21 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
*/
static bool init_global_datetime_format(timestamp_type format_type,
- DATE_TIME_FORMAT **var_ptr)
+ DATE_TIME_FORMAT *format)
{
- /* Get command line option */
- const char *str= opt_date_time_formats[format_type];
+ /*
+ Get command line option
+ format->format.str is already set by my_getopt
+ */
+ format->format.length= strlen(format->format.str);
- if (!str) // No specified format
+ if (parse_date_time_format(format_type, format))
{
- str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
- format_type);
- /*
- Set the "command line" option to point to the generated string so
- that we can set global formats back to default
- */
- opt_date_time_formats[format_type]= str;
+ fprintf(stderr, "Wrong date/time format specifier: %s\n",
+ format->format.str);
+ return true;
}
- if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
- {
- fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
- return 1;
- }
- return 0;
+ return false;
}
SHOW_VAR com_status_vars[]= {
@@ -3173,10 +3006,22 @@ SHOW_VAR com_status_vars[]= {
{NullS, NullS, SHOW_LONG}
};
+/**
+ Create the name of the default general log file
+
+ @param[IN] buff Location for building new string.
+ @param[IN] log_ext The extension for the file (e.g .log)
+ @returns Pointer to a new string containing the name
+*/
+static inline char *make_default_log_name(char *buff,const char* log_ext)
+{
+ return make_log_name(buff, default_logfile_name, log_ext);
+}
+
static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
{
- char buff[FN_REFLEN], *s;
+ char buff[FN_REFLEN];
umask(((~my_umask) & 0666));
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
tzset(); // Set tzname
@@ -3418,12 +3263,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (item_create_init())
return 1;
item_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);
@@ -3478,8 +3317,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.collation_database= default_charset_info;
global_system_variables.collation_connection= default_charset_info;
global_system_variables.character_set_results= default_charset_info;
- global_system_variables.character_set_client= default_charset_info;
-
+ global_system_variables.character_set_client= default_charset_info;
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
MY_CS_PRIMARY, MYF(MY_WME))))
@@ -3493,20 +3331,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
return 1;
}
global_system_variables.lc_time_names= my_default_lc_time_names;
-
- sys_init_connect.value_length= 0;
- if ((sys_init_connect.value= opt_init_connect))
- sys_init_connect.value_length= strlen(opt_init_connect);
- else
- sys_init_connect.value=my_strdup("",MYF(0));
- sys_init_connect.is_os_charset= TRUE;
-
- sys_init_slave.value_length= 0;
- if ((sys_init_slave.value= opt_init_slave))
- sys_init_slave.value_length= strlen(opt_init_slave);
- else
- sys_init_slave.value=my_strdup("",MYF(0));
- sys_init_slave.is_os_charset= TRUE;
/* check log options and issue warnings if needed */
if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
@@ -3521,13 +3345,17 @@ 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=file option.");
- 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);
+#define FIX_LOG_VAR(VAR, ALT) \
+ if (!VAR || !*VAR) \
+ { \
+ x_free(VAR); /* it could be an allocated empty string "" */ \
+ VAR= my_strdup(ALT, MYF(0)); \
+ }
- 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);
+ FIX_LOG_VAR(opt_logname,
+ make_default_log_name(buff, ".log"));
+ FIX_LOG_VAR(opt_slow_logname,
+ make_default_log_name(buff, "-slow.log"));
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the debug sync facility. See debug_sync.cc. */
@@ -3790,7 +3618,7 @@ static void end_ssl()
static int init_server_components()
{
- FILE* reopen;
+ FILE *reopen;
DBUG_ENTER("init_server_components");
/*
We need to call each of these following functions to ensure that
@@ -3799,7 +3627,6 @@ static int init_server_components()
if (table_cache_init() | table_def_init() | hostname_cache_init())
unireg_abort(1);
- query_cache_result_size_limit(query_cache_limit);
query_cache_set_min_res_unit(query_cache_min_res_unit);
query_cache_init();
query_cache_resize(query_cache_size);
@@ -3826,7 +3653,7 @@ static int init_server_components()
fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
MY_UNPACK_FILENAME | MY_SAFE_PATH);
if (!log_error_file[0])
- opt_error_log= 1; // Too long file name
+ opt_error_log= 0; // Too long file name
else
{
#ifndef EMBEDDED_LIBRARY
@@ -3913,27 +3740,9 @@ with --log-bin instead.");
sql_print_warning("You need to use --log-bin to make "
"--log-slave-updates work.");
}
- if (!opt_bin_log)
- {
- if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
- {
- sql_print_warning("You need to use --log-bin to make "
- "--binlog-format work.");
-
- global_system_variables.binlog_format= opt_binlog_format_id;
- }
- else
- {
- global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
- }
- }
- else
- if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
- global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
- else
- {
- DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
- }
+ if (!opt_bin_log && binlog_format_used)
+ sql_print_warning("You need to use --log-bin to make "
+ "--binlog-format work.");
/* Check that we have not let the format to unspecified at this point */
DBUG_ASSERT((uint)global_system_variables.binlog_format <=
@@ -4015,19 +3824,21 @@ a file name for --log-bin-index option", opt_binlog_index_name);
if (ha_init_errors())
DBUG_RETURN(1);
- {
- 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 initialize plugins.");
- unireg_abort(1);
- }
- plugins_are_initialized= TRUE; /* Don't separate from init function */
+ 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 initialize plugins.");
+ unireg_abort(1);
}
+ plugins_are_initialized= TRUE; /* Don't separate from init function */
- if (opt_help)
- unireg_abort(0);
+ have_csv= plugin_status(STRING_WITH_LEN("csv"),
+ MYSQL_STORAGE_ENGINE_PLUGIN);
+ have_ndbcluster= plugin_status(STRING_WITH_LEN("ndbcluster"),
+ MYSQL_STORAGE_ENGINE_PLUGIN);
+ have_partitioning= plugin_status(STRING_WITH_LEN("partition"),
+ MYSQL_STORAGE_ENGINE_PLUGIN);
/* we do want to exit if there are any other unknown options */
if (defaults_argc > 1)
@@ -4060,6 +3871,9 @@ a file name for --log-bin-index option", opt_binlog_index_name);
}
}
+ if (opt_help)
+ unireg_abort(0);
+
/* if the errmsg.sys is not loaded, terminate to maintain behaviour */
if (!DEFAULT_ERRMSGS[0][0])
unireg_abort(1);
@@ -4111,42 +3925,37 @@ a file name for --log-bin-index option", opt_binlog_index_name);
#endif
/*
- Check that the default storage engine is actually available.
+ Set the default storage engine
*/
- if (default_storage_engine_str)
+ LEX_STRING name= { default_storage_engine, strlen(default_storage_engine) };
+ plugin_ref plugin;
+ handlerton *hton;
+ if ((plugin= ha_resolve_by_name(0, &name)))
+ hton= plugin_data(plugin, handlerton*);
+ else
{
- LEX_STRING name= { default_storage_engine_str,
- strlen(default_storage_engine_str) };
- plugin_ref plugin;
- handlerton *hton;
-
- if ((plugin= ha_resolve_by_name(0, &name)))
- hton= plugin_data(plugin, handlerton*);
- else
+ sql_print_error("Unknown/unsupported storage engine: %s",
+ default_storage_engine);
+ unireg_abort(1);
+ }
+ if (!ha_storage_engine_is_enabled(hton))
+ {
+ if (!opt_bootstrap)
{
- sql_print_error("Unknown/unsupported table type: %s",
- default_storage_engine_str);
+ sql_print_error("Default storage engine (%s) is not available",
+ default_storage_engine);
unireg_abort(1);
}
- if (!ha_storage_engine_is_enabled(hton))
- {
- if (!opt_bootstrap)
- {
- sql_print_error("Default storage engine (%s) is not available",
- default_storage_engine_str);
- unireg_abort(1);
- }
- 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;
- }
+ 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;
}
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
@@ -4446,10 +4255,6 @@ int main(int argc, char **argv)
check_data_home(mysql_real_data_home);
if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
unireg_abort(1); /* purecov: inspected */
- mysql_data_home= mysql_data_home_buff;
- mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
- mysql_data_home[1]=0;
- mysql_data_home_len= 2;
if ((user_info= check_user(mysqld_user)))
{
@@ -4517,6 +4322,7 @@ int main(int argc, char **argv)
unlink(mysqld_unix_port);
exit(1);
}
+
if (!opt_noacl)
(void) grant_init();
@@ -4555,7 +4361,7 @@ int main(int argc, char **argv)
bootstrap(stdin);
unireg_abort(bootstrap_error ? 1 : 0);
}
- if (opt_init_file)
+ if (opt_init_file && *opt_init_file)
{
if (read_init_file(opt_init_file))
unireg_abort(1);
@@ -5611,179 +5417,13 @@ error:
Handle start options
******************************************************************************/
-enum options_mysqld
-{
- OPT_ISAM_LOG=256, OPT_SKIP_NEW,
- OPT_SKIP_GRANT, OPT_SKIP_LOCK,
- OPT_ENABLE_LOCK, OPT_USE_LOCKING,
- OPT_SOCKET, OPT_UPDATE_LOG,
- OPT_BIN_LOG, OPT_SKIP_RESOLVE,
- OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
- OPT_BIND_ADDRESS, OPT_PID_FILE,
- OPT_SKIP_PRIOR, OPT_BIG_TABLES,
- OPT_STANDALONE, OPT_ONE_THREAD,
- OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
- OPT_SKIP_HOST_CACHE, OPT_SHORT_LOG_FORMAT,
- OPT_FLUSH, OPT_SAFE,
- OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
- OPT_STORAGE_ENGINE, OPT_INIT_FILE,
- OPT_DELAY_KEY_WRITE_ALL, OPT_SLOW_QUERY_LOG,
- OPT_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
- OPT_MASTER_INFO_FILE,
- OPT_MASTER_RETRY_COUNT, OPT_LOG_TC, OPT_LOG_TC_SIZE,
- OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
- OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
- OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
- OPT_BINLOG_FORMAT,
-#ifndef DBUG_OFF
- OPT_BINLOG_SHOW_XID,
-#endif
- OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
- OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
- OPT_MEMLOCK, OPT_MYISAM_RECOVER,
- OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
- 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_LOG_BIN_TRUST_FUNCTION_CREATORS,
- 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,
- OPT_NDB_MGMD, OPT_NDB_NODEID,
- OPT_NDB_DISTRIBUTION,
- OPT_NDB_INDEX_STAT_ENABLE,
- OPT_NDB_EXTRA_LOGGING,
- OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
- OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
- OPT_NDB_USE_COPYING_ALTER_TABLE,
- OPT_SKIP_SAFEMALLOC,
- OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
- OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
- OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
- OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
- OPT_HAVE_NAMED_PIPE,
- OPT_DO_PSTACK, OPT_EVENT_SCHEDULER, OPT_REPORT_HOST,
- OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
- OPT_SHOW_SLAVE_AUTH_INFO,
- OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
- OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
- OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
- OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
- OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
- OPT_SSL_CAPATH, OPT_SSL_CIPHER,
- OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
- OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
- OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
- OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
- OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
- OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
- OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
- OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
- OPT_LONG_QUERY_TIME,
- OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
- OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
- OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
- OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
- OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
- OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
- OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
- OPT_MAX_LENGTH_FOR_SORT_DATA,
- OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
- OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
- OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
- OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
- OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
- OPT_MYISAM_MMAP_SIZE,
- OPT_MYISAM_STATS_METHOD,
- OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
- OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
- OPT_OPEN_FILES_LIMIT,
- OPT_PRELOAD_BUFFER_SIZE,
- OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
- OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
- OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
- OPT_RELAY_LOG_PURGE,
- OPT_RELAY_LOG_RECOVERY,
- OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
- OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
- OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
- OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
- OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
- OPT_WAIT_TIMEOUT,
- OPT_ERROR_LOG_FILE,
- OPT_DEFAULT_WEEK_FORMAT,
- OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
- OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
- OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
- OPT_SYNC_FRM, OPT_SYNC_BINLOG,
- OPT_SYNC_REPLICATION,
- OPT_SYNC_REPLICATION_SLAVE_ID,
- OPT_SYNC_REPLICATION_TIMEOUT,
- OPT_ENABLE_SHARED_MEMORY,
- OPT_SHARED_MEMORY_BASE_NAME,
- OPT_OLD_PASSWORDS,
- OPT_OLD_ALTER_TABLE,
- OPT_EXPIRE_LOGS_DAYS,
- OPT_GROUP_CONCAT_MAX_LEN,
- OPT_DEFAULT_COLLATION,
- OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
- OPT_CHARACTER_SET_FILESYSTEM,
- OPT_LC_ERROR_MESSAGES,
- OPT_LC_TIME_NAMES,
- OPT_INIT_CONNECT,
- OPT_INIT_SLAVE,
- OPT_SECURE_AUTH,
- OPT_DATE_FORMAT,
- OPT_TIME_FORMAT,
- OPT_DATETIME_FORMAT,
- OPT_LOG_QUERIES_NOT_USING_INDEXES,
- OPT_DEFAULT_TIME_ZONE,
- OPT_SYSDATE_IS_NOW,
- OPT_OPTIMIZER_SEARCH_DEPTH,
- OPT_OPTIMIZER_PRUNE_LEVEL,
- OPT_OPTIMIZER_SWITCH,
- OPT_UPDATABLE_VIEWS_WITH_LIMIT,
- OPT_SP_AUTOMATIC_PRIVILEGES,
- OPT_MAX_SP_RECURSION_DEPTH,
- OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
- OPT_ENABLE_LARGE_PAGES,
- OPT_ENABLE_SUPER_LARGE_PAGES,
- OPT_TIMED_MUTEXES,
- 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_PROFILING,
- OPT_KEEP_FILES_ON_CREATE,
- OPT_GENERAL_LOG,
- OPT_SLOW_LOG,
- OPT_THREAD_HANDLING,
- OPT_INNODB_ROLLBACK_ON_TIMEOUT,
- OPT_SECURE_FILE_PRIV,
- OPT_MIN_EXAMINED_ROW_LIMIT,
- OPT_LOG_SLOW_SLAVE_STATEMENTS,
-#if defined(ENABLED_DEBUG_SYNC)
- OPT_DEBUG_SYNC_TIMEOUT,
-#endif /* defined(ENABLED_DEBUG_SYNC) */
- OPT_OLD_MODE,
- OPT_SLAVE_EXEC_MODE,
- OPT_GENERAL_LOG_FILE,
- OPT_SLOW_QUERY_LOG_FILE,
- OPT_IGNORE_BUILTIN_INNODB,
- OPT_SYNC_RELAY_LOG,
- OPT_SYNC_RELAY_LOG_INFO,
- OPT_SYNC_MASTER_INFO
-};
-
+DYNAMIC_ARRAY all_options;
-#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
+/**
+ System variables are automatically command-line options (few
+ exceptions are documented in sys_var.h), so don't need
+ to be listed here.
+*/
struct my_option my_long_options[] =
{
@@ -5791,12 +5431,12 @@ struct my_option my_long_options[] =
(uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
#ifdef HAVE_REPLICATION
- {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
+ {"abort-slave-event-count", 0,
"Option used by mysql-test for debugging and testing of replication.",
(uchar**) &abort_slave_event_count, (uchar**) &abort_slave_event_count,
0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
- {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
+ {"allow-suspicious-udfs", 0,
"Allows use of UDFs consisting of only one symbol xxx() "
"without corresponding xxx_init() or xxx_deinit(). That also means "
"that one can load any function from any library, for example exit() "
@@ -5805,51 +5445,16 @@ struct my_option my_long_options[] =
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"auto-increment-increment", OPT_AUTO_INCREMENT,
- "Auto-increment columns are incremented by this",
- (uchar**) &global_system_variables.auto_increment_increment,
- (uchar**) &max_system_variables.auto_increment_increment, 0, GET_ULONG,
- OPT_ARG, 1, 1, 65535, 0, 1, 0 },
- {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
- "Offset added to Auto-increment columns. Used when auto-increment-increment != 1",
- (uchar**) &global_system_variables.auto_increment_offset,
- (uchar**) &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
- 1, 1, 65535, 0, 1, 0 },
- {"automatic-sp-privileges", OPT_SP_AUTOMATIC_PRIVILEGES,
- "Creating and dropping stored procedures alters ACLs. Disable with --skip-automatic-sp-privileges.",
- (uchar**) &sp_automatic_privileges, (uchar**) &sp_automatic_privileges,
- 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
- {"basedir", 'b',
- "Path to installation directory. All paths are usually resolved relative to this.",
- (uchar**) &mysql_home_ptr, (uchar**) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
- {"big-tables", OPT_BIG_TABLES,
- "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors).",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
(uchar**) &my_bind_addr_str, (uchar**) &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"binlog_format", OPT_BINLOG_FORMAT,
- "Does not have any effect without '--log-bin'. "
- "Tell the master the form of binary logging to use: either 'row' for "
- "row-based binary logging, or 'statement' for statement-based binary "
- "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
- "for those statements where only row-based is correct: those which "
- "involve user-defined functions (i.e. UDFs) or the UUID() function; for "
- "those, row-based binary logging is automatically used. "
-#ifdef HAVE_NDB_BINLOG
- "If ndbcluster is enabled and binlog_format is `mixed', the format switches"
- " to 'row' and back implicitly per each query accessing a NDB table."
-#endif
- ,(uchar**) &opt_binlog_format, (uchar**) &opt_binlog_format,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
"Tells the master that updates to the given database should not be logged tothe binary log.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+ {"binlog-row-event-max-size", 0,
"The maximum size of a row-based binary log event in bytes. Rows will be "
"grouped into events smaller than this size if possible. "
"The value has to be a multiple of 256.",
@@ -5864,12 +5469,12 @@ struct my_option my_long_options[] =
{"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
+ {"character-set-client-handshake", 0,
"Don't ignore client side character set value sent during handshake.",
(uchar**) &opt_character_set_client_handshake,
(uchar**) &opt_character_set_client_handshake,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
- {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
+ {"character-set-filesystem", 0,
"Set the filesystem character set.",
(uchar**) &character_set_filesystem_name,
(uchar**) &character_set_filesystem_name,
@@ -5877,229 +5482,114 @@ struct my_option my_long_options[] =
{"character-set-server", 'C', "Set the default character set.",
(uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"character-sets-dir", OPT_CHARSETS_DIR,
- "Directory where character sets are.", (uchar**) &charsets_dir,
- (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"chroot", 'r', "Chroot mysqld daemon during startup.",
(uchar**) &mysqld_chroot, (uchar**) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
- {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
+ {"collation-server", 0, "Set the default collation.",
(uchar**) &default_collation_name, (uchar**) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
- (uchar**) &global_system_variables.completion_type,
- (uchar**) &max_system_variables.completion_type, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
- {"concurrent-insert", OPT_CONCURRENT_INSERT,
- "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0",
- (uchar**) &myisam_concurrent_insert, (uchar**) &myisam_concurrent_insert,
- 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
{"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.",
(uchar**) &opt_console, (uchar**) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
{"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"datadir", 'h', "Path to the database root.", (uchar**) &mysql_data_home,
- (uchar**) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifndef DBUG_OFF
- {"debug", '#', "Debug log.", (uchar**) &default_dbug_option,
- (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).",
(uchar**) &default_character_set_name, (uchar**) &default_character_set_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).",
+ {"default-collation", 0, "Set the default collation (deprecated option, use --collation-server instead).",
(uchar**) &default_collation_name, (uchar**) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"default-storage-engine", OPT_STORAGE_ENGINE,
- "Set the default storage engine (table type) for tables.",
- (uchar**)&default_storage_engine_str, (uchar**)&default_storage_engine_str,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
+ {"default-storage-engine", 0, "The default storage engine for new tables",
+ (uchar**) &default_storage_engine, 0, 0, GET_STR, REQUIRED_ARG,
+ (longlong)"MyISAM", 0, 0, 0, 0, 0 },
+ {"default-time-zone", 0, "Set the default time zone.",
(uchar**) &default_tz_name, (uchar**) &default_tz_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
- 0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
"Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_OPENSSL
- {"des-key-file", OPT_DES_KEY_FILE,
+ {"des-key-file", 0,
"Load keys for des_encrypt() and des_encrypt from given file.",
(uchar**) &des_key_file, (uchar**) &des_key_file, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
#endif /* HAVE_OPENSSL */
#ifdef HAVE_REPLICATION
- {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
+ {"disconnect-slave-event-count", 0,
"Option used by mysql-test for debugging and testing of replication.",
(uchar**) &disconnect_slave_event_count,
(uchar**) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
#endif /* HAVE_REPLICATION */
- {"enable-locking", OPT_ENABLE_LOCK,
+ {"enable-locking", 0,
"Deprecated option, use --external-locking instead.",
(uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef _WIN32
- {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT).",
- (uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL,
- NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
#ifdef HAVE_STACK_TRACE_ON_SEGV
- {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
+ {"enable-pstack", 0, "Print a symbolic stack trace on failure.",
(uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
#endif /* HAVE_STACK_TRACE_ON_SEGV */
- {"engine-condition-pushdown",
- OPT_ENGINE_CONDITION_PUSHDOWN,
- "Push supported query conditions to the storage engine.",
- (uchar**) &global_system_variables.engine_condition_pushdown,
- (uchar**) &global_system_variables.engine_condition_pushdown,
- 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
/* See how it's handled in get_one_option() */
- {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.",
- NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"external-locking", OPT_USE_LOCKING, "Use system (external) locking (disabled by default). With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.",
+ {"external-locking", 0, "Use system (external) locking (disabled by default). With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.",
(uchar**) &opt_external_locking, (uchar**) &opt_external_locking,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
/* We must always support the next option to make scripts like mysqltest
easier to do */
- {"gdb", OPT_DEBUGGING,
+ {"gdb", 0,
"Set up signals usable for debugging",
(uchar**) &opt_debugging, (uchar**) &opt_debugging,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"general_log", OPT_GENERAL_LOG,
- "Enable|disable general log", (uchar**) &opt_log,
- (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_LARGE_PAGE_OPTION
- {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
-Disable with --skip-large-pages.",
- (uchar**) &opt_large_pages, (uchar**) &opt_large_pages, 0, GET_BOOL,
- NO_ARG, 0, 0, 1, 0, 1, 0},
- {"super-large-pages", OPT_ENABLE_SUPER_LARGE_PAGES,
- "Enable support for super large pages. \
-Disable with --skip-super-large-pages.",
+ {"super-large-pages", 0, "Enable support for super large pages.",
(uchar**) &opt_super_large_pages, (uchar**) &opt_super_large_pages, 0,
- GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ GET_BOOL, OPT_ARG, 0, 0, 1, 0, 1, 0},
#endif
- {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
- "Disable initialization of builtin InnoDB plugin",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection",
- (uchar**) &opt_init_connect, (uchar**) &opt_init_connect, 0, GET_STR_ALLOC,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifndef DISABLE_GRANT_OPTIONS
- {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
- (uchar**) &opt_init_file, (uchar**) &opt_init_file, 0, GET_STR, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
-#endif
- {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
-each time the SQL thread starts.",
- (uchar**) &opt_init_slave, (uchar**) &opt_init_slave, 0, GET_STR_ALLOC,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"language", 'L',
"Client error messages in given language. May be given as a full path. "
"Deprecated. Use --lc-messages-dir instead.",
(uchar**) &lc_messages_dir_ptr, (uchar**) &lc_messages_dir_ptr, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"lc-messages-dir", 'L',
- "Directory where error messages are.", (uchar**) &lc_messages_dir_ptr,
- (uchar**) &lc_messages_dir_ptr, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"lc-messages", OPT_LC_ERROR_MESSAGES,
+ {"lc-messages", 0,
"Set the language used for the error messages.",
(uchar**) &lc_messages, (uchar**) &lc_messages, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0 },
- {"lc-time-names", OPT_LC_TIME_NAMES,
+ {"lc-time-names", 0,
"Set the language used for the month names and the days of the week.",
(uchar**) &lc_time_names_name,
(uchar**) &lc_time_names_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"local-infile", OPT_LOCAL_INFILE,
- "Enable/disable LOAD DATA LOCAL INFILE (takes values 1|0).",
- (uchar**) &opt_local_infile,
- (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG,
- 1, 0, 0, 0, 0, 0},
{"log", 'l', "Log connections and queries to file (deprecated option, use "
- "--general_log/--general_log_file instead).", (uchar**) &opt_logname,
- (uchar**) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"general_log_file", OPT_GENERAL_LOG_FILE,
- "Log connections and queries to given file.", (uchar**) &opt_logname,
- (uchar**) &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "--general-log/--general-log-file instead).", (uchar**) &opt_logname,
+ (uchar**) &opt_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-bin", OPT_BIN_LOG,
"Log update queries in binary format. Optional (but strongly recommended "
"to avoid replication problems if server's hostname changes) argument "
"should be the chosen location for the binary log files.",
(uchar**) &opt_bin_logname, (uchar**) &opt_bin_logname, 0, GET_STR_ALLOC,
OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"log-bin-index", OPT_BIN_LOG_INDEX,
+ {"log-bin-index", 0,
"File that holds the names for last binary log files.",
(uchar**) &opt_binlog_index_name, (uchar**) &opt_binlog_index_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
- /*
- In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
- log-bin-trust-function-creators but kept also the old name for
- compatibility; the behaviour was also changed to apply only to functions
- (and triggers). In a future release this old name could be removed.
- */
- {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
- "(deprecated) Use log-bin-trust-function-creators.",
- (uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
- /*
- This option starts with "log-bin" to emphasize that it is specific of
- binary logging.
- */
- {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
- "If equal to 0 (the default), then when --log-bin is used, creation of "
- "a stored function (or trigger) is allowed only to users having the SUPER privilege "
- "and only if this stored function (trigger) may not break binary logging."
- "Note that if ALL connections to this server ALWAYS use row-based binary "
- "logging, the security issues do not exist and the binary logging cannot "
- "break, so you can safely set this to 1."
- ,(uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
- (uchar**) &log_error_file_ptr, (uchar**) &log_error_file_ptr, 0, GET_STR,
- OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
(uchar**) &myisam_log_filename, (uchar**) &myisam_log_filename, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0},
{"log-long-format", '0',
"Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_CSV_STORAGE_ENGINE
- {"log-output", OPT_LOG_OUTPUT,
- "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
- "FILE or NONE.",
- (uchar**) &log_output_str, (uchar**) &log_output_str, 0,
- GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#endif
- {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
- "Log queries that are executed without benefit of any index to the slow log if it is open.",
- (uchar**) &opt_log_queries_not_using_indexes, (uchar**) &opt_log_queries_not_using_indexes,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log-short-format", OPT_SHORT_LOG_FORMAT,
+ {"log-short-format", 0,
"Don't log extra information to update and slow-query logs.",
(uchar**) &opt_short_log_format, (uchar**) &opt_short_log_format,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
- "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
- (uchar**) &opt_log_slave_updates, (uchar**) &opt_log_slave_updates, 0, GET_BOOL,
- NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
+ {"log-slow-admin-statements", 0,
"Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
(uchar**) &opt_log_slow_admin_statements,
(uchar**) &opt_log_slow_admin_statements,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
+ {"log-slow-slave-statements", 0,
"Log slow statements executed by slave thread to the slow log if it is open.",
(uchar**) &opt_log_slow_slave_statements,
(uchar**) &opt_log_slow_slave_statements,
@@ -6109,19 +5599,15 @@ each time the SQL thread starts.",
"mysql.slow_log or hostname-slow.log if --log-output=file is used. "
"Must be enabled to activate other slow log options. "
"Deprecated option, use --slow-query-log/--slow-query-log-file instead.",
- (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
+ (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR_ALLOC, OPT_ARG,
0, 0, 0, 0, 0, 0},
- {"slow-query-log-file", OPT_SLOW_QUERY_LOG_FILE,
- "Log slow queries to given log file. Defaults logging to hostname-slow.log. Must be enabled to activate other slow log options.",
- (uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"log-tc", OPT_LOG_TC,
+ {"log-tc", 0,
"Path to transaction coordinator log (used for transactions that affect "
"more than one storage engine, when binary log is disabled)",
(uchar**) &opt_tc_log_file, (uchar**) &opt_tc_log_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_MMAP
- {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
+ {"log-tc-size", 0, "Size of transaction coordinator log.",
(uchar**) &opt_tc_log_size, (uchar**) &opt_tc_log_size, 0, GET_ULONG,
REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
TC_LOG_PAGE_SIZE, 0},
@@ -6131,199 +5617,37 @@ each time the SQL thread starts.",
log and this option justs turns on --log-bin instead.",
(uchar**) &opt_update_logname, (uchar**) &opt_update_logname, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"log-warnings", 'W', "Log some not critical warnings to the log file.",
- (uchar**) &global_system_variables.log_warnings,
- (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
- 0, 0, 0},
- {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
- "INSERT/DELETE/UPDATE has lower priority than selects.",
- (uchar**) &global_system_variables.low_priority_updates,
- (uchar**) &max_system_variables.low_priority_updates,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"master-info-file", OPT_MASTER_INFO_FILE,
+ {"master-info-file", 0,
"The location and name of the file that remembers the master and where the I/O replication \
thread is in the master's binlogs.",
(uchar**) &master_info_file, (uchar**) &master_info_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"master-retry-count", OPT_MASTER_RETRY_COUNT,
+ {"master-retry-count", 0,
"The number of tries the slave will make to connect to the master before giving up.",
(uchar**) &master_retry_count, (uchar**) &master_retry_count, 0, GET_ULONG,
REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
- {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
+ {"init-rpl-role", 0, "Set the replication role.",
+ (uchar**)&rpl_status, (uchar**)&rpl_status, &rpl_role_typelib,
+ GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"max-binlog-dump-events", 0,
"Option used by mysql-test for debugging and testing of replication.",
(uchar**) &max_binlog_dump_events, (uchar**) &max_binlog_dump_events, 0,
GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif /* HAVE_REPLICATION */
- {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
+ {"memlock", 0, "Lock mysqld in memory.", (uchar**) &locked_in_memory,
(uchar**) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"myisam-recover", OPT_MYISAM_RECOVER,
- "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
- (uchar**) &myisam_recover_options_str, (uchar**) &myisam_recover_options_str, 0,
- GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
- "Connect string for ndbcluster.",
- (uchar**) &opt_ndb_connectstring,
- (uchar**) &opt_ndb_connectstring,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"ndb-mgmd-host", OPT_NDB_MGMD,
- "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
- (uchar**) &opt_ndb_mgmd,
- (uchar**) &opt_ndb_mgmd,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"ndb-nodeid", OPT_NDB_NODEID,
- "Nodeid for this mysqlserver in the cluster.",
- (uchar**) &opt_ndb_nodeid,
- (uchar**) &opt_ndb_nodeid,
- 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
- "Specify number of autoincrement values that are prefetched.",
- (uchar**) &global_system_variables.ndb_autoincrement_prefetch_sz,
- (uchar**) &max_system_variables.ndb_autoincrement_prefetch_sz,
- 0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
- {"ndb-force-send", OPT_NDB_FORCE_SEND,
- "Force send of buffers to ndb immediately without waiting for "
- "other threads.",
- (uchar**) &global_system_variables.ndb_force_send,
- (uchar**) &global_system_variables.ndb_force_send,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb_force_send", OPT_NDB_FORCE_SEND,
- "same as --ndb-force-send.",
- (uchar**) &global_system_variables.ndb_force_send,
- (uchar**) &global_system_variables.ndb_force_send,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb-extra-logging", OPT_NDB_EXTRA_LOGGING,
- "Turn on more logging in the error log.",
- (uchar**) &ndb_extra_logging,
- (uchar**) &ndb_extra_logging,
- 0, GET_INT, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef HAVE_NDB_BINLOG
- {"ndb-report-thresh-binlog-epoch-slip", OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
- "Threshold on number of epochs to be behind before reporting binlog status. "
- "E.g. 3 means that if the difference between what epoch has been received "
- "from the storage nodes and what has been applied to the binlog is 3 or more, "
- "a status message will be sent to the cluster log.",
- (uchar**) &ndb_report_thresh_binlog_epoch_slip,
- (uchar**) &ndb_report_thresh_binlog_epoch_slip,
- 0, GET_ULONG, REQUIRED_ARG, 3, 0, 256, 0, 0, 0},
- {"ndb-report-thresh-binlog-mem-usage", OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
- "Threshold on percentage of free memory before reporting binlog status. E.g. "
- "10 means that if amount of available memory for receiving binlog data from "
- "the storage nodes goes below 10%, "
- "a status message will be sent to the cluster log.",
- (uchar**) &ndb_report_thresh_binlog_mem_usage,
- (uchar**) &ndb_report_thresh_binlog_mem_usage,
- 0, GET_ULONG, REQUIRED_ARG, 10, 0, 100, 0, 0, 0},
-#endif
- {"ndb-use-exact-count", OPT_NDB_USE_EXACT_COUNT,
- "Use exact records count during query planning and for fast "
- "select count(*), disable for faster queries.",
- (uchar**) &global_system_variables.ndb_use_exact_count,
- (uchar**) &global_system_variables.ndb_use_exact_count,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
- "same as --ndb-use-exact-count.",
- (uchar**) &global_system_variables.ndb_use_exact_count,
- (uchar**) &global_system_variables.ndb_use_exact_count,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
- "Use transactions for large inserts, if enabled then large "
- "inserts will be split into several smaller transactions",
- (uchar**) &global_system_variables.ndb_use_transactions,
- (uchar**) &global_system_variables.ndb_use_transactions,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
- "same as --ndb-use-transactions.",
- (uchar**) &global_system_variables.ndb_use_transactions,
- (uchar**) &global_system_variables.ndb_use_transactions,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- {"ndb-shm", OPT_NDB_SHM,
- "Use shared memory connections when available.",
- (uchar**) &opt_ndb_shm,
- (uchar**) &opt_ndb_shm,
- 0, GET_BOOL, OPT_ARG, OPT_NDB_SHM_DEFAULT, 0, 0, 0, 0, 0},
- {"ndb-optimized-node-selection", OPT_NDB_OPTIMIZED_NODE_SELECTION,
- "Select nodes for transactions in a more optimal way.",
- (uchar**) &opt_ndb_optimized_node_selection,
- (uchar**) &opt_ndb_optimized_node_selection,
- 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
- { "ndb-cache-check-time", OPT_NDB_CACHE_CHECK_TIME,
- "A dedicated thread is created to, at the given millisecons interval, invalidate the query cache if another MySQL server in the cluster has changed the data in the database.",
- (uchar**) &opt_ndb_cache_check_time, (uchar**) &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
- 0, 0, LONG_TIMEOUT, 0, 1, 0},
- {"ndb-index-stat-enable", OPT_NDB_INDEX_STAT_ENABLE,
- "Use ndb index statistics in query optimization.",
- (uchar**) &global_system_variables.ndb_index_stat_enable,
- (uchar**) &max_system_variables.ndb_index_stat_enable,
- 0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 0, 0},
-#endif
- {"ndb-use-copying-alter-table",
- OPT_NDB_USE_COPYING_ALTER_TABLE,
- "Force ndbcluster to always copy tables at alter table (should only be used if on-line alter table fails).",
- (uchar**) &global_system_variables.ndb_use_copying_alter_table,
- (uchar**) &global_system_variables.ndb_use_copying_alter_table,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"new", 'n', "Use very new possible 'unsafe' functions.",
- (uchar**) &global_system_variables.new_mode,
- (uchar**) &max_system_variables.new_mode,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef NOT_YET
- {"no-mix-table-types", OPT_NO_MIX_TYPE, "Don't allow commands with uses two different table types.",
- (uchar**) &opt_no_mix_types, (uchar**) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
-#endif
- {"old-alter-table", OPT_OLD_ALTER_TABLE,
- "Use old, non-optimized alter table.",
- (uchar**) &global_system_variables.old_alter_table,
- (uchar**) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
- {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
- (uchar**) &global_system_variables.old_passwords,
- (uchar**) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
{"one-thread", OPT_ONE_THREAD,
"(deprecated): Only use one thread (for debugging under Linux). Use thread-handling=no-threads instead",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
+ {"old-style-user-limits", 0,
"Enable old-style user limits (before 5.0.3 user resources were counted per each user+host vs. per account)",
(uchar**) &opt_old_style_user_limits, (uchar**) &opt_old_style_user_limits,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
- (uchar**) &pidfile_name_ptr, (uchar**) &pidfile_name_ptr, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"port", 'P', "Port number to use for connection or 0 for default to, in "
- "order of preference, my.cnf, $MYSQL_TCP_PORT, "
-#if MYSQL_PORT_DEFAULT == 0
- "/etc/services, "
-#endif
- "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
- (uchar**) &mysqld_port,
- (uchar**) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
+ {"port-open-timeout", 0,
"Maximum time in seconds to wait for the port to become free. "
"(Default: no wait)", (uchar**) &mysqld_port_timeout,
(uchar**) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#if defined(ENABLED_PROFILING)
- {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory",
- (uchar**) &global_system_variables.profiling_history_size,
- (uchar**) &max_system_variables.profiling_history_size,
- 0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
-#endif
- {"relay-log", OPT_RELAY_LOG,
- "The location and name to use for relay logs.",
- (uchar**) &opt_relay_logname, (uchar**) &opt_relay_logname, 0,
- GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"relay-log-index", OPT_RELAY_LOG_INDEX,
- "The location and name to use for the file that keeps a list of the last \
-relay logs.",
- (uchar**) &opt_relaylog_index_name, (uchar**) &opt_relaylog_index_name, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
- "The location and name of the file that remembers where the SQL replication \
-thread is in the relay logs.",
- (uchar**) &relay_log_info_file, (uchar**) &relay_log_info_file, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-do-db", OPT_REPLICATE_DO_DB,
"Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -6340,7 +5664,7 @@ thread is in the relay logs.",
"Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
- {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
+ {"replicate-same-server-id", 0,
"In replication, if set to 1, do not skip events having our server id. \
Default value is 0 (to break infinite loops in circular replication). \
Can't be set to 1 if --log-slave-updates is used.",
@@ -6354,67 +5678,34 @@ Can't be set to 1 if --log-slave-updates is used.",
{"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
"Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- // In replication, we may need to tell the other servers how to connect
- {"report-host", OPT_REPORT_HOST,
- "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.",
- (uchar**) &report_host, (uchar**) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
- 0, 0, 0, 0},
- {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
- (uchar**) &report_password, (uchar**) &report_password, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"report-port", OPT_REPORT_PORT,
- "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.",
- (uchar**) &report_port, (uchar**) &report_port, 0, GET_UINT, REQUIRED_ARG,
- MYSQL_PORT, 0, 0, 0, 0, 0},
- {"report-user", OPT_REPORT_USER, "Undocumented.", (uchar**) &report_user,
- (uchar**) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.",
- (uchar**) &rpl_recovery_rank, (uchar**) &rpl_recovery_rank, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef TO_BE_DELETED
- {"safe-show-database", OPT_SAFE_SHOW_DB,
+ {"safe-show-database", 0,
"Deprecated option; use GRANT SHOW DATABASES instead...",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"safe-user-create", OPT_SAFE_USER_CREATE,
+ {"safe-user-create", 0,
"Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
(uchar**) &opt_safe_user_create, (uchar**) &opt_safe_user_create, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
- "Simulate memory shortage when compiled with the --with-debug=full option.",
- 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
- (uchar**) &opt_secure_auth, (uchar**) &opt_secure_auth, 0, GET_BOOL, NO_ARG,
- my_bool(0), 0, 0, 0, 0, 0},
- {"secure-file-priv", OPT_SECURE_FILE_PRIV,
- "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory",
- (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0,
- GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"server-id", OPT_SERVER_ID,
- "Uniquely identifies the server instance in the community of replication partners.",
- (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX32,
- 0, 0, 0},
+#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
+ {"safemalloc", 0, "Enable the memory allocation checking.",
+ (uchar**) &sf_malloc_quick, (uchar**) &sf_malloc_quick, 0,
+ GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"safemalloc-mem-limit", 0, "Simulate memory shortage.",
+ (uchar**)&sf_malloc_mem_limit, (uchar**)&sf_malloc_mem_limit, 0, GET_UINT,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"set-variable", 'O',
"Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef HAVE_SMEM
- {"shared-memory", OPT_ENABLE_SHARED_MEMORY,
- "Enable the shared memory.",(uchar**) &opt_enable_shared_memory, (uchar**) &opt_enable_shared_memory,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
-#ifdef HAVE_SMEM
- {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
- "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#endif
- {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
+ {"show-slave-auth-info", 0,
"Show user and password in SHOW SLAVE HOSTS on this master",
(uchar**) &opt_show_slave_auth_info, (uchar**) &opt_show_slave_auth_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DISABLE_GRANT_OPTIONS
- {"skip-grant-tables", OPT_SKIP_GRANT,
+ {"skip-grant-tables", 0,
"Start without grant tables. This gives all users FULL ACCESS to all tables!",
(uchar**) &opt_noacl, (uchar**) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
@@ -6427,22 +5718,9 @@ Can't be set to 1 if --log-slave-updates is used.",
{"skip-name-resolve", OPT_SKIP_RESOLVE,
"Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-networking", OPT_SKIP_NETWORKING,
- "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
- 0, 0, 0},
{"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifndef DBUG_OFF
-#ifdef SAFEMALLOC
- {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
- "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
-#endif
-#endif
- {"skip-show-database", OPT_SKIP_SHOW_DB,
- "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
- 0, 0, 0, 0},
- {"skip-slave-start", OPT_SKIP_SLAVE_START,
+ {"skip-slave-start", 0,
"If set, slave is not autostarted.", (uchar**) &opt_skip_slave_start,
(uchar**) &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-stack-trace", OPT_SKIP_STACK_TRACE,
@@ -6455,44 +5733,22 @@ Can't be set to 1 if --log-slave-updates is used.",
"because it has no effect; the implied behavior is already the default.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
- {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
- "The location where the slave should put its temporary files when \
-replicating a LOAD DATA INFILE command.",
- (uchar**) &slave_load_tmpdir, (uchar**) &slave_load_tmpdir, 0, GET_STR_ALLOC,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
- "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
- "Modes for how replication events should be executed. Legal values are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations that are idempotent. In STRICT mode, replication will stop on any unexpected difference between the master and the slave.",
- (uchar**) &slave_exec_mode_str, (uchar**) &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#endif
- {"slow-query-log", OPT_SLOW_LOG,
- "Enable|disable slow query log", (uchar**) &opt_slow_log,
- (uchar**) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"socket", OPT_SOCKET, "Socket file to use for connection.",
- (uchar**) &mysqld_unix_port, (uchar**) &mysqld_unix_port, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef HAVE_REPLICATION
- {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
+ {"sporadic-binlog-dump-fail", 0,
"Option used by mysql-test for debugging and testing of replication.",
(uchar**) &opt_sporadic_binlog_dump_fail,
(uchar**) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
#endif /* HAVE_REPLICATION */
- {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
- "The update log is deprecated since version 5.0, is replaced by the binary \
-log and this option does nothing anymore.",
+ {"sql-bin-update-same", 0,
+ "The update log is deprecated since version 5.0, is replaced by the "
+ "binary log and this option does nothing anymore.",
0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"sql-mode", OPT_SQL_MODE,
- "Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
- (uchar**) &sql_mode_str, (uchar**) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
- 0, 0, 0, 0, 0},
-#ifdef HAVE_OPENSSL
-#include "sslopt-longopts.h"
-#endif
+ {"ssl", 0,
+ "Enable SSL for connection (automatically enabled with other flags).",
+ (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
+ 0, 0, 0},
#ifdef __WIN__
- {"standalone", OPT_STANDALONE,
+ {"standalone", 0,
"Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
@@ -6504,14 +5760,14 @@ log and this option does nothing anymore.",
option if compiled with valgrind support.
*/
IF_PURIFY(0,1), 0, 0, 0, 0, 0},
- {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
+ {"sysdate-is-now", 0,
"Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. Since 5.0, SYSDATE() returns a `dynamic' value different for different invocations, even within the same statement.",
(uchar**) &global_system_variables.sysdate_is_now,
0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
- {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
+ {"tc-heuristic-recover", 0,
"Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
- (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ (uchar**) &tc_heuristic_recover, (uchar**) &tc_heuristic_recover,
+ &tc_heuristic_recover_typelib, GET_ENUM, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#if defined(ENABLED_DEBUG_SYNC)
{"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
"Enable the debug sync facility "
@@ -6520,7 +5776,7 @@ log and this option does nothing anymore.",
(uchar**) &opt_debug_sync_timeout, 0,
0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
#endif /* defined(ENABLED_DEBUG_SYNC) */
- {"temp-pool", OPT_TEMP_POOL,
+ {"temp-pool", 0,
#if (ENABLE_TEMP_POOL)
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
#else
@@ -6528,24 +5784,11 @@ log and this option does nothing anymore.",
#endif
(uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
-
- {"timed_mutexes", OPT_TIMED_MUTEXES,
- "Specify whether to time mutexes (only InnoDB mutexes are currently supported)",
- (uchar**) &timed_mutexes, (uchar**) &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
- 0, 0, 0, 0, 0},
- {"tmpdir", 't',
- "Path for temporary files. Several paths may be specified, separated by a "
-#if defined(__WIN__) || defined(__NETWARE__)
- "semicolon (;)"
-#else
- "colon (:)"
-#endif
- ", in this case they are used in a round-robin fashion.",
- (uchar**) &opt_mysql_tmpdir,
- (uchar**) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"transaction-isolation", OPT_TX_ISOLATION,
- "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
- 0, 0, 0, 0, 0},
+ {"transaction-isolation", 0,
+ "Default transaction isolation level.",
+ (uchar**)&global_system_variables.tx_isolation,
+ (uchar**)&global_system_variables.tx_isolation, &tx_isolation_typelib,
+ GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
{"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.",
(uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG,
IF_PURIFY(0,1), 0, 0, 0, 0, 0},
@@ -6560,556 +5803,19 @@ log and this option does nothing anymore.",
(uchar**) &global_system_variables.log_warnings,
(uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
1, 0, ULONG_MAX, 0, 0, 0},
- { "back_log", OPT_BACK_LOG,
- "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.",
- (uchar**) &back_log, (uchar**) &back_log, 0, GET_ULONG,
- REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
- {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
- "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.",
- (uchar**) &binlog_cache_size, (uchar**) &binlog_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
- {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
- "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!",
- (uchar**) &global_system_variables.bulk_insert_buff_size,
- (uchar**) &max_system_variables.bulk_insert_buff_size,
- 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
- {"connect_timeout", OPT_CONNECT_TIMEOUT,
- "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.",
- (uchar**) &connect_timeout, (uchar**) &connect_timeout,
- 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
- { "date_format", OPT_DATE_FORMAT,
- "The DATE format (For future).",
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- { "datetime_format", OPT_DATETIME_FORMAT,
- "The DATETIME/TIMESTAMP format (for future).",
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
- "The default week format used by WEEK() functions.",
- (uchar**) &global_system_variables.default_week_format,
- (uchar**) &max_system_variables.default_week_format,
- 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
- {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
- "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.",
- (uchar**) &delayed_insert_limit, (uchar**) &delayed_insert_limit, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
- {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
- "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
- (uchar**) &delayed_insert_timeout, (uchar**) &delayed_insert_timeout, 0,
- GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
- { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
- "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
- (uchar**) &delayed_queue_size, (uchar**) &delayed_queue_size, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
- {"div_precision_increment", OPT_DIV_PRECINCREMENT,
- "Precision of the result of '/' operator will be increased on that value.",
- (uchar**) &global_system_variables.div_precincrement,
- (uchar**) &max_system_variables.div_precincrement, 0, GET_ULONG,
- REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
- {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
- "If non-zero, binary logs will be purged after expire_logs_days "
- "days; possible purges happen at startup and at binary log rotation.",
- (uchar**) &expire_logs_days,
- (uchar**) &expire_logs_days, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
- { "flush_time", OPT_FLUSH_TIME,
- "A dedicated thread is created to flush all tables at the given interval.",
- (uchar**) &flush_time, (uchar**) &flush_time, 0, GET_ULONG, REQUIRED_ARG,
- FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
- { "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
- "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
- 0, 0, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
- "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
- (uchar**) &ft_max_word_len, (uchar**) &ft_max_word_len, 0, GET_ULONG,
- REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0},
- { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
- "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.",
- (uchar**) &ft_min_word_len, (uchar**) &ft_min_word_len, 0, GET_ULONG,
- REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0},
- { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT,
- "Number of best matches to use for query expansion",
- (uchar**) &ft_query_expansion_limit, (uchar**) &ft_query_expansion_limit, 0, GET_ULONG,
- REQUIRED_ARG, 20, 0, 1000, 0, 1, 0},
- { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
- "Use stopwords from this file instead of built-in list.",
- (uchar**) &ft_stopword_file, (uchar**) &ft_stopword_file, 0, GET_STR,
- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
- "The maximum length of the result of function group_concat.",
- (uchar**) &global_system_variables.group_concat_max_len,
- (uchar**) &max_system_variables.group_concat_max_len, 0, GET_ULONG,
- REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
- {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
- "The number of seconds the server waits for activity on an interactive connection before closing it.",
- (uchar**) &global_system_variables.net_interactive_timeout,
- (uchar**) &max_system_variables.net_interactive_timeout, 0,
- GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
- {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
- "The size of the buffer that is used for full joins.",
- (uchar**) &global_system_variables.join_buff_size,
- (uchar**) &max_system_variables.join_buff_size, 0, GET_ULONG,
- REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
- MALLOC_OVERHEAD, IO_SIZE, 0},
- {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
- "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
- (uchar**) &global_system_variables.keep_files_on_create,
- (uchar**) &max_system_variables.keep_files_on_create,
- 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
- "The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
- (uchar**) &dflt_key_cache_var.param_buff_size,
- (uchar**) 0,
- 0, (GET_ULL | GET_ASK_ADDR),
- REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, SIZE_T_MAX, MALLOC_OVERHEAD,
- IO_SIZE, 0},
- {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
- "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",
- (uchar**) &dflt_key_cache_var.param_age_threshold,
- (uchar**) 0,
- 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
- 300, 100, ULONG_MAX, 0, 100, 0},
- {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
- "The default size of key cache blocks",
- (uchar**) &dflt_key_cache_var.param_block_size,
- (uchar**) 0,
- 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
- KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
- {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
- "The minimum percentage of warm blocks in key cache",
- (uchar**) &dflt_key_cache_var.param_division_limit,
- (uchar**) 0,
- 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
- 1, 100, 0, 1, 0},
- {"long_query_time", OPT_LONG_QUERY_TIME,
- "Log all queries that have taken more than long_query_time seconds to execute to file. "
- "The argument will be treated as a decimal value with microsecond precission.",
- (uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
- REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
- {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
- "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system",
- (uchar**) &lower_case_table_names,
- (uchar**) &lower_case_table_names, 0, GET_UINT, OPT_ARG,
-#ifdef FN_NO_CASE_SENCE
- 1
-#else
- 0
-#endif
- , 0, 2, 0, 1, 0},
- {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
- "Max packetlength to send/receive from to server.",
- (uchar**) &global_system_variables.max_allowed_packet,
- (uchar**) &max_system_variables.max_allowed_packet, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
- {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
- "Can be used to restrict the total size used to cache a multi-transaction query.",
- (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
- GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
- {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
- "Binary log will be rotated automatically when the size exceeds this \
-value. Will also apply to relay logs if max_relay_log_size is 0. \
-The minimum value for this variable is 4096.",
- (uchar**) &max_binlog_size, (uchar**) &max_binlog_size, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
- {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
- "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.",
- (uchar**) &max_connect_errors, (uchar**) &max_connect_errors, 0, GET_ULONG,
- REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
- // Default max_connections of 151 is larger than Apache's default max
- // children, to avoid "too many connections" error in a common setup
- {"max_connections", OPT_MAX_CONNECTIONS,
- "The number of simultaneous clients allowed.", (uchar**) &max_connections,
- (uchar**) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1,
- 0},
- {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
- "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.",
- (uchar**) &global_system_variables.max_insert_delayed_threads,
- (uchar**) &max_system_variables.max_insert_delayed_threads,
- 0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
- {"max_error_count", OPT_MAX_ERROR_COUNT,
- "Max number of errors/warnings to store for a statement.",
- (uchar**) &global_system_variables.max_error_count,
- (uchar**) &max_system_variables.max_error_count,
- 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
- {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
- "Don't allow creation of heap tables bigger than this.",
- (uchar**) &global_system_variables.max_heap_table_size,
- (uchar**) &max_system_variables.max_heap_table_size, 0, GET_ULL,
- REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
- MALLOC_OVERHEAD, 1024, 0},
- {"max_join_size", OPT_MAX_JOIN_SIZE,
- "Joins that are probably going to read more than max_join_size records return an error.",
- (uchar**) &global_system_variables.max_join_size,
- (uchar**) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
- HA_POS_ERROR, 1, HA_POS_ERROR, 0, 1, 0},
- {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
- "Max number of bytes in sorted records.",
- (uchar**) &global_system_variables.max_length_for_sort_data,
- (uchar**) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
- REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
- {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
- "Maximum number of prepared statements in the server.",
- (uchar**) &max_prepared_stmt_count, (uchar**) &max_prepared_stmt_count,
- 0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
- {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
- "If non-zero: relay log will be rotated automatically when the size exceeds this value; if zero (the default): when the size exceeds max_binlog_size. 0 excepted, the minimum value for this variable is 4096.",
- (uchar**) &max_relay_log_size, (uchar**) &max_relay_log_size, 0, GET_ULONG,
- REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
- { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
- "Limit assumed max number of seeks when looking up rows based on a key",
- (uchar**) &global_system_variables.max_seeks_for_key,
- (uchar**) &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
- REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
- {"max_sort_length", OPT_MAX_SORT_LENGTH,
- "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).",
- (uchar**) &global_system_variables.max_sort_length,
- (uchar**) &max_system_variables.max_sort_length, 0, GET_ULONG,
- REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
- {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
- "Maximum stored procedure recursion depth. (discussed with docs).",
- (uchar**) &global_system_variables.max_sp_recursion_depth,
- (uchar**) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
- OPT_ARG, 0, 0, 255, 0, 1, 0 },
- {"max_tmp_tables", OPT_MAX_TMP_TABLES,
- "Maximum number of temporary tables a client can keep open at a time.",
- (uchar**) &global_system_variables.max_tmp_tables,
- (uchar**) &max_system_variables.max_tmp_tables, 0, GET_ULONG,
- REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
- {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
- "The maximum number of active connections for a single user (0 = no limit).",
- (uchar**) &max_user_connections, (uchar**) &max_user_connections, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
- {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
- "After this many write locks, allow some read locks to run in between.",
- (uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
- REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
- {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
- "Don't write queries to slow log that examine fewer than min_examined_row_limit rows.",
- (uchar**) &global_system_variables.min_examined_row_limit,
- (uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
- {"multi_range_count", OPT_MULTI_RANGE_COUNT,
- "Number of key ranges to request at once.",
- (uchar**) &global_system_variables.multi_range_count,
- (uchar**) &max_system_variables.multi_range_count, 0,
- GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
- {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
- "Block size to be used for MyISAM index pages.",
- (uchar**) &opt_myisam_block_size,
- (uchar**) &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
- MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
- 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
- {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
- "Default pointer size to be used for MyISAM tables.",
- (uchar**) &myisam_data_pointer_size,
- (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
- 6, 2, 7, 0, 1, 0},
- {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
- "Deprecated option",
- (uchar**) &global_system_variables.myisam_max_extra_sort_file_size,
- (uchar**) &max_system_variables.myisam_max_extra_sort_file_size,
- 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH,
- 0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
- {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
- "Don't use the fast sort index method to created index if the temporary file would get bigger than this.",
- (uchar**) &global_system_variables.myisam_max_sort_file_size,
- (uchar**) &max_system_variables.myisam_max_sort_file_size, 0,
- GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
- 0, 1024*1024, 0},
- {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE,
- "Can be used to restrict the total memory used for memory mmaping of myisam files",
- (uchar**) &myisam_mmap_size, (uchar**) &myisam_mmap_size, 0,
- GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0},
- {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
- "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.",
- (uchar**) &global_system_variables.myisam_repair_threads,
- (uchar**) &max_system_variables.myisam_repair_threads, 0,
- GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
- {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
- "The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
- (uchar**) &global_system_variables.myisam_sort_buff_size,
- (uchar**) &max_system_variables.myisam_sort_buff_size, 0,
- GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0},
- {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
- "Use memory mapping for reading and writing MyISAM tables",
- (uchar**) &opt_myisam_use_mmap,
- (uchar**) &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG, 0,
- 0, 0, 0, 0, 0},
- {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
- "Specifies how MyISAM index statistics collection code should threat NULLs. "
- "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
- "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
- (uchar**) &myisam_stats_method_str, (uchar**) &myisam_stats_method_str, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
- "Buffer length for TCP/IP and socket communication.",
- (uchar**) &global_system_variables.net_buffer_length,
- (uchar**) &max_system_variables.net_buffer_length, 0, GET_ULONG,
- REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
- {"net_read_timeout", OPT_NET_READ_TIMEOUT,
- "Number of seconds to wait for more data from a connection before aborting the read.",
- (uchar**) &global_system_variables.net_read_timeout,
- (uchar**) &max_system_variables.net_read_timeout, 0, GET_ULONG,
- REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
- {"net_retry_count", OPT_NET_RETRY_COUNT,
- "If a read on a communication port is interrupted, retry this many times before giving up.",
- (uchar**) &global_system_variables.net_retry_count,
- (uchar**) &max_system_variables.net_retry_count,0,
- GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
- {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
- "Number of seconds to wait for a block to be written to a connection before aborting the write.",
- (uchar**) &global_system_variables.net_write_timeout,
- (uchar**) &max_system_variables.net_write_timeout, 0, GET_ULONG,
- REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
- { "old", OPT_OLD_MODE, "Use compatible behavior.",
- (uchar**) &global_system_variables.old_mode,
- (uchar**) &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
- {"open_files_limit", OPT_OPEN_FILES_LIMIT,
- "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
- (uchar**) &open_files_limit, (uchar**) &open_files_limit, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
- {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
- "Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows.",
- (uchar**) &global_system_variables.optimizer_prune_level,
- (uchar**) &max_system_variables.optimizer_prune_level,
- 0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
- {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
- "Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Smaller values than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to MAX_TABLES+2, the optimizer will switch to the original find_best (used for testing/comparison).",
- (uchar**) &global_system_variables.optimizer_search_depth,
- (uchar**) &max_system_variables.optimizer_search_depth,
- 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
- {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
- "optimizer_switch=option=val[,option=val...], where option={index_merge, "
- "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
- "val={on, off, default}.",
- (uchar**) &optimizer_switch_str, (uchar**) &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
- /*OPTIMIZER_SWITCH_DEFAULT*/0,
- 0, 0, 0, 0, 0},
- {"plugin_dir", OPT_PLUGIN_DIR,
- "Directory for plugins.",
- (uchar**) &opt_plugin_dir_ptr, (uchar**) &opt_plugin_dir_ptr, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"plugin-load", OPT_PLUGIN_LOAD,
+ {"plugin-load", 0,
"Optional semicolon-separated list of plugins to load, where each plugin is "
"identified as name=library, where name is the plugin name and library "
"is the plugin library in plugin_dir.",
(uchar**) &opt_plugin_load, (uchar**) &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",
- (uchar**) &global_system_variables.preload_buff_size,
- (uchar**) &max_system_variables.preload_buff_size, 0, GET_ULONG,
- REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
- {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
- "Allocation block size for query parsing and execution",
- (uchar**) &global_system_variables.query_alloc_block_size,
- (uchar**) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
-#ifdef HAVE_QUERY_CACHE
- {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
- "Don't cache results that are bigger than this.",
- (uchar**) &query_cache_limit, (uchar**) &query_cache_limit, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
- {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
- "minimal size of unit in wich space for results is allocated (last unit will be trimed after writing all result data.",
- (uchar**) &query_cache_min_res_unit, (uchar**) &query_cache_min_res_unit,
- 0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
- 0, ULONG_MAX, 0, 1, 0},
-#endif /*HAVE_QUERY_CACHE*/
- {"query_cache_size", OPT_QUERY_CACHE_SIZE,
- "The memory allocated to store results from old queries.",
- (uchar**) &query_cache_size, (uchar**) &query_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
-#ifdef HAVE_QUERY_CACHE
- {"query_cache_type", OPT_QUERY_CACHE_TYPE,
- "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
- (uchar**) &global_system_variables.query_cache_type,
- (uchar**) &max_system_variables.query_cache_type,
- 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
- {"query_cache_wlock_invalidate", OPT_QUERY_CACHE_WLOCK_INVALIDATE,
- "Invalidate queries in query cache on LOCK for write",
- (uchar**) &global_system_variables.query_cache_wlock_invalidate,
- (uchar**) &max_system_variables.query_cache_wlock_invalidate,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-#endif /*HAVE_QUERY_CACHE*/
- {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
- "Persistent buffer for query parsing and execution",
- (uchar**) &global_system_variables.query_prealloc_size,
- (uchar**) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
- ULONG_MAX, 0, 1024, 0},
- {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
- "Allocation block size for storing ranges during optimization",
- (uchar**) &global_system_variables.range_alloc_block_size,
- (uchar**) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
- 0, 1024, 0},
- {"read_buffer_size", OPT_RECORD_BUFFER,
- "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
+ {"record_buffer", 0, "Deprecated; use --read-buffer-size instead.",
(uchar**) &global_system_variables.read_buff_size,
(uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
- 0},
- {"read_only", OPT_READONLY,
- "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
- (uchar**) &opt_readonly,
- (uchar**) &opt_readonly,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
- {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
- "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.",
- (uchar**) &global_system_variables.read_rnd_buff_size,
- (uchar**) &max_system_variables.read_rnd_buff_size, 0,
- GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
- INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
- {"record_buffer", OPT_RECORD_BUFFER,
- "Alias for read_buffer_size",
- (uchar**) &global_system_variables.read_buff_size,
- (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
- 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
-#ifdef HAVE_REPLICATION
- {"relay_log_purge", OPT_RELAY_LOG_PURGE,
- "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
- (uchar**) &relay_log_purge,
- (uchar**) &relay_log_purge, 0, GET_BOOL, NO_ARG,
- 1, 0, 1, 0, 1, 0},
- {"relay_log_recovery", OPT_RELAY_LOG_RECOVERY,
- "Enables automatic relay log recovery right after the database startup, "
- "which means that the IO Thread starts re-fetching from the master "
- "right after the last transaction processed.",
- (uchar**) &relay_log_recovery,
- (uchar**) &relay_log_recovery, 0, GET_BOOL, NO_ARG,
- 0, 0, 1, 0, 1, 0},
- {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
- "Maximum space to use for all relay logs.",
- (uchar**) &relay_log_space_limit,
- (uchar**) &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
- (longlong) ULONG_MAX, 0, 1, 0},
- {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
- "Use compression on master/slave protocol.",
- (uchar**) &opt_slave_compressed_protocol,
- (uchar**) &opt_slave_compressed_protocol,
- 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
- {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
- "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
- (uchar**) &slave_net_timeout, (uchar**) &slave_net_timeout, 0,
- GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
- {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
- "Number of times the slave SQL thread will retry a transaction in case "
- "it failed with a deadlock or elapsed lock wait timeout, "
- "before giving up and stopping.",
- (uchar**) &slave_trans_retries, (uchar**) &slave_trans_retries, 0,
- GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
-#endif /* HAVE_REPLICATION */
- {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
- "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.",
- (uchar**) &slow_launch_time, (uchar**) &slow_launch_time, 0, GET_ULONG,
- REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
- {"sort_buffer_size", OPT_SORT_BUFFER,
- "Each thread that needs to do a sort allocates a buffer of this size.",
- (uchar**) &global_system_variables.sortbuff_size,
- (uchar**) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
- MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
- 1, 0},
- {"sync-binlog", OPT_SYNC_BINLOG,
- "Synchronously flush binary log to disk after every #th event. "
- "Use 0 (default) to disable synchronous flushing.",
- (uchar**) &sync_binlog_period, (uchar**) &sync_binlog_period, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, (longlong) UINT_MAX, 0, 1, 0},
- {"sync-relay-log", OPT_SYNC_RELAY_LOG,
- "Synchronously flush relay log to disk after every #th event. "
- "Use 0 (default) to disable synchronous flushing.",
- (uchar**) &sync_relaylog_period, (uchar**) &sync_relaylog_period, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, (longlong) UINT_MAX, 0, 1, 0},
- {"sync-relay-log-info", OPT_SYNC_RELAY_LOG_INFO,
- "Synchronously flush relay log info to disk after #th transaction. "
- "Use 0 (default) to disable synchronous flushing.",
- (uchar**) &sync_relayloginfo_period, (uchar**) &sync_relayloginfo_period, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, (longlong) UINT_MAX, 0, 1, 0},
- {"sync-master-info", OPT_SYNC_MASTER_INFO,
- "Synchronously flush master info to disk after every #th event. "
- "Use 0 (default) to disable synchronous flushing.",
- (uchar**) &sync_masterinfo_period, (uchar**) &sync_masterinfo_period, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, (longlong) UINT_MAX, 0, 1, 0},
- {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
- (uchar**) &opt_sync_frm, (uchar**) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
- 0, 0, 0, 0},
- {"table_cache", OPT_TABLE_OPEN_CACHE,
- "Deprecated; use --table_open_cache instead.",
- (uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
- {"table_definition_cache", OPT_TABLE_DEF_CACHE,
- "The number of cached table definitions.",
- (uchar**) &table_def_size, (uchar**) &table_def_size,
- 0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
- 512*1024L, 0, 1, 0},
- {"table_open_cache", OPT_TABLE_OPEN_CACHE,
- "The number of cached open tables.",
+ 128*1024L, IO_SIZE*2, INT_MAX32, 0, IO_SIZE, 0},
+ {"table_cache", 0, "Deprecated; use --table-open-cache instead.",
(uchar**) &table_cache_size, (uchar**) &table_cache_size, 0, GET_ULONG,
REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
- {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
- "Timeout in seconds to wait for a table level lock before returning an "
- "error. Used only if the connection has active cursors.",
- (uchar**) &table_lock_wait_timeout, (uchar**) &table_lock_wait_timeout,
- 0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
- {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
- "How many threads we should keep in a cache for reuse.",
- (uchar**) &thread_cache_size, (uchar**) &thread_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
- {"thread_concurrency", OPT_THREAD_CONCURRENCY,
- "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.",
- (uchar**) &concurrency, (uchar**) &concurrency, 0, GET_ULONG, REQUIRED_ARG,
- DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
-#if HAVE_POOL_OF_THREADS == 1
- {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
- "How many threads we should create to handle query requests in case of 'thread_handling=pool-of-threads'",
- (uchar**) &thread_pool_size, (uchar**) &thread_pool_size, 0, GET_ULONG,
- REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
-#endif
- {"thread_stack", OPT_THREAD_STACK,
- "The stack size for each thread.", (uchar**) &my_thread_stack_size,
- (uchar**) &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
- 1024L*128L, ULONG_MAX, 0, 1024, 0},
- { "time_format", OPT_TIME_FORMAT,
- "The TIME format (for future).",
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
- (uchar**) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"tmp_table_size", OPT_TMP_TABLE_SIZE,
- "If an internal in-memory temporary table exceeds this size, MySQL will"
- " automatically convert it to an on-disk MyISAM table.",
- (uchar**) &global_system_variables.tmp_table_size,
- (uchar**) &max_system_variables.tmp_table_size, 0, GET_ULL,
- REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
- {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
- "Allocation block size for transactions to be stored in binary log",
- (uchar**) &global_system_variables.trans_alloc_block_size,
- (uchar**) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
- {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
- "Persistent buffer for transactions to be stored in binary log",
- (uchar**) &global_system_variables.trans_prealloc_size,
- (uchar**) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
- REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
- {"thread_handling", OPT_THREAD_HANDLING,
- "Define threads usage for handling queries: "
- "one-thread-per-connection or no-threads", 0, 0,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
- "1 = YES = Don't issue an error message (warning only) if a VIEW without presence of a key of the underlying table is used in queries with a LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which does not contain a key of the underlying table and the query uses a LIMIT clause (usually get from GUI tools).",
- (uchar**) &global_system_variables.updatable_views_with_limit,
- (uchar**) &max_system_variables.updatable_views_with_limit,
- 0, GET_ULONG, REQUIRED_ARG, 1, 0, 1, 0, 1, 0},
- {"wait_timeout", OPT_WAIT_TIMEOUT,
- "The number of seconds the server waits for activity on a connection before closing it.",
- (uchar**) &global_system_variables.net_wait_timeout,
- (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
- REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
- 0, 1, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -7638,6 +6344,12 @@ SHOW_VAR status_vars[]= {
{NullS, NullS, SHOW_LONG}
};
+static bool all_options_add_terminator()
+{
+ my_option empty_element= {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0};
+ return insert_dynamic(&all_options, (uchar *)&empty_element);
+}
+
#ifndef EMBEDDED_LIBRARY
static void print_version(void)
{
@@ -7647,8 +6359,52 @@ static void print_version(void)
server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
}
+/** Compares two options' names, treats - and _ the same */
+static int option_cmp(my_option *a, my_option *b)
+{
+ const char *sa= a->name;
+ const char *sb= b->name;
+ for (; *sa || *sb; sa++, sb++)
+ {
+ if (*sa < *sb)
+ {
+ if (*sa == '-' && *sb == '_')
+ continue;
+ else
+ return -1;
+ }
+ if (*sa > *sb)
+ {
+ if (*sa == '_' && *sb == '-')
+ continue;
+ else
+ return 1;
+ }
+ }
+ DBUG_ASSERT(a->name == b->name);
+ return 0;
+}
+
+static void print_help()
+{
+ MEM_ROOT mem_root;
+ init_alloc_root(&mem_root, 4096, 4096);
+
+ pop_dynamic(&all_options);
+ add_plugin_options(&all_options, &mem_root);
+ sort_dynamic(&all_options, (qsort_cmp) option_cmp);
+ all_options_add_terminator();
+
+ my_print_help((my_option*) all_options.buffer);
+ my_print_variables((my_option*) all_options.buffer);
+
+ free_root(&mem_root, MYF(0));
+ delete_dynamic(&all_options);
+}
+
static void usage(void)
{
+ DBUG_ENTER("usage");
if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
MY_CS_PRIMARY,
MYF(MY_WME))))
@@ -7658,7 +6414,7 @@ static void usage(void)
print_version();
puts("\
Copyright (C) 2000-2008 MySQL AB, by Monty and others\n\
-Copyright (C) 2008 Sun Microsystems, Inc.\n\
+Copyright (C) 2008,2009 Sun Microsystems, Inc.\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n\n\
Starts the MySQL database server\n");
@@ -7686,7 +6442,7 @@ Starts the MySQL database server\n");
set_ports();
/* Print out all the options including plugin supplied options */
- my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
+ print_help();
if (! plugins_are_initialized)
{
@@ -7699,15 +6455,12 @@ because execution stopped before plugins were initialized.");
To see what values a running MySQL server is using, type\n\
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
}
+ DBUG_VOID_RETURN;
}
#endif /*!EMBEDDED_LIBRARY*/
-
/**
- Initialize all MySQL global variables to default values.
-
- We don't need to set numeric variables refered to in my_long_options
- as these are initialized by my_getopt.
+ Initialize MySQL global variables to default values.
@note
The reason to set a lot of global variables to zero is to allow one to
@@ -7715,27 +6468,24 @@ To see what values a running MySQL server is using, type\n\
It's also needed on some exotic platforms where global variables are
not set to 0 when a program starts.
- We don't need to set numeric variables refered to in my_long_options
+ We don't need to set variables refered to in my_long_options
as these are initialized by my_getopt.
*/
static int mysql_init_variables(void)
{
- int error;
/* Things reset to zero */
opt_skip_slave_start= opt_reckless_slave = 0;
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
myisam_test_invalid_symlink= test_if_data_home_dir;
opt_log= opt_slow_log= 0;
opt_update_log= 0;
- log_output_options= find_bit_type(log_output_str, &log_output_typelib);
opt_bin_log= 0;
opt_disable_networking= opt_skip_show_db=0;
opt_ignore_builtin_innodb= 0;
opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
opt_secure_auth= 0;
- opt_secure_file_priv= 0;
opt_bootstrap= opt_myisam_log= 0;
mqh_used= 0;
segfaulted= kill_in_progress= 0;
@@ -7776,25 +6526,12 @@ static int mysql_init_variables(void)
table_alias_charset= &my_charset_bin;
character_set_filesystem= &my_charset_bin;
- opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
-
- /* Things with default values that are not zero */
- delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
- slave_exec_mode_options= 0;
- slave_exec_mode_options= (uint)
- find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL,
- &error);
- if (error)
- return 1;
opt_specialflag= SPECIAL_ENGLISH;
unix_sock= ip_sock= INVALID_SOCKET;
mysql_home_ptr= mysql_home;
pidfile_name_ptr= pidfile_name;
log_error_file_ptr= log_error_file;
lc_messages_dir_ptr= lc_messages_dir;
- mysql_data_home= mysql_real_data_home;
- thd_startup_options= (OPTION_BIN_LOG |
- OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
protocol_version= PROTOCOL_VERSION;
what_to_log= ~ (1L << (uint) COM_TIME);
refresh_version= 1L; /* Increments on each reload */
@@ -7802,8 +6539,6 @@ static int mysql_init_variables(void)
my_atomic_rwlock_init(&global_query_id_lock);
my_atomic_rwlock_init(&thread_running_lock);
strmov(server_version, MYSQL_SERVER_VERSION);
- myisam_recover_options_str= sql_mode_str= "OFF";
- myisam_stats_method_str= "nulls_unequal";
threads.empty();
thread_cache.empty();
key_caches.empty();
@@ -7817,12 +6552,9 @@ static int mysql_init_variables(void)
multi_keycache_init();
/* Set directory paths */
- strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
- sizeof(mysql_real_data_home)-1);
- mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
- mysql_data_home_buff[1]=0;
- mysql_data_home_len= 2;
-
+ mysql_real_data_home_len=
+ strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
+ sizeof(mysql_real_data_home)-1) - mysql_real_data_home;
/* Replication parameters */
master_info_file= (char*) "master.info",
relay_log_info_file= (char*) "relay-log.info";
@@ -7833,28 +6565,10 @@ static int mysql_init_variables(void)
charsets_dir= 0;
default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
default_collation_name= compiled_default_collation_name;
- sys_charset_system.value= (char*) system_charset_info->csname;
character_set_filesystem_name= (char*) "binary";
lc_messages= (char*) "en_US";
lc_time_names_name= (char*) "en_US";
- /* Set default values for some option variables */
- default_storage_engine_str= (char*) "MyISAM";
- 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;
- global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
- max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
- global_system_variables.old_passwords= 0;
- global_system_variables.old_alter_table= 0;
- global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
- /*
- Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
- when collecting index statistics for MyISAM tables.
- */
- global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
- global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
/* Variables that depends on compile options */
#ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
@@ -7866,12 +6580,7 @@ static int mysql_init_variables(void)
#else
have_profiling = SHOW_OPTION_NO;
#endif
- 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;
+
#ifdef HAVE_OPENSSL
have_ssl=SHOW_OPTION_YES;
#else
@@ -7952,14 +6661,11 @@ static int mysql_init_variables(void)
return 0;
}
-
my_bool
mysqld_get_one_option(int optid,
const struct my_option *opt __attribute__((unused)),
char *argument)
{
- int error;
-
switch(optid) {
case '#':
#ifndef DBUG_OFF
@@ -7968,7 +6674,7 @@ mysqld_get_one_option(int optid,
opt_endinfo=1; /* unireg: memory allocation */
break;
case 'a':
- global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
+ global_system_variables.sql_mode= MODE_ANSI;
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
break;
case 'b':
@@ -7985,8 +6691,7 @@ mysqld_get_one_option(int optid,
case 'h':
strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
/* Correct pointer set by my_getopt (for embedded library) */
- mysql_data_home= mysql_real_data_home;
- mysql_data_home_len= strlen(mysql_data_home);
+ mysql_real_data_home_ptr= mysql_real_data_home;
break;
case 'u':
if (!mysqld_user || !strcmp(mysqld_user, argument))
@@ -7996,22 +6701,10 @@ mysqld_get_one_option(int optid,
break;
case 'L':
strmake(lc_messages_dir, argument, sizeof(lc_messages_dir)-1);
+ lc_messages_dir_ptr= lc_messages_dir;
break;
-#ifdef HAVE_REPLICATION
- case OPT_SLAVE_SKIP_ERRORS:
- init_slave_skip_errors(argument);
- break;
- case OPT_SLAVE_EXEC_MODE:
- slave_exec_mode_options= (uint)
- find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error);
- if (error)
- return 1;
- break;
-#endif
- case OPT_SAFEMALLOC_MEM_LIMIT:
-#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
- sf_malloc_mem_limit = atoi(argument);
-#endif
+ case OPT_BINLOG_FORMAT:
+ binlog_format_used= true;
break;
#include <sslopt-case.h>
#ifndef EMBEDDED_LIBRARY
@@ -8031,12 +6724,6 @@ mysqld_get_one_option(int optid,
test_flags= argument ? (uint) atoi(argument) : 0;
opt_endinfo=1;
break;
- case (int) OPT_BIG_TABLES:
- thd_startup_options|=OPTION_BIG_TABLES;
- break;
- case (int) OPT_IGNORE_BUILTIN_INNODB:
- opt_ignore_builtin_innodb= 1;
- break;
case (int) OPT_ISAM_LOG:
opt_myisam_log=1;
break;
@@ -8046,17 +6733,7 @@ mysqld_get_one_option(int optid,
case (int) OPT_BIN_LOG:
opt_bin_log= test(argument != disabled_my_option);
break;
- case (int) OPT_ERROR_LOG_FILE:
- opt_error_log= 1;
- break;
#ifdef HAVE_REPLICATION
- case (int) OPT_INIT_RPL_ROLE:
- {
- int role;
- role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
- rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
- break;
- }
case (int)OPT_REPLICATE_IGNORE_DB:
{
rpl_filter->add_ignore_db(argument);
@@ -8103,13 +6780,6 @@ mysqld_get_one_option(int optid,
binlog_filter->add_ignore_db(argument);
break;
}
- case OPT_BINLOG_FORMAT:
- {
- int id;
- id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
- global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
- break;
- }
case (int)OPT_BINLOG_DO_DB:
{
binlog_filter->add_do_db(argument);
@@ -8156,38 +6826,11 @@ mysqld_get_one_option(int optid,
WARN_DEPRECATED(NULL, 7, 0, "--log-slow-queries", "'--slow-query-log'/'--slow-query-log-file'");
opt_slow_log= 1;
break;
-#ifdef WITH_CSV_STORAGE_ENGINE
- case OPT_LOG_OUTPUT:
- {
- if (!argument || !argument[0])
- {
- log_output_options= LOG_FILE;
- log_output_str= log_output_typelib.type_names[1];
- }
- else
- {
- log_output_str= argument;
- log_output_options=
- find_bit_type_or_exit(argument, &log_output_typelib, opt->name, &error);
- if (error)
- return 1;
- }
- break;
- }
-#endif
- case OPT_EVENT_SCHEDULER:
-#ifndef HAVE_EVENT_SCHEDULER
- sql_perror("Event scheduler is not supported in embedded build.");
-#else
- if (Events::set_opt_event_scheduler(argument))
- return 1;
-#endif
- break;
case (int) OPT_SKIP_NEW:
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
- delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
+ delay_key_write_options= DELAY_KEY_WRITE_NONE;
myisam_concurrent_insert=0;
- myisam_recover_options= HA_RECOVER_NONE;
+ myisam_recover_options= HA_RECOVER_OFF;
sp_automatic_privileges=0;
my_use_symdir=0;
ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
@@ -8197,7 +6840,7 @@ mysqld_get_one_option(int optid,
break;
case (int) OPT_SAFE:
opt_specialflag|= SPECIAL_SAFE_MODE;
- delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
+ delay_key_write_options= DELAY_KEY_WRITE_NONE;
myisam_recover_options= HA_RECOVER_DEFAULT;
ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
break;
@@ -8216,18 +6859,6 @@ mysqld_get_one_option(int optid,
case (int) OPT_SKIP_RESOLVE:
opt_specialflag|=SPECIAL_NO_RESOLVE;
break;
- case (int) OPT_SKIP_NETWORKING:
-#if defined(__NETWARE__)
- sql_perror("Can't start server: skip-networking option is currently not supported on NetWare");
- return 1;
-#endif
- opt_disable_networking=1;
- mysqld_port=0;
- break;
- case (int) OPT_SKIP_SHOW_DB:
- opt_skip_show_db=1;
- opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
- break;
case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL;
break;
@@ -8259,25 +6890,10 @@ mysqld_get_one_option(int optid,
freeaddrinfo(res_lst);
}
break;
- case (int) OPT_PID_FILE:
- strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
- break;
-#ifdef __WIN__
- case (int) OPT_STANDALONE: /* Dummy option for NT */
- break;
-#endif
case OPT_CONSOLE:
if (opt_console)
opt_error_log= 0; // Force logs to stdout
break;
- case (int) OPT_FLUSH:
- myisam_flush=1;
- flush_time=0; // No auto flush
- break;
- case OPT_LOW_PRIORITY_UPDATES:
- thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
- global_system_variables.low_priority_updates=1;
- break;
case OPT_BOOTSTRAP:
opt_noacl=opt_bootstrap=1;
break;
@@ -8286,188 +6902,14 @@ mysqld_get_one_option(int optid,
break;
case OPT_DELAY_KEY_WRITE_ALL:
if (argument != disabled_my_option)
- argument= (char*) "ALL";
- /* Fall through */
- case OPT_DELAY_KEY_WRITE:
- if (argument == disabled_my_option)
- delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
- else if (! argument)
- delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
- else
- {
- int type;
- type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
- delay_key_write_options= (uint) type-1;
- }
- break;
- case OPT_CHARSETS_DIR:
- strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
- charsets_dir = mysql_charsets_dir;
- break;
- case OPT_TX_ISOLATION:
- {
- int type;
- type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
- global_system_variables.tx_isolation= (type-1);
- break;
- }
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
- case OPT_NDB_MGMD:
- case OPT_NDB_NODEID:
- {
- int len= my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
- sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
- "%s%s%s",opt_ndb_constrbuf_len > 0 ? ",":"",
- optid == OPT_NDB_NODEID ? "nodeid=" : "",
- argument);
- opt_ndb_constrbuf_len+= len;
- }
- /* fall through to add the connectstring to the end
- * and set opt_ndbcluster_connectstring
- */
- case OPT_NDB_CONNECTSTRING:
- if (opt_ndb_connectstring && opt_ndb_connectstring[0])
- my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
- sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
- "%s%s", opt_ndb_constrbuf_len > 0 ? ",":"",
- opt_ndb_connectstring);
- else
- opt_ndb_constrbuf[opt_ndb_constrbuf_len]= 0;
- opt_ndbcluster_connectstring= opt_ndb_constrbuf;
- break;
- case OPT_NDB_DISTRIBUTION:
- int id;
- id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
- opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
- break;
- case OPT_NDB_EXTRA_LOGGING:
- if (!argument)
- ndb_extra_logging++;
- else if (argument == disabled_my_option)
- ndb_extra_logging= 0L;
+ delay_key_write_options= DELAY_KEY_WRITE_ALL;
else
- ndb_extra_logging= atoi(argument);
+ delay_key_write_options= DELAY_KEY_WRITE_NONE;
break;
-#endif
- case OPT_MYISAM_RECOVER:
- {
- if (!argument)
- {
- myisam_recover_options= HA_RECOVER_DEFAULT;
- myisam_recover_options_str= myisam_recover_typelib.type_names[0];
- }
- else if (!argument[0])
- {
- myisam_recover_options= HA_RECOVER_NONE;
- myisam_recover_options_str= "OFF";
- }
- else
- {
- myisam_recover_options_str=argument;
- myisam_recover_options=
- find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
- &error);
- if (error)
- return 1;
- }
- ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
- break;
- }
- case OPT_CONCURRENT_INSERT:
- /* The following code is mainly here to emulate old behavior */
- if (!argument) /* --concurrent-insert */
- myisam_concurrent_insert= 1;
- else if (argument == disabled_my_option)
- myisam_concurrent_insert= 0; /* --skip-concurrent-insert */
- break;
- case OPT_TC_HEURISTIC_RECOVER:
- tc_heuristic_recover= find_type_or_exit(argument,
- &tc_heuristic_recover_typelib,
- opt->name);
- break;
- case OPT_MYISAM_STATS_METHOD:
- {
- ulong method_conv;
- int method;
- LINT_INIT(method_conv);
-
- myisam_stats_method_str= argument;
- method= find_type_or_exit(argument, &myisam_stats_method_typelib,
- opt->name);
- switch (method-1) {
- case 2:
- method_conv= MI_STATS_METHOD_IGNORE_NULLS;
- break;
- case 1:
- method_conv= MI_STATS_METHOD_NULLS_EQUAL;
- break;
- case 0:
- default:
- method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
- break;
- }
- global_system_variables.myisam_stats_method= method_conv;
- break;
- }
- case OPT_SQL_MODE:
- {
- sql_mode_str= argument;
- global_system_variables.sql_mode=
- find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name, &error);
- if (error)
- return 1;
- global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
- sql_mode);
- break;
- }
- case OPT_OPTIMIZER_SWITCH:
- {
- bool not_used;
- char *error= 0;
- uint error_len= 0;
- optimizer_switch_str= argument;
- global_system_variables.optimizer_switch=
- (ulong)find_set_from_flags(&optimizer_switch_typelib,
- optimizer_switch_typelib.count,
- global_system_variables.optimizer_switch,
- global_system_variables.optimizer_switch,
- argument, strlen(argument), NULL,
- &error, &error_len, &not_used);
- if (error)
- {
- char buf[512];
- char *cbuf= buf;
- cbuf += my_snprintf(buf, 512, "Error in parsing optimizer_switch setting near %*s\n", error_len, error);
- sql_perror(buf);
- return 1;
- }
- break;
- }
case OPT_ONE_THREAD:
- global_system_variables.thread_handling=
- SCHEDULER_ONE_THREAD_PER_CONNECTION;
- break;
- case OPT_THREAD_HANDLING:
- {
- global_system_variables.thread_handling=
- find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
- break;
- }
- case OPT_FT_BOOLEAN_SYNTAX:
- if (ft_boolean_check_syntax_string((uchar*) argument))
- {
- sql_print_error("Invalid ft-boolean-syntax string: %s\n", argument);
- return 1;
- }
- strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
- break;
- case OPT_SKIP_SAFEMALLOC:
-#ifdef SAFEMALLOC
- sf_malloc_quick=1;
-#endif
+ thread_handling= SCHEDULER_ONE_THREAD_PER_CONNECTION;
break;
case OPT_LOWER_CASE_TABLE_NAMES:
- lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
break;
#if defined(ENABLED_DEBUG_SYNC)
@@ -8559,24 +7001,92 @@ static int get_options(int *argc,char **argv)
int ho_error;
my_getopt_register_get_addr(mysql_getopt_value);
- strmake(def_ft_boolean_syntax, ft_boolean_syntax,
- sizeof(ft_boolean_syntax)-1);
my_getopt_error_reporter= option_error_reporter;
+ /* prepare all_options array */
+ my_init_dynamic_array(&all_options, sizeof(my_option),
+ array_elements(my_long_options), array_elements(my_long_options)/4);
+ for (my_option *opt= my_long_options;
+ opt < my_long_options + array_elements(my_long_options) - 1;
+ opt++)
+ insert_dynamic(&all_options, (uchar*) opt);
+ sys_var_init(&all_options);
+ all_options_add_terminator();
+
/* 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,
+ if ((ho_error= handle_options(argc, &argv, (my_option*)(all_options.buffer),
mysqld_get_one_option)))
return ho_error;
+
+ if (!opt_help)
+ delete_dynamic(&all_options);
+
(*argc)++; /* add back one for the progname handle_options removes */
/* no need to do this for argv as we are discarding it. */
+ /*
+ Options have been parsed. Now some of them need additional special
+ handling, like custom value checking, checking of incompatibilites
+ between options, setting of multiple variables, etc.
+ Do them here.
+ */
+
if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
opt_log_slow_slave_statements) &&
!opt_slow_log)
sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log_slow_queries is not set");
+ if (log_error_file_ptr != disabled_my_option)
+ opt_error_log= 1;
+ else
+ log_error_file_ptr= const_cast<char*>("");
+
+ opt_init_connect.length=strlen(opt_init_connect.str);
+ opt_init_slave.length=strlen(opt_init_slave.str);
+
+ if (global_system_variables.low_priority_updates)
+ thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
+
+ if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax))
+ {
+ sql_print_error("Invalid ft-boolean-syntax string: %s\n",
+ ft_boolean_syntax);
+ return 1;
+ }
+
+ if (opt_disable_networking)
+ {
+#if defined(__NETWARE__)
+ sql_print_error("Can't start server: skip-networking option is currently not supported on NetWare");
+ return 1;
+#endif
+ mysqld_port= 0;
+ }
+ if (opt_skip_show_db)
+ opt_specialflag|= SPECIAL_SKIP_SHOW_DB;
+
+ if (myisam_flush)
+ flush_time= 0;
+
+#ifdef HAVE_REPLICATION
+ if (opt_slave_skip_errors)
+ init_slave_skip_errors(opt_slave_skip_errors);
+#endif
+
+ if (global_system_variables.max_join_size == HA_POS_ERROR)
+ global_system_variables.option_bits|= OPTION_BIG_SELECTS;
+ else
+ global_system_variables.option_bits&= ~OPTION_BIG_SELECTS;
+
+ if (global_system_variables.option_bits & OPTION_AUTOCOMMIT)
+ global_system_variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
+ else
+ global_system_variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
+
+ global_system_variables.sql_mode=
+ expand_sql_mode(global_system_variables.sql_mode);
#if defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
@@ -8595,15 +7105,13 @@ static int get_options(int *argc,char **argv)
test_flags&= ~TEST_CORE_ON_SIGNAL;
}
/* Set global MyISAM variables from delay_key_write_options */
- fix_delay_key_write((THD*) 0, OPT_GLOBAL);
- /* Set global slave_exec_mode from its option */
- fix_slave_exec_mode(OPT_GLOBAL);
+ fix_delay_key_write(0, 0, OPT_GLOBAL);
#ifndef EMBEDDED_LIBRARY
if (mysqld_chroot)
set_root(mysqld_chroot);
#else
- global_system_variables.thread_handling = SCHEDULER_NO_THREADS;
+ thread_handling = SCHEDULER_NO_THREADS;
max_allowed_packet= global_system_variables.max_allowed_packet;
net_buffer_length= global_system_variables.net_buffer_length;
#endif
@@ -8616,34 +7124,27 @@ static int get_options(int *argc,char **argv)
*/
my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
my_default_record_cache_size=global_system_variables.read_buff_size;
- myisam_max_temp_length=
- (my_off_t) global_system_variables.myisam_max_sort_file_size;
- /* Set global variables based on startup options */
- myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
-
- /* long_query_time is in microseconds */
- global_system_variables.long_query_time= max_system_variables.long_query_time=
- (longlong) (long_query_time * 1000000.0);
+ global_system_variables.long_query_time= (ulonglong)
+ (global_system_variables.long_query_time_double * 1e6);
if (opt_short_log_format)
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
- &global_system_variables.date_format) ||
+ &global_date_format) ||
init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
- &global_system_variables.time_format) ||
+ &global_time_format) ||
init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
- &global_system_variables.datetime_format))
+ &global_datetime_format))
return 1;
#ifdef EMBEDDED_LIBRARY
one_thread_scheduler(&thread_scheduler);
#else
- if (global_system_variables.thread_handling <=
- SCHEDULER_ONE_THREAD_PER_CONNECTION)
+ if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
one_thread_per_connection_scheduler(&thread_scheduler);
- else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
+ else if (thread_handling == SCHEDULER_NO_THREADS)
one_thread_scheduler(&thread_scheduler);
else
pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */
@@ -8729,7 +7230,7 @@ static int fix_paths(void)
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
- (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
+ (void) my_load_path(pidfile_name, pidfile_name_ptr, mysql_real_data_home);
(void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
get_relative_path(PLUGINDIR), mysql_home);
opt_plugin_dir_ptr= opt_plugin_dir;
@@ -8749,23 +7250,22 @@ static int fix_paths(void)
(void) my_load_path(lc_messages_dir, lc_messages_dir, buff);
/* If --character-sets-dir isn't given, use shared library dir */
- if (charsets_dir != mysql_charsets_dir)
- {
+ if (charsets_dir)
+ strmake(mysql_charsets_dir, charsets_dir, sizeof(mysql_charsets_dir)-1);
+ else
strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
CHARSET_DIR, NullS);
- }
(void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
charsets_dir=mysql_charsets_dir;
if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
return 1;
+ if (!opt_mysql_tmpdir)
+ opt_mysql_tmpdir= mysql_tmpdir;
#ifdef HAVE_REPLICATION
if (!slave_load_tmpdir)
- {
- if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
- return 1;
- }
+ slave_load_tmpdir= mysql_tmpdir;
#endif /* HAVE_REPLICATION */
/*
Convert the secure-file-priv option to system format, allowing
@@ -8774,106 +7274,12 @@ static int fix_paths(void)
if (opt_secure_file_priv)
{
convert_dirname(buff, opt_secure_file_priv, NullS);
- my_free(opt_secure_file_priv, MYF(0));
+ x_free(opt_secure_file_priv);
opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE));
}
return 0;
}
-
-static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
- const char *option, int *error)
-{
- ulong result;
- const char **ptr;
-
- *error= 0;
- if ((result= find_bit_type(x, bit_lib)) == ~(ulong) 0)
- {
- char *buff= (char *) my_alloca(2048);
- char *cbuf;
- ptr= bit_lib->type_names;
- cbuf= buff + ((!*x) ?
- my_snprintf(buff, 2048, "No option given to %s\n", option) :
- my_snprintf(buff, 2048, "Wrong option to %s. Option(s) given: %s\n",
- option, x));
- cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), "Alternatives are: '%s'", *ptr);
- while (*++ptr)
- cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), ",'%s'", *ptr);
- my_snprintf(cbuf, 2048 - (cbuf-buff), "\n");
- sql_perror(buff);
- *error= 1;
- my_afree(buff);
- return 0;
- }
-
- return result;
-}
-
-
-/**
- @return
- a bitfield from a string of substrings separated by ','
- or
- ~(ulong) 0 on error.
-*/
-
-static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
-{
- bool found_end;
- int found_count;
- const char *end,*i,*j;
- const char **array, *pos;
- ulong found,found_int,bit;
- DBUG_ENTER("find_bit_type");
- DBUG_PRINT("enter",("x: '%s'",x));
-
- found=0;
- found_end= 0;
- pos=(char *) x;
- while (*pos == ' ') pos++;
- found_end= *pos == 0;
- while (!found_end)
- {
- if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
- {
- while (end > pos && end[-1] == ' ')
- end--; /* Skip end-space */
- found_end=1;
- }
- found_int=0; found_count=0;
- for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
- {
- j=pos;
- while (j != end)
- {
- if (my_toupper(mysqld_charset,*i++) !=
- my_toupper(mysqld_charset,*j++))
- goto skip;
- }
- found_int=bit;
- if (! *i)
- {
- found_count=1;
- break;
- }
- else if (j != pos) // Half field found
- {
- found_count++; // Could be one of two values
- }
-skip: ;
- }
- if (found_count != 1)
- DBUG_RETURN(~(ulong) 0); // No unique value
- found|=found_int;
- pos=end+1;
- }
-
- DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
- DBUG_RETURN(found);
-} /* find_bit_type */
-
-
/**
Check if file system used for databases is case insensitive.
@@ -8976,11 +7382,6 @@ void refresh_status(THD *thd)
This section should go away soon
*****************************************************************************/
-#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
-ulong ndb_cache_check_time;
-ulong ndb_extra_logging;
-#endif
-
/*****************************************************************************
Instantiate templates
*****************************************************************************/
@@ -8991,7 +7392,6 @@ template class I_List<THD>;
template class I_List_iterator<THD>;
template class I_List<i_string>;
template class I_List<i_string_pair>;
-template class I_List<NAMED_LIST>;
template class I_List<Statement>;
template class I_List_iterator<Statement>;
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index ac5b1f575de..741815585e2 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -5834,7 +5834,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
SEL_ARG *tree= 0;
MEM_ROOT *alloc= param->mem_root;
uchar *str;
- ulong orig_sql_mode;
+ ulonglong orig_sql_mode;
int err;
DBUG_ENTER("get_mm_leaf");
@@ -7574,7 +7574,6 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
#endif
-
/*
Calculate estimate of number records that will be retrieved by a range
scan on given index using given SEL_ARG intervals tree.
@@ -7811,8 +7810,8 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
param->range_count++;
if (!tmp_min_flag && ! tmp_max_flag &&
(uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
- (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
- HA_NOSAME && min_key_length == max_key_length &&
+ param->table->key_info[keynr].flags & HA_NOSAME &&
+ min_key_length == max_key_length &&
!memcmp(param->min_key, param->max_key, min_key_length) &&
!param->first_null_comp)
{
@@ -8105,8 +8104,7 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
{
KEY *table_key=quick->head->key_info+quick->index;
flag=EQ_RANGE;
- if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
- key->part == table_key->key_parts-1)
+ if ((table_key->flags & HA_NOSAME) && key->part == table_key->key_parts-1)
{
if (!(table_key->flags & HA_NULL_PART_KEY) ||
!null_part_in_key(key,
@@ -8155,8 +8153,7 @@ bool QUICK_RANGE_SELECT::unique_key_range()
if ((tmp->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
{
KEY *key=head->key_info+index;
- return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
- key->key_length == tmp->min_length);
+ return (key->flags & HA_NOSAME) && key->key_length == tmp->min_length;
}
}
return 0;
@@ -8274,8 +8271,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
range->min_length= range->max_length= ref->key_length;
range->min_keypart_map= range->max_keypart_map=
make_prev_keypart_map(ref->key_parts);
- range->flag= ((ref->key_length == key_info->key_length &&
- (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
+ range->flag= (ref->key_length == key_info->key_length ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 8392b2c1c3d..c4df268279a 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -38,7 +38,7 @@
#define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
-RPL_STATUS rpl_status=RPL_NULL;
+uint rpl_status=RPL_NULL;
pthread_mutex_t LOCK_rpl_status;
pthread_cond_t COND_rpl_status;
HASH slave_list;
@@ -49,7 +49,7 @@ TYPELIB rpl_role_typelib = {array_elements(rpl_role_type)-1,"",
const char* rpl_status_type[]=
{
- "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
+ "AUTH_MASTER","IDLE_SLAVE","ACTIVE_SLAVE","LOST_SOLDIER","TROOP_SOLDIER",
"RECOVERY_CAPTAIN","NULL",NullS
};
TYPELIB rpl_status_typelib= {array_elements(rpl_status_type)-1,"",
@@ -98,9 +98,6 @@ static int init_failsafe_rpl_thread(THD* thd)
}
thd->mem_root->free= thd->mem_root->used= 0;
- if (thd->variables.max_join_size == HA_POS_ERROR)
- thd->options|= OPTION_BIG_SELECTS;
-
thd_proc_info(thd, "Thread initialized");
thd->version=refresh_version;
thd->set_time();
diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h
index bce2c727050..f140b026bc1 100644
--- a/sql/repl_failsafe.h
+++ b/sql/repl_failsafe.h
@@ -22,11 +22,11 @@
#include "my_sys.h"
#include "slave.h"
-typedef enum {RPL_AUTH_MASTER=0,RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE,
+typedef enum {RPL_AUTH_MASTER=0,RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE,
RPL_LOST_SOLDIER,RPL_TROOP_SOLDIER,
RPL_RECOVERY_CAPTAIN,RPL_NULL /* inactive */,
RPL_ANY /* wild card used by change_rpl_status */ } RPL_STATUS;
-extern RPL_STATUS rpl_status;
+extern uint rpl_status;
extern pthread_mutex_t LOCK_rpl_status;
extern pthread_cond_t COND_rpl_status;
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index 8e80620dd2c..8f3a41fbeef 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -366,7 +366,6 @@ int prepare_record(TABLE *const table,
*/
for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr)
{
- uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
if ((f->flags & NO_DEFAULT_VALUE_FLAG) &&
(f->real_type() != MYSQL_TYPE_ENUM))
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 4bbafa0253a..70d24f42985 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1043,7 +1043,7 @@ bool Relay_log_info::is_until_satisfied(THD *thd, Log_event *ev)
DBUG_RETURN(FALSE);
log_name= group_master_log_name;
log_pos= (!ev)? group_master_log_pos :
- ((thd->options & OPTION_BEGIN || !ev->log_pos) ?
+ ((thd->variables.option_bits & OPTION_BEGIN || !ev->log_pos) ?
group_master_log_pos : ev->log_pos - ev->data_written);
}
else
@@ -1168,7 +1168,7 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
middle of the "transaction". START SLAVE will resume at BEGIN
while the MyISAM table has already been updated.
*/
- if ((sql_thd->options & OPTION_BEGIN) && opt_using_transactions)
+ if ((sql_thd->variables.option_bits & OPTION_BEGIN) && opt_using_transactions)
inc_event_relay_log_pos();
else
{
@@ -1221,8 +1221,8 @@ void Relay_log_info::cleanup_context(THD *thd, bool error)
/*
Cleanup for the flags that have been set at do_apply_event.
*/
- thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
- thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+ thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+ thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
DBUG_VOID_RETURN;
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index ec314e50cc7..33b708cb1bd 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -22,6 +22,7 @@
struct RPL_TABLE_LIST;
class Master_info;
+extern uint sql_slave_skip_counter;
/****************************************************************************
@@ -426,7 +427,7 @@ public:
@retval false Replication thread is currently not inside a group
*/
bool is_in_group() const {
- return (sql_thd->options & OPTION_BEGIN) ||
+ return (sql_thd->variables.option_bits & OPTION_BEGIN) ||
(m_flags & (1UL << IN_STMT));
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 42829590942..65218dce1eb 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -13,2134 +13,324 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/**
- @file
-
- @brief
- Handling of MySQL SQL variables
-
- @details
- To add a new variable, one has to do the following:
-
- - Use one of the 'sys_var... classes from set_var.h or write a specific
- one for the variable type.
- - Define it in the 'variable definition list' in this file.
- - If the variable is thread specific, add it to 'system_variables' struct.
- If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
- - If the variable should be changed from the command line, add a definition
- 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!
-
- @todo
- Add full support for the variable character_set (for 4.1)
-
- @todo
- When updating myisam_delay_key_write, we should do a 'flush tables'
- of all MyISAM tables to ensure that they are reopen with the
- new attribute.
-
- @note
- Be careful with var->save_result: sys_var::check() only updates
- ulonglong_value; so other members of the union are garbage then; to use
- them you must first assign a value to them (in specific ::check() for
- example).
-*/
-
#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
+#pragma implementation
#endif
-#include "mysql_priv.h"
-#include <mysql.h>
-#include "slave.h"
-#include "rpl_mi.h"
-#include <my_getopt.h>
-#include <thr_alarm.h>
-#include <myisam.h>
-#include <my_dir.h>
-
-#include "events.h"
-
-/* WITH_NDBCLUSTER_STORAGE_ENGINE */
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-extern ulong ndb_cache_check_time;
-extern char opt_ndb_constrbuf[];
-extern ulong ndb_extra_logging;
-#endif
-
-#ifdef HAVE_NDB_BINLOG
-extern ulong ndb_report_thresh_binlog_epoch_slip;
-extern ulong ndb_report_thresh_binlog_mem_usage;
-#endif
-
-extern CHARSET_INFO *character_set_filesystem;
+/* variable declarations are in sys_vars.cc now !!! */
+#include "mysql_priv.h"
+#include "sys_vars_shared.h"
static HASH system_variable_hash;
-
-const char *bool_type_names[]= { "OFF", "ON", NullS };
-TYPELIB bool_typelib=
-{
- array_elements(bool_type_names)-1, "", bool_type_names, NULL
-};
-
-const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
-TYPELIB delay_key_write_typelib=
-{
- array_elements(delay_key_write_type_names)-1, "",
- delay_key_write_type_names, NULL
-};
-
-const char *slave_exec_mode_names[]=
-{ "STRICT", "IDEMPOTENT", NullS };
-static const unsigned int slave_exec_mode_names_len[]=
-{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 };
-TYPELIB slave_exec_mode_typelib=
-{
- array_elements(slave_exec_mode_names)-1, "",
- slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len
-};
-
-static int sys_check_ftb_syntax(THD *thd, set_var *var);
-static bool sys_update_ftb_syntax(THD *thd, set_var * var);
-static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
-static bool sys_update_init_connect(THD*, set_var*);
-static void sys_default_init_connect(THD*, enum_var_type type);
-static bool sys_update_init_slave(THD*, set_var*);
-static void sys_default_init_slave(THD*, enum_var_type type);
-static bool set_option_bit(THD *thd, set_var *var);
-static bool set_option_log_bin_bit(THD *thd, set_var *var);
-static bool set_option_autocommit(THD *thd, set_var *var);
-static int check_log_update(THD *thd, set_var *var);
-static bool set_log_update(THD *thd, set_var *var);
-static int check_pseudo_thread_id(THD *thd, set_var *var);
-void fix_binlog_format_after_update(THD *thd, enum_var_type type);
-static void fix_low_priority_updates(THD *thd, enum_var_type type);
-static int check_tx_isolation(THD *thd, set_var *var);
-static void fix_tx_isolation(THD *thd, enum_var_type type);
-static int check_completion_type(THD *thd, set_var *var);
-static void fix_completion_type(THD *thd, enum_var_type type);
-static void fix_net_read_timeout(THD *thd, enum_var_type type);
-static void fix_net_write_timeout(THD *thd, enum_var_type type);
-static void fix_net_retry_count(THD *thd, enum_var_type type);
-static void fix_max_join_size(THD *thd, enum_var_type type);
-#ifdef HAVE_QUERY_CACHE
-static void fix_query_cache_size(THD *thd, enum_var_type type);
-static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
-#endif
-static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
-static void fix_max_binlog_size(THD *thd, enum_var_type type);
-static void fix_max_relay_log_size(THD *thd, enum_var_type type);
-static void fix_max_connections(THD *thd, enum_var_type type);
-static int check_max_delayed_threads(THD *thd, set_var *var);
-static void fix_thd_mem_root(THD *thd, enum_var_type type);
-static void fix_trans_mem_root(THD *thd, enum_var_type type);
-static void fix_server_id(THD *thd, enum_var_type type);
-bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
- const char *name, longlong val);
-static KEY_CACHE *create_key_cache(const char *name, uint length);
-void fix_sql_mode_var(THD *thd, enum_var_type type);
-static uchar *get_error_count(THD *thd);
-static uchar *get_warning_count(THD *thd);
-static uchar *get_tmpdir(THD *thd);
-static int sys_check_log_path(THD *thd, set_var *var);
-static bool sys_update_general_log_path(THD *thd, set_var * var);
-static void sys_default_general_log_path(THD *thd, enum_var_type type);
-static bool sys_update_slow_log_path(THD *thd, set_var * var);
-static void sys_default_slow_log_path(THD *thd, enum_var_type type);
-static uchar *get_myisam_mmap_size(THD *thd);
-
-/*
- Variable definition list
-
- These are variables that can be set from the command line, in
- alphabetic order.
-
- The variables are linked into the list. A variable is added to
- it in the constructor (see sys_var class for details).
-*/
-
-static sys_var_chain vars = { NULL, NULL };
-
-static sys_var_thd_ulong
-sys_auto_increment_increment(&vars, "auto_increment_increment",
- &SV::auto_increment_increment, NULL, NULL,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_thd_ulong
-sys_auto_increment_offset(&vars, "auto_increment_offset",
- &SV::auto_increment_offset, NULL, NULL,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-
-static sys_var_bool_ptr sys_automatic_sp_privileges(&vars, "automatic_sp_privileges",
- &sp_automatic_privileges);
-
-static sys_var_const sys_back_log(&vars, "back_log",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*) &back_log);
-static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
-static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
- &binlog_cache_size);
-static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
- &SV::binlog_format);
-static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
- &SV::bulk_insert_buff_size);
-static sys_var_const_os sys_character_sets_dir(&vars,
- "character_sets_dir",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*)
- mysql_charsets_dir);
-static sys_var_character_set_sv
-sys_character_set_server(&vars, "character_set_server",
- &SV::collation_server, &default_charset_info, 0,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-sys_var_const_str sys_charset_system(&vars, "character_set_system",
- (char *)my_charset_utf8_general_ci.name);
-static sys_var_character_set_database
-sys_character_set_database(&vars, "character_set_database",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_character_set_client
-sys_character_set_client(&vars, "character_set_client",
- &SV::character_set_client,
- &default_charset_info,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_character_set_sv
-sys_character_set_connection(&vars, "character_set_connection",
- &SV::collation_connection,
- &default_charset_info, 0,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-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);
-static sys_var_collation_sv
-sys_collation_connection(&vars, "collation_connection",
- &SV::collation_connection, &default_charset_info,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_collation_sv
-sys_collation_database(&vars, "collation_database", &SV::collation_database,
- &default_charset_info,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_collation_sv
-sys_collation_server(&vars, "collation_server", &SV::collation_server,
- &default_charset_info,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert",
- &myisam_concurrent_insert);
-static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
- &connect_timeout);
-static sys_var_const_os_str sys_datadir(&vars, "datadir", mysql_real_data_home);
-#ifndef DBUG_OFF
-static sys_var_thd_dbug sys_dbug(&vars, "debug");
-#endif
-static sys_var_enum sys_delay_key_write(&vars, "delay_key_write",
- &delay_key_write_options,
- &delay_key_write_typelib,
- fix_delay_key_write);
-static sys_var_long_ptr sys_delayed_insert_limit(&vars, "delayed_insert_limit",
- &delayed_insert_limit);
-static sys_var_long_ptr sys_delayed_insert_timeout(&vars, "delayed_insert_timeout",
- &delayed_insert_timeout);
-static sys_var_long_ptr sys_delayed_queue_size(&vars, "delayed_queue_size",
- &delayed_queue_size);
-
-#ifdef HAVE_EVENT_SCHEDULER
-static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
-#endif
-
-static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
- &expire_logs_days);
-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);
-static sys_var_const sys_ft_max_word_len(&vars, "ft_max_word_len",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*) &ft_max_word_len);
-static sys_var_const sys_ft_min_word_len(&vars, "ft_min_word_len",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*) &ft_min_word_len);
-static sys_var_const sys_ft_query_expansion_limit(&vars,
- "ft_query_expansion_limit",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*)
- &ft_query_expansion_limit);
-static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &ft_stopword_file);
-
-static sys_var_const sys_ignore_builtin_innodb(&vars, "ignore_builtin_innodb",
- OPT_GLOBAL, SHOW_BOOL,
- (uchar*) &opt_ignore_builtin_innodb);
-
-sys_var_str sys_init_connect(&vars, "init_connect", 0,
- sys_update_init_connect,
- sys_default_init_connect,0);
-static sys_var_const sys_init_file(&vars, "init_file",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &opt_init_file);
-sys_var_str sys_init_slave(&vars, "init_slave", 0,
- sys_update_init_slave,
- sys_default_init_slave,0);
-static sys_var_thd_ulong sys_interactive_timeout(&vars, "interactive_timeout",
- &SV::net_interactive_timeout);
-static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
- &SV::join_buff_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));
-static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_division_limit",
- offsetof(KEY_CACHE,
- param_division_limit));
-static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
- offsetof(KEY_CACHE,
- param_age_threshold));
-static sys_var_const sys_large_files_support(&vars, "large_files_support",
- OPT_GLOBAL, SHOW_BOOL,
- (uchar*) &opt_large_files);
-static sys_var_const sys_large_page_size(&vars, "large_page_size",
- OPT_GLOBAL, SHOW_INT,
- (uchar*) &opt_large_page_size);
-static sys_var_const sys_large_pages(&vars, "large_pages",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*) &opt_large_pages);
-static sys_var_const sys_language(&vars, "lc_messages_dir",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*) lc_messages_dir);
-static sys_var_bool_ptr sys_local_infile(&vars, "local_infile",
- &opt_local_infile);
-#ifdef HAVE_MLOCKALL
-static sys_var_const sys_locked_in_memory(&vars, "locked_in_memory",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*) &locked_in_memory);
-#endif
-static sys_var_const sys_log_bin(&vars, "log_bin",
- OPT_GLOBAL, SHOW_BOOL,
- (uchar*) &opt_bin_log);
-static sys_var_bool_ptr
-sys_trust_function_creators(&vars, "log_bin_trust_function_creators",
- &trust_function_creators);
-static sys_var_const sys_log_error(&vars, "log_error",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*) log_error_file);
-static sys_var_bool_ptr
- sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes",
- &opt_log_queries_not_using_indexes);
-static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
-static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time",
- &SV::long_query_time);
-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 */
-static sys_var_thd_bool sys_sql_low_priority_updates(&vars, "sql_low_priority_updates",
- &SV::low_priority_updates,
- fix_low_priority_updates);
-#endif
-static sys_var_const sys_lower_case_file_system(&vars,
- "lower_case_file_system",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*)
- &lower_case_file_system);
-static sys_var_const sys_lower_case_table_names(&vars,
- "lower_case_table_names",
- OPT_GLOBAL, SHOW_INT,
- (uchar*)
- &lower_case_table_names);
-static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet",
- &SV::max_allowed_packet);
-static sys_var_ulonglong_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size",
- &max_binlog_cache_size);
-static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size",
- &max_binlog_size,
- fix_max_binlog_size);
-static sys_var_long_ptr sys_max_connections(&vars, "max_connections",
- &max_connections,
- fix_max_connections);
-static sys_var_long_ptr sys_max_connect_errors(&vars, "max_connect_errors",
- &max_connect_errors);
-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);
-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);
-static sys_var_thd_ulong sys_max_error_count(&vars, "max_error_count",
- &SV::max_error_count);
-static sys_var_thd_ulonglong sys_max_heap_table_size(&vars, "max_heap_table_size",
- &SV::max_heap_table_size);
-static sys_var_thd_ulong sys_pseudo_thread_id(&vars, "pseudo_thread_id",
- &SV::pseudo_thread_id,
- check_pseudo_thread_id, 0,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_thd_ha_rows sys_max_join_size(&vars, "max_join_size",
- &SV::max_join_size,
- fix_max_join_size);
-static sys_var_thd_ulong sys_max_seeks_for_key(&vars, "max_seeks_for_key",
- &SV::max_seeks_for_key);
-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 */
-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(&vars, "max_prepared_stmt_count",
- &max_prepared_stmt_count,
- &LOCK_prepared_stmt_count);
-static sys_var_long_ptr sys_max_relay_log_size(&vars, "max_relay_log_size",
- &max_relay_log_size,
- fix_max_relay_log_size);
-static sys_var_thd_ulong sys_max_sort_length(&vars, "max_sort_length",
- &SV::max_sort_length);
-static sys_var_thd_ulong sys_max_sp_recursion_depth(&vars, "max_sp_recursion_depth",
- &SV::max_sp_recursion_depth);
-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);
-static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
- &max_write_lock_count);
-static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit",
- &SV::min_examined_row_limit);
-static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count",
- &SV::multi_range_count);
-static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
- &myisam_data_pointer_size);
-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_const sys_myisam_recover_options(&vars, "myisam_recover_options",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*)
- &myisam_recover_options_str);
-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);
-
-static sys_var_thd_enum sys_myisam_stats_method(&vars, "myisam_stats_method",
- &SV::myisam_stats_method,
- &myisam_stats_method_typelib,
- NULL);
-
-#ifdef _WIN32
-/* purecov: begin inspected */
-static sys_var_const sys_named_pipe(&vars, "named_pipe",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*) &opt_enable_named_pipe);
-/* purecov: end */
-#endif
-static sys_var_thd_ulong_session_readonly sys_net_buffer_length(&vars, "net_buffer_length",
- &SV::net_buffer_length);
-static sys_var_thd_ulong sys_net_read_timeout(&vars, "net_read_timeout",
- &SV::net_read_timeout,
- 0, fix_net_read_timeout);
-static sys_var_thd_ulong sys_net_write_timeout(&vars, "net_write_timeout",
- &SV::net_write_timeout,
- 0, fix_net_write_timeout);
-static sys_var_thd_ulong sys_net_retry_count(&vars, "net_retry_count",
- &SV::net_retry_count,
- 0, fix_net_retry_count);
-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);
-/* these two cannot be static */
-sys_var_thd_bool sys_old_alter_table(&vars, "old_alter_table",
- &SV::old_alter_table);
-sys_var_thd_bool sys_old_passwords(&vars, "old_passwords", &SV::old_passwords);
-static sys_var_const sys_open_files_limit(&vars, "open_files_limit",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*)
- &open_files_limit);
-static sys_var_thd_ulong sys_optimizer_prune_level(&vars, "optimizer_prune_level",
- &SV::optimizer_prune_level);
-static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_search_depth",
- &SV::optimizer_search_depth);
-static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
- &SV::optimizer_switch);
-static sys_var_const sys_pid_file(&vars, "pid_file",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*) pidfile_name);
-static sys_var_const_os sys_plugin_dir(&vars, "plugin_dir",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*) opt_plugin_dir);
-static sys_var_const sys_port(&vars, "port",
- OPT_GLOBAL, SHOW_INT,
- (uchar*) &mysqld_port);
-static sys_var_thd_ulong sys_preload_buff_size(&vars, "preload_buffer_size",
- &SV::preload_buff_size);
-static sys_var_const sys_protocol_version(&vars, "protocol_version",
- OPT_GLOBAL, SHOW_INT,
- (uchar*)
- &protocol_version);
-static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size",
- &SV::read_buff_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);
-static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
- &SV::div_precincrement);
-static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
- &rpl_recovery_rank);
-
-static sys_var_thd_ulong sys_range_alloc_block_size(&vars, "range_alloc_block_size",
- &SV::range_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);
-static sys_var_thd_ulong sys_query_prealloc_size(&vars, "query_prealloc_size",
- &SV::query_prealloc_size,
- 0, fix_thd_mem_root);
-#ifdef HAVE_SMEM
-/* purecov: begin tested */
-static sys_var_const sys_shared_memory(&vars, "shared_memory",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*)
- &opt_enable_shared_memory);
-static sys_var_const sys_shared_memory_base_name(&vars,
- "shared_memory_base_name",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*)
- &shared_memory_base_name);
-/* purecov: end */
-#endif
-static sys_var_const sys_skip_external_locking(&vars,
- "skip_external_locking",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*)
- &my_disable_locking);
-static sys_var_const sys_skip_networking(&vars, "skip_networking",
- OPT_GLOBAL, SHOW_BOOL,
- (uchar*) &opt_disable_networking);
-static sys_var_const sys_skip_show_database(&vars, "skip_show_database",
- OPT_GLOBAL, SHOW_BOOL,
- (uchar*) &opt_skip_show_db);
-
-static sys_var_const sys_socket(&vars, "socket",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &mysqld_unix_port);
-
-#ifdef HAVE_THR_SETCONCURRENCY
-/* purecov: begin tested */
-static sys_var_const sys_thread_concurrency(&vars, "thread_concurrency",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*) &concurrency);
-/* purecov: end */
-#endif
-static sys_var_const sys_thread_stack(&vars, "thread_stack",
- OPT_GLOBAL, SHOW_LONG,
- (uchar*) &my_thread_stack_size);
-static sys_var_readonly_os 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);
-static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
- &SV::trans_prealloc_size,
- 0, fix_trans_mem_root);
-sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
- &SV::thread_handling,
- &thread_handling_typelib,
- NULL);
-
-#ifdef HAVE_QUERY_CACHE
-static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
- &query_cache_size,
- fix_query_cache_size);
-static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit",
- &query_cache.query_cache_limit);
-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);
-static int check_query_cache_type(THD *thd, set_var *var);
-static sys_var_thd_enum sys_query_cache_type(&vars, "query_cache_type",
- &SV::query_cache_type,
- &query_cache_type_typelib, NULL,
- check_query_cache_type);
-static sys_var_thd_bool
-sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
- &SV::query_cache_wlock_invalidate);
-#endif /* HAVE_QUERY_CACHE */
-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);
-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);
-static sys_var_set_slave_mode slave_exec_mode(&vars,
- "slave_exec_mode",
- &slave_exec_mode_options,
- &slave_exec_mode_typelib,
- 0);
-static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
- &slow_launch_time);
-static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size",
- &SV::sortbuff_size);
-/*
- sql_mode should *not* have binlog_mode=SESSION_VARIABLE_IN_BINLOG:
- even though it is written to the binlog, the slave ignores the
- MODE_NO_DIR_IN_CREATE variable, so slave's value differs from
- master's (see log_event.cc: Query_log_event::do_apply_event()).
-*/
-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;
-static sys_var_const_os_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca);
-static sys_var_const_os_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath);
-static sys_var_const_os_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert);
-static sys_var_const_os_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher);
-static sys_var_const_os_str_ptr sys_ssl_key(&vars, "ssl_key", &opt_ssl_key);
-#else
-static sys_var_const_os_str sys_ssl_ca(&vars, "ssl_ca", NULL);
-static sys_var_const_os_str sys_ssl_capath(&vars, "ssl_capath", NULL);
-static sys_var_const_os_str sys_ssl_cert(&vars, "ssl_cert", NULL);
-static sys_var_const_os_str sys_ssl_cipher(&vars, "ssl_cipher", NULL);
-static sys_var_const_os_str sys_ssl_key(&vars, "ssl_key", NULL);
-#endif
-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);
-
-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);
-static sys_var_long_ptr sys_table_def_size(&vars, "table_definition_cache",
- &table_def_size);
-static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
- &table_cache_size);
-static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
- &table_lock_wait_timeout);
-
-#if defined(ENABLED_DEBUG_SYNC)
-/* Debug Sync Facility. Implemented in debug_sync.cc. */
-static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
-#endif /* defined(ENABLED_DEBUG_SYNC) */
-
-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(&vars, "thread_pool_size",
- &thread_pool_size);
-#endif
-static sys_var_thd_enum sys_tx_isolation(&vars, "tx_isolation",
- &SV::tx_isolation,
- &tx_isolation_typelib,
- fix_tx_isolation,
- check_tx_isolation);
-static sys_var_thd_ulonglong sys_tmp_table_size(&vars, "tmp_table_size",
- &SV::tmp_table_size);
-static sys_var_bool_ptr sys_timed_mutexes(&vars, "timed_mutexes",
- &timed_mutexes);
-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);
-static sys_var_const_str sys_version_compile_machine(&vars, "version_compile_machine",
- MACHINE_TYPE);
-static sys_var_const_str sys_version_compile_os(&vars, "version_compile_os",
- SYSTEM_TYPE);
-static sys_var_thd_ulong sys_net_wait_timeout(&vars, "wait_timeout",
- &SV::net_wait_timeout);
-
-/* Condition pushdown to storage engine */
-static sys_var_thd_bool
-sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
- &SV::engine_condition_pushdown);
-
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-/* ndb thread specific variable settings */
-static sys_var_thd_ulong
-sys_ndb_autoincrement_prefetch_sz(&vars, "ndb_autoincrement_prefetch_sz",
- &SV::ndb_autoincrement_prefetch_sz);
-static sys_var_thd_bool
-sys_ndb_force_send(&vars, "ndb_force_send", &SV::ndb_force_send);
-#ifdef HAVE_NDB_BINLOG
-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);
-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
-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_const_str
-sys_ndb_connectstring(&vars, "ndb_connectstring", opt_ndb_constrbuf);
-static sys_var_thd_bool
-sys_ndb_index_stat_enable(&vars, "ndb_index_stat_enable",
- &SV::ndb_index_stat_enable);
-static sys_var_thd_ulong
-sys_ndb_index_stat_cache_entries(&vars, "ndb_index_stat_cache_entries",
- &SV::ndb_index_stat_cache_entries);
-static sys_var_thd_ulong
-sys_ndb_index_stat_update_freq(&vars, "ndb_index_stat_update_freq",
- &SV::ndb_index_stat_update_freq);
-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);
-#endif //WITH_NDBCLUSTER_STORAGE_ENGINE
-
-/* Time/date/datetime formats */
-
-static sys_var_thd_date_time_format sys_time_format(&vars, "time_format",
- &SV::time_format,
- MYSQL_TIMESTAMP_TIME);
-static sys_var_thd_date_time_format sys_date_format(&vars, "date_format",
- &SV::date_format,
- MYSQL_TIMESTAMP_DATE);
-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(&vars, "autocommit", 0,
- set_option_autocommit,
- OPTION_NOT_AUTOCOMMIT,
- 1);
-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(&vars, "sql_big_tables", 0,
- set_option_bit,
- OPTION_BIG_TABLES);
-#endif
-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(&vars, "sql_log_off",
- check_log_update,
- set_option_bit,
- OPTION_LOG_OFF);
-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(&vars, "sql_log_bin",
- check_log_update,
- set_option_log_bin_bit,
- OPTION_BIN_LOG);
-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(&vars, "sql_notes", 0,
- set_option_bit,
- OPTION_SQL_NOTES);
-static sys_var_thd_bit sys_auto_is_null(&vars, "sql_auto_is_null", 0,
- set_option_bit,
- OPTION_AUTO_IS_NULL, 0,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-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(&vars, "sql_buffer_result", 0,
- set_option_bit,
- OPTION_BUFFER_RESULT);
-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(&vars, "foreign_key_checks", 0,
- set_option_bit,
- OPTION_NO_FOREIGN_KEY_CHECKS,
- 1, sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_thd_bit sys_unique_checks(&vars, "unique_checks", 0,
- set_option_bit,
- OPTION_RELAXED_UNIQUE_CHECKS,
- 1,
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-#if defined(ENABLED_PROFILING)
-static sys_var_thd_bit sys_profiling(&vars, "profiling", NULL,
- set_option_bit,
- ulonglong(OPTION_PROFILING));
-static sys_var_thd_ulong sys_profiling_history_size(&vars, "profiling_history_size",
- &SV::profiling_history_size);
-#endif
-
-/* Local state variables */
-
-static sys_var_thd_ha_rows sys_select_limit(&vars, "sql_select_limit",
- &SV::select_limit);
-static sys_var_timestamp sys_timestamp(&vars, "timestamp",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_last_insert_id
-sys_last_insert_id(&vars, "last_insert_id",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-/*
- identity is an alias for last_insert_id(), so that we are compatible
- with Sybase
-*/
-static sys_var_last_insert_id
-sys_identity(&vars, "identity", sys_var::SESSION_VARIABLE_IN_BINLOG);
-
-static sys_var_thd_lc_messages
-sys_lc_messages(&vars, "lc_messages", sys_var::NOT_IN_BINLOG);
-
-static sys_var_thd_lc_time_names
-sys_lc_time_names(&vars, "lc_time_names", sys_var::SESSION_VARIABLE_IN_BINLOG);
-
-/*
- insert_id should *not* be marked as written to the binlog (i.e., it
- should *not* have binlog_status==SESSION_VARIABLE_IN_BINLOG),
- because we want any statement that refers to insert_id explicitly to
- be unsafe. (By "explicitly", we mean using @@session.insert_id,
- whereas insert_id is used "implicitly" when NULL value is inserted
- into an auto_increment column).
-
- We want statements referring explicitly to @@session.insert_id to be
- unsafe, because insert_id is modified internally by the slave sql
- thread when NULL values are inserted in an AUTO_INCREMENT column.
- This modification interfers with the value of the
- @@session.insert_id variable if @@session.insert_id is referred
- explicitly by an insert statement (as is seen by executing "SET
- @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
- AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
- statement-based logging mode: t will be different on master and
- slave).
-*/
-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(&vars, "warning_count",
- OPT_SESSION,
- SHOW_LONG,
- get_warning_count);
-
-static sys_var_rand_seed1 sys_rand_seed1(&vars, "rand_seed1",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-static sys_var_rand_seed2 sys_rand_seed2(&vars, "rand_seed2",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-
-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(&vars, "group_concat_max_len",
- &SV::group_concat_max_len);
-
-sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
- sys_var::SESSION_VARIABLE_IN_BINLOG);
-
-/* Global read-only variable containing hostname */
-static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
-
-#ifndef EMBEDDED_LIBRARY
-static sys_var_const_str_ptr sys_repl_report_host(&vars, "report_host", &report_host);
-static sys_var_const_str_ptr sys_repl_report_user(&vars, "report_user", &report_user);
-static sys_var_const_str_ptr sys_repl_report_password(&vars, "report_password", &report_password);
-
-static uchar *slave_get_report_port(THD *thd)
-{
- thd->sys_var_tmp.long_value= report_port;
- return (uchar*) &thd->sys_var_tmp.long_value;
-}
-
-static sys_var_readonly sys_repl_report_port(&vars, "report_port", OPT_GLOBAL, SHOW_LONG, slave_get_report_port);
-
-#endif
-
-sys_var_thd_bool sys_keep_files_on_create(&vars, "keep_files_on_create",
- &SV::keep_files_on_create);
-/* Read only variables */
-
-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_ssl);
-static sys_var_have_variable sys_have_ssl(&vars, "have_ssl", &have_ssl);
-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_profiling(&vars, "have_profiling", &have_profiling);
-static sys_var_have_variable sys_have_query_cache(&vars, "have_query_cache",
- &have_query_cache);
-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 */
-static sys_var_const_str sys_license(&vars, "license", STRINGIFY_ARG(LICENSE));
-/* Global variables which enable|disable logging */
-static sys_var_log_state sys_var_general_log(&vars, "general_log", &opt_log,
- QUERY_LOG_GENERAL);
-/* Synonym of "general_log" for consistency with SHOW VARIABLES output */
-static sys_var_log_state sys_var_log(&vars, "log", &opt_log,
- QUERY_LOG_GENERAL);
-static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
- QUERY_LOG_SLOW);
-/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
-static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
- &opt_slow_log, QUERY_LOG_SLOW);
-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(&vars, "slow_query_log_file", sys_check_log_path,
- sys_update_slow_log_path,
- sys_default_slow_log_path,
- opt_slow_logname);
-static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
- &log_output_typelib, 0);
-static sys_var_readonly sys_myisam_mmap_size(&vars, "myisam_mmap_size",
- OPT_GLOBAL,
- SHOW_LONGLONG,
- get_myisam_mmap_size);
-
-
-bool sys_var::check(THD *thd, set_var *var)
-{
- var->save_result.ulonglong_value= var->value->val_int();
- return 0;
-}
-
-bool sys_var_str::check(THD *thd, set_var *var)
-{
- int res;
- if (!check_func)
- return 0;
-
- if ((res=(*check_func)(thd, var)) < 0)
- {
- ErrConvString err(&var->value->str_value);
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, err.ptr());
- }
- return res;
-}
-
-/*
- Functions to check and update variables
-*/
-
-
-/*
- Update variables 'init_connect, init_slave'.
-
- In case of 'DEFAULT' value
- (for example: 'set GLOBAL init_connect=DEFAULT')
- 'var' parameter is NULL pointer.
-*/
-
-bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
- set_var *var)
-{
- char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
- uint new_length= (var ? var->value->str_value.length() : 0);
- if (!old_value)
- old_value= (char*) "";
- if (!(res= my_strndup(old_value, new_length, MYF(0))))
- return 1;
- /*
- Replace the old value in such a way that the any thread using
- the value will work.
- */
- rw_wrlock(var_mutex);
- old_value= var_str->value;
- var_str->value= res;
- var_str->value_length= new_length;
- var_str->is_os_charset= FALSE;
- rw_unlock(var_mutex);
- my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
- return 0;
-}
-
-
-static bool sys_update_init_connect(THD *thd, set_var *var)
-{
- return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
-}
-
-
-static void sys_default_init_connect(THD* thd, enum_var_type type)
-{
- update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
-}
-
-
-static bool sys_update_init_slave(THD *thd, set_var *var)
-{
- return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
-}
-
-
-static void sys_default_init_slave(THD* thd, enum_var_type type)
-{
- update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
-}
-
-static int sys_check_ftb_syntax(THD *thd, set_var *var)
-{
- if (thd->security_ctx->master_access & SUPER_ACL)
- return (ft_boolean_check_syntax_string((uchar*)
- var->value->str_value.c_ptr()) ?
- -1 : 0);
- else
- {
- my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
- return 1;
- }
-}
-
-static bool sys_update_ftb_syntax(THD *thd, set_var * var)
-{
- strmake(ft_boolean_syntax, var->value->str_value.c_ptr(),
- sizeof(ft_boolean_syntax)-1);
-
-#ifdef HAVE_QUERY_CACHE
- query_cache.flush();
-#endif /* HAVE_QUERY_CACHE */
-
- return 0;
-}
-
-static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
-{
- strmake(ft_boolean_syntax, def_ft_boolean_syntax,
- sizeof(ft_boolean_syntax)-1);
-}
-
+static PolyLock_mutex PLock_global_system_variables(&LOCK_global_system_variables);
/**
- If one sets the LOW_PRIORIY UPDATES flag, we also must change the
- used lock type.
-*/
-
-static void fix_low_priority_updates(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- thr_upgraded_concurrent_insert_lock=
- (global_system_variables.low_priority_updates ?
- TL_WRITE_LOW_PRIORITY : TL_WRITE);
- else
- thd->update_lock_default= (thd->variables.low_priority_updates ?
- TL_WRITE_LOW_PRIORITY : TL_WRITE);
-}
-
-
-static void
-fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
-{
- myisam_max_temp_length=
- (my_off_t) global_system_variables.myisam_max_sort_file_size;
-}
-
-/**
- Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
+ Return variable name and length for hashing of variables.
*/
-static void fix_max_join_size(THD *thd, enum_var_type type)
+static uchar *get_sys_var_length(const sys_var *var, size_t *length,
+ my_bool first)
{
- if (type != OPT_GLOBAL)
- {
- if (thd->variables.max_join_size == HA_POS_ERROR)
- thd->options|= OPTION_BIG_SELECTS;
- else
- thd->options&= ~OPTION_BIG_SELECTS;
- }
+ *length= var->name.length;
+ return (uchar*) var->name.str;
}
+sys_var_chain all_sys_vars = { NULL, NULL };
-/**
- Can't change the 'next' tx_isolation while we are already in
- a transaction
-*/
-static int check_tx_isolation(THD *thd, set_var *var)
-{
- if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
- {
- my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
- return 1;
- }
- return 0;
-}
-
-/*
- If one doesn't use the SESSION modifier, the isolation level
- is only active for the next command.
-*/
-static void fix_tx_isolation(THD *thd, enum_var_type type)
+int sys_var_init(DYNAMIC_ARRAY *long_options)
{
- if (type == OPT_SESSION)
- thd->session_tx_isolation= ((enum_tx_isolation)
- thd->variables.tx_isolation);
-}
+ uint count= 0;
+ uint saved_elements= long_options->elements;
-static void fix_completion_type(THD *thd __attribute__((unused)),
- enum_var_type type __attribute__((unused))) {}
-
-static int check_completion_type(THD *thd, set_var *var)
-{
- longlong val= var->value->val_int();
- if (val < 0 || val > 2)
- {
- char buf[64];
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
- return 1;
- }
- return 0;
-}
+ DBUG_ENTER("sys_var_init");
+ for (sys_var *var=all_sys_vars.first; var; var= var->next, count++)
+ if (var->register_option(long_options))
+ goto error;
-/*
- If we are changing the thread variable, we have to copy it to NET too
-*/
+ if (my_hash_init(&system_variable_hash, system_charset_info, 100, 0,
+ 0, (my_hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
+ goto error;
-#ifdef HAVE_REPLICATION
-static void fix_net_read_timeout(THD *thd, enum_var_type type)
-{
- if (type != OPT_GLOBAL)
- my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
-}
+ if (mysql_add_sys_var_chain(all_sys_vars.first))
+ goto error;
+ DBUG_RETURN(0);
-static void fix_net_write_timeout(THD *thd, enum_var_type type)
-{
- if (type != OPT_GLOBAL)
- my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
+error:
+ fprintf(stderr, "failed to initialize System variables");
+ long_options->elements= saved_elements;
+ DBUG_RETURN(1);
}
-static void fix_net_retry_count(THD *thd, enum_var_type type)
+void sys_var_end()
{
- if (type != OPT_GLOBAL)
- thd->net.retry_count=thd->variables.net_retry_count;
-}
-#else /* HAVE_REPLICATION */
-static void fix_net_read_timeout(THD *thd __attribute__((unused)),
- enum_var_type type __attribute__((unused)))
-{}
-static void fix_net_write_timeout(THD *thd __attribute__((unused)),
- enum_var_type type __attribute__((unused)))
-{}
-static void fix_net_retry_count(THD *thd __attribute__((unused)),
- enum_var_type type __attribute__((unused)))
-{}
-#endif /* HAVE_REPLICATION */
+ DBUG_ENTER("sys_var_end");
-#ifdef HAVE_QUERY_CACHE
-static void fix_query_cache_size(THD *thd, enum_var_type type)
-{
- ulong new_cache_size= query_cache.resize(query_cache_size);
+ my_hash_free(&system_variable_hash);
- /*
- Note: query_cache_size is a global variable reflecting the
- requested cache size. See also query_cache_size_arg
- */
+ for (sys_var *var=all_sys_vars.first; var; var= var->next)
+ var->~sys_var();
- if (query_cache_size != new_cache_size)
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
- query_cache_size, new_cache_size);
-
- query_cache_size= new_cache_size;
+ DBUG_VOID_RETURN;
}
-
/**
- Trigger before query_cache_type variable is updated.
- @param thd Thread handler
- @param var Pointer to the new variable status
-
- @return Status code
- @retval 1 Failure
- @retval 0 Success
-*/
-
-static int check_query_cache_type(THD *thd, set_var *var)
-{
- /*
- Don't allow changes of the query_cache_type if the query cache
- is disabled.
- */
- if (query_cache.is_disabled())
+ sys_var constructor
+
+ @param chain variables are linked into chain for mysql_add_sys_var_chain()
+ @param name_arg the name of the variable. @sa my_option::name
+ @param comment shown in mysqld --help, @sa my_option::comment
+ @param flags_arg or'ed flag_enum values
+ @param off offset of the global variable value from the
+ &global_system_variables.
+ @param getopt_id -1 for no command-line option, otherwise @sa my_option::id
+ @param getopt_arg_type @sa my_option::arg_type
+ @param show_val_type_arg what value_ptr() returns for sql_show.cc
+ @param def_val default value, @sa my_option::def_value
+ @param lock mutex or rw_lock that protects the global variable
+ *in addition* to LOCK_global_system_variables.
+ @param binlog_status_enum @sa binlog_status_enum
+ @param on_check_func a function to be called at the end of sys_var::check,
+ put your additional checks here
+ @param on_update_func a function to be called at the end of sys_var::update,
+ any post-update activity should happen here
+ @param deprecated_version if not 0 - when this variable will go away
+ @param substitute if not 0 - what one should use instead when this
+ deprecated variable
+*/
+sys_var::sys_var(sys_var_chain *chain, const char *name_arg,
+ const char *comment, int flags_arg, ptrdiff_t off,
+ int getopt_id, enum get_opt_arg_type getopt_arg_type,
+ SHOW_TYPE show_val_type_arg, longlong def_val,
+ PolyLock *lock, enum binlog_status_enum binlog_status_arg,
+ on_check_function on_check_func,
+ on_update_function on_update_func,
+ uint deprecated_version, const char *substitute) :
+ next(0),
+ binlog_status(binlog_status_arg),
+ flags(flags_arg), show_val_type(show_val_type_arg),
+ guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func),
+ is_os_charset(FALSE)
+{
+ name.str= name_arg;
+ name.length= strlen(name_arg);
+ DBUG_ASSERT(name.length <= NAME_CHAR_LEN);
+
+ bzero(&option, sizeof(option));
+ option.name= name_arg;
+ option.id= getopt_id;
+ option.comment= comment;
+ option.arg_type= getopt_arg_type;
+ option.value= (uchar **)global_var_ptr();
+ option.def_value= def_val;
+
+ deprecated.version= deprecated_version;
+ deprecated.substitute= substitute;
+ DBUG_ASSERT((deprecated_version != 0) || (substitute == 0));
+ DBUG_ASSERT(deprecated_version % 100 == 0);
+ DBUG_ASSERT(!deprecated_version || MYSQL_VERSION_ID < deprecated_version);
+
+ if (chain->last)
+ chain->last->next= this;
+ else
+ chain->first= this;
+ chain->last= this;
+}
+
+bool sys_var::update(THD *thd, set_var *var)
+{
+ enum_var_type type= var->type;
+ if (type == OPT_GLOBAL || scope() == GLOBAL)
{
- my_error(ER_QUERY_CACHE_DISABLED,MYF(0));
- return 1;
+ /*
+ Yes, both locks need to be taken before an update, just as
+ both are taken to get a value. If we'll take only 'guard' here,
+ then value_ptr() for strings won't be safe in SHOW VARIABLES anymore,
+ to make it safe we'll need value_ptr_unlock().
+ */
+ AutoWLock lock1(&PLock_global_system_variables);
+ AutoWLock lock2(guard);
+ return global_update(thd, var) ||
+ (on_update && on_update(this, thd, OPT_GLOBAL));
}
-
- return 0;
-}
-
-
-static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
-{
- query_cache_min_res_unit=
- query_cache.set_min_res_unit(query_cache_min_res_unit);
+ else
+ return session_update(thd, var) ||
+ (on_update && on_update(this, thd, OPT_SESSION));
}
-#endif
-
-extern void fix_delay_key_write(THD *thd, enum_var_type type)
+uchar *sys_var::session_value_ptr(THD *thd, LEX_STRING *base)
{
- switch ((enum_delay_key_write) delay_key_write_options) {
- case DELAY_KEY_WRITE_NONE:
- myisam_delay_key_write=0;
- break;
- case DELAY_KEY_WRITE_ON:
- myisam_delay_key_write=1;
- break;
- case DELAY_KEY_WRITE_ALL:
- myisam_delay_key_write=1;
- ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
- break;
- }
+ return session_var_ptr(thd);
}
-bool sys_var_set::update(THD *thd, set_var *var)
+uchar *sys_var::global_value_ptr(THD *thd, LEX_STRING *base)
{
- *value= var->save_result.ulong_value;
- return 0;
+ return global_var_ptr();
}
-uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
+bool sys_var::check(THD *thd, set_var *var)
{
- char buff[256];
- String tmp(buff, sizeof(buff), &my_charset_latin1);
- ulong length;
- ulong val= *value;
-
- tmp.length(0);
- for (uint i= 0; val; val>>= 1, i++)
+ do_deprecated_warning(thd);
+ if ((var->value && do_check(thd, var))
+ || (on_check && on_check(this, thd, var)))
{
- if (val & 1)
+ if (!thd->is_error())
{
- tmp.append(enum_names->type_names[i],
- enum_names->type_lengths[i]);
- tmp.append(',');
- }
- }
-
- if ((length= tmp.length()))
- length--;
- return (uchar*) thd->strmake(tmp.ptr(), length);
-}
-
-void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
-{
- slave_exec_mode_options= 0;
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
-}
-
-bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
-{
- bool rc= sys_var_set::check(thd, var);
- if (!rc &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
- {
- rc= true;
- my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
- }
- return rc;
-}
-
-bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
-{
- bool rc;
- pthread_mutex_lock(&LOCK_global_system_variables);
- rc= sys_var_set::update(thd, var);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return rc;
-}
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
-void fix_slave_exec_mode(enum_var_type type)
-{
- DBUG_ENTER("fix_slave_exec_mode");
- compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
- > SLAVE_EXEC_MODE_LAST_BIT - 1);
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
- bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
- {
- sql_print_error("Ambiguous slave modes combination."
- " STRICT will be used");
- bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
+ if (!var->value)
+ {
+ str.set(STRING_WITH_LEN("DEFAULT"), &my_charset_latin1);
+ res= &str;
+ }
+ else if (!(res=var->value->val_str(&str)))
+ {
+ str.set(STRING_WITH_LEN("NULL"), &my_charset_latin1);
+ res= &str;
+ }
+ ErrConvString err(res);
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr());
+ }
+ return true;
}
- if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
- bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
- DBUG_VOID_RETURN;
-}
-
-
-bool sys_var_thd_binlog_format::check(THD *thd, set_var *var) {
- /*
- All variables that affect writing to binary log (either format or
- turning logging on and off) use the same checking. We call the
- superclass ::check function to assign the variable correctly, and
- then check the value.
- */
- bool result= sys_var_thd_enum::check(thd, var);
- if (!result)
- result= check_log_update(thd, var);
- return result;
+ return false;
}
-
-bool sys_var_thd_binlog_format::is_readonly() const
+uchar *sys_var::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
{
- /*
- Under certain circumstances, the variable is read-only (unchangeable):
- */
- THD *thd= current_thd;
- /*
- If RBR and open temporary tables, their CREATE TABLE may not be in the
- binlog, so we can't toggle to SBR in this connection.
- The test below will also prevent SET GLOBAL, well it was not easy to test
- if global or not here.
- And this test will also prevent switching from RBR to RBR (a no-op which
- should not happen too often).
-
- If we don't have row-based replication compiled in, the variable
- is always read-only.
- */
- if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
- thd->temporary_tables)
- {
- my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
- return 1;
- }
- /*
- if in a stored function/trigger, it's too late to change mode
- */
- if (thd->in_sub_stmt)
+ if (type == OPT_GLOBAL || scope() == GLOBAL)
{
- my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
- return 1;
+ safe_mutex_assert_owner(&LOCK_global_system_variables);
+ AutoRLock lock(guard);
+ return global_value_ptr(thd, base);
}
- return sys_var_thd_enum::is_readonly();
+ else
+ return session_value_ptr(thd, base);
}
-
-void fix_binlog_format_after_update(THD *thd, enum_var_type type)
+bool sys_var::set_default(THD *thd, enum_var_type type)
{
- thd->reset_current_stmt_binlog_row_based();
-}
-
+ LEX_STRING empty={0,0};
+ set_var var(type, 0, &empty, 0);
-static void fix_max_binlog_size(THD *thd, enum_var_type type)
-{
- DBUG_ENTER("fix_max_binlog_size");
- DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
- max_binlog_size, max_relay_log_size));
- mysql_bin_log.set_max_size(max_binlog_size);
-#ifdef HAVE_REPLICATION
- if (!max_relay_log_size)
- active_mi->rli.relay_log.set_max_size(max_binlog_size);
-#endif
- DBUG_VOID_RETURN;
-}
+ if (type == OPT_GLOBAL || scope() == GLOBAL)
+ global_save_default(thd, &var);
+ else
+ session_save_default(thd, &var);
-static void fix_max_relay_log_size(THD *thd, enum_var_type type)
-{
- DBUG_ENTER("fix_max_relay_log_size");
- DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
- max_binlog_size, max_relay_log_size));
-#ifdef HAVE_REPLICATION
- active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
- max_relay_log_size: max_binlog_size);
-#endif
- DBUG_VOID_RETURN;
+ return check(thd, &var) || update(thd, &var);
}
-
-static int check_max_delayed_threads(THD *thd, set_var *var)
+void sys_var::do_deprecated_warning(THD *thd)
{
- longlong val= var->value->val_int();
- if (var->type != OPT_GLOBAL && val != 0 &&
- val != (longlong) global_system_variables.max_insert_delayed_threads)
+ if (deprecated.version)
{
- char buf[64];
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
- return 1;
+ char buf1[NAME_CHAR_LEN + 3], buf2[10];
+ strxnmov(buf1, sizeof(buf1)-1, "@@", name.str, 0);
+ my_snprintf(buf2, sizeof(buf2), "%d.%d", deprecated.version/100/100,
+ deprecated.version/100%100);
+ uint errmsg= deprecated.substitute
+ ? ER_WARN_DEPRECATED_SYNTAX_WITH_VER
+ : ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT;
+ if (thd)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DEPRECATED_SYNTAX, ER(errmsg),
+ buf1, buf2, deprecated.substitute);
+ else
+ sql_print_warning(ER_DEFAULT(errmsg), buf1, buf2, deprecated.substitute);
}
- return 0;
-}
-
-static void fix_max_connections(THD *thd, enum_var_type type)
-{
-#ifndef EMBEDDED_LIBRARY
- resize_thr_alarm(max_connections +
- global_system_variables.max_insert_delayed_threads + 10);
-#endif
-}
-
-
-static void fix_thd_mem_root(THD *thd, enum_var_type type)
-{
- if (type != OPT_GLOBAL)
- reset_root_defaults(thd->mem_root,
- thd->variables.query_alloc_block_size,
- thd->variables.query_prealloc_size);
-}
-
-
-static void fix_trans_mem_root(THD *thd, enum_var_type type)
-{
- if (type != OPT_GLOBAL)
- reset_root_defaults(&thd->transaction.mem_root,
- thd->variables.trans_alloc_block_size,
- thd->variables.trans_prealloc_size);
-}
-
-
-static void fix_server_id(THD *thd, enum_var_type type)
-{
- server_id_supplied = 1;
- thd->server_id= server_id;
}
-
/**
Throw warning (error in STRICT mode) if value for variable needed bounding.
- Only call from check(), not update(), because an error in update() would be
- bad mojo. Plug-in interface also uses this.
+ Plug-in interface also uses this.
- @param thd thread handle
- @param fixed did we have to correct the value? (throw warn/err if so)
- @param unsignd is value's type unsigned?
- @param name variable's name
- @param val variable's value
+ @param thd thread handle
+ @param name variable's name
+ @param fixed did we have to correct the value? (throw warn/err if so)
+ @param is_unsigned is value's type unsigned?
+ @param v variable's value
- @retval TRUE on error, FALSE otherwise (warning or OK)
+ @retval true on error, false otherwise (warning or ok)
*/
-bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
- const char *name, longlong val)
+bool throw_bounds_warning(THD *thd, const char *name,
+ bool fixed, bool is_unsigned, longlong v)
{
- if (fixed)
+ if (fixed || (!is_unsigned && v < 0))
{
char buf[22];
- if (unsignd)
- ullstr((ulonglong) val, buf);
+ if (is_unsigned)
+ ullstr((ulonglong) v, buf);
else
- llstr(val, buf);
+ llstr(v, buf);
if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
- return TRUE;
+ return true;
}
-
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
}
- return FALSE;
-}
-
-
-/**
- check an unsigned user-supplied value for a systemvariable against bounds.
-
- TODO: This is a wrapper function to call clipping from within an update()
- function. Calling bounds from within update() is fair game in theory,
- but we can only send warnings from in there, not errors, and besides,
- it violates our model of separating check from update phase.
- To avoid breaking out of the server with an ASSERT() in strict mode,
- we pretend we're not in strict mode when we go through here. Bug#43233
- was opened to remind us to replace this kludge with The Right Thing,
- which of course is to do the check in the actual check phase, and then
- throw an error or warning accordingly.
-
- @param thd thread handle
- @param num the value to limit
- @param option_limits the bounds-record, or NULL if none
- */
-static void bound_unsigned(THD *thd, ulonglong *num,
- const struct my_option *option_limits)
-{
- if (option_limits)
- {
- my_bool fixed = FALSE;
- ulonglong unadjusted= *num;
-
- *num= getopt_ull_limit_value(unadjusted, option_limits, &fixed);
-
- if (fixed)
- {
- ulong ssm= thd->variables.sql_mode;
- thd->variables.sql_mode&= ~MODE_STRICT_ALL_TABLES;
- throw_bounds_warning(thd, fixed, TRUE, option_limits->name, unadjusted);
- thd->variables.sql_mode= ssm;
- }
- }
-}
-
-
-/**
- Get unsigned system-variable.
- Negative value does not wrap around, but becomes zero.
- Check user-supplied value for a systemvariable against bounds.
- If we needed to adjust the value, throw a warning or error depending
- on SQL-mode.
-
- @param thd thread handle
- @param var the system-variable to get
- @param user_max a limit given with --maximum-variable-name=... or 0
- @param var_type function will bound on systems where necessary.
-
- @retval TRUE on error, FALSE otherwise (warning or OK)
- */
-static bool get_unsigned(THD *thd, set_var *var, ulonglong user_max,
- ulong var_type)
-{
- int warnings= 0;
- ulonglong unadjusted;
- const struct my_option *limits= var->var->option_limits;
- struct my_option fallback;
-
- /* get_unsigned() */
- if (var->value->unsigned_flag)
- var->save_result.ulonglong_value= (ulonglong) var->value->val_int();
- else
- {
- longlong v= var->value->val_int();
- var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v);
- if (v < 0)
- {
- warnings++;
- if (throw_bounds_warning(thd, TRUE, FALSE, var->var->name, v))
- return TRUE; /* warning was promoted to error, give up */
- }
- }
-
- unadjusted= var->save_result.ulonglong_value;
-
- /* max, if any */
-
- if ((user_max > 0) && (unadjusted > user_max))
- {
- var->save_result.ulonglong_value= user_max;
-
- if ((warnings == 0) && throw_bounds_warning(thd, TRUE, TRUE,
- var->var->name,
- (longlong) unadjusted))
- return TRUE;
-
- warnings++;
- }
-
- /*
- if the sysvar doesn't have a proper bounds record but the check
- function would like bounding to ULONG where its size differs from
- that of ULONGLONG, we make up a bogus limits record here and let
- the usual suspects handle the actual limiting.
- */
-
- if (!limits && var_type != GET_ULL)
- {
- bzero(&fallback, sizeof(fallback));
- fallback.var_type= var_type;
- limits= &fallback;
- }
-
- /* fix_unsigned() */
- if (limits)
- {
- my_bool fixed;
-
- var->save_result.ulonglong_value= getopt_ull_limit_value(var->save_result.
- ulonglong_value,
- limits, &fixed);
-
- if ((warnings == 0) && throw_bounds_warning(thd, fixed, TRUE,
- var->var->name,
- (longlong) unadjusted))
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-bool sys_var_uint_ptr::check(THD *thd, set_var *var)
-{
- var->save_result.ulong_value= (ulong) var->value->val_uint();
- return 0;
-}
-
-bool sys_var_uint_ptr::update(THD *thd, set_var *var)
-{
- *value= (uint) var->save_result.ulong_value;
- return 0;
-}
-
-void sys_var_uint_ptr::set_default(THD *thd, enum_var_type type)
-{
- *value= (uint) option_limits->def_value;
-}
-
-sys_var_long_ptr::
-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(chain, name_arg, value_ptr_arg,
- &LOCK_global_system_variables, after_update_arg)
-{}
-
-
-bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
-{
- return get_unsigned(thd, var, 0, GET_ULONG);
+ return false;
}
-bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
+bool throw_bounds_warning(THD *thd, const char *name, bool fixed, double v)
{
- pthread_mutex_lock(guard);
- *value= (ulong) var->save_result.ulonglong_value;
- pthread_mutex_unlock(guard);
- return 0;
-}
-
-
-void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
-{
- my_bool not_used;
- pthread_mutex_lock(guard);
- *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
- option_limits, &not_used);
- pthread_mutex_unlock(guard);
-}
-
-
-bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
-{
- ulonglong tmp= var->save_result.ulonglong_value;
- pthread_mutex_lock(&LOCK_global_system_variables);
- bound_unsigned(thd, &tmp, option_limits);
- *value= (ulonglong) tmp;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return 0;
-}
-
-
-void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
-{
- my_bool not_used;
- pthread_mutex_lock(&LOCK_global_system_variables);
- *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
- option_limits, &not_used);
- pthread_mutex_unlock(&LOCK_global_system_variables);
-}
-
-
-bool sys_var_bool_ptr::update(THD *thd, set_var *var)
-{
- *value= (my_bool) var->save_result.ulong_value;
- return 0;
-}
-
-
-void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
-{
- *value= (my_bool) option_limits->def_value;
-}
-
-
-bool sys_var_enum::update(THD *thd, set_var *var)
-{
- *value= (uint) var->save_result.ulong_value;
- return 0;
-}
-
-
-uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
-{
- return (uchar*) enum_names->type_names[*value];
-}
-
-
-uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- return (uchar*) enum_names->type_names[global_system_variables.*offset];
-}
-
-bool sys_var_thd_ulong::check(THD *thd, set_var *var)
-{
- if (get_unsigned(thd, var, max_system_variables.*offset, GET_ULONG))
- return TRUE;
- DBUG_ASSERT(var->save_result.ulonglong_value <= ULONG_MAX);
- return ((check_func && (*check_func)(thd, var)));
-}
-
-bool sys_var_thd_ulong::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.*offset= (ulong) var->save_result.ulonglong_value;
- else
- thd->variables.*offset= (ulong) var->save_result.ulonglong_value;
-
- return 0;
-}
-
-
-void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- {
- my_bool not_used;
- /* We will not come here if option_limits is not set */
- global_system_variables.*offset=
- (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
- option_limits, &not_used);
- }
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type == OPT_GLOBAL)
- return (uchar*) &(global_system_variables.*offset);
- return (uchar*) &(thd->variables.*offset);
-}
-
-
-bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
-{
- ulonglong tmp= var->save_result.ulonglong_value;
-
- /* Don't use bigger value than given with --maximum-variable-name=.. */
- if ((ha_rows) tmp > max_system_variables.*offset)
- tmp= max_system_variables.*offset;
-
- bound_unsigned(thd, &tmp, option_limits);
-
- if (var->type == OPT_GLOBAL)
- {
- /* Lock is needed to make things safe on 32 bit systems */
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ha_rows) tmp;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= (ha_rows) tmp;
- return 0;
-}
-
-
-void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- {
- my_bool not_used;
- /* We will not come here if option_limits is not set */
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset=
- (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
- option_limits, &not_used);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type == OPT_GLOBAL)
- return (uchar*) &(global_system_variables.*offset);
- return (uchar*) &(thd->variables.*offset);
-}
-
-bool sys_var_thd_ulonglong::check(THD *thd, set_var *var)
-{
- return get_unsigned(thd, var, max_system_variables.*offset, GET_ULL);
-}
-
-bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- {
- /* Lock is needed to make things safe on 32 bit systems */
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= (ulonglong)
- var->save_result.ulonglong_value;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= (ulonglong) var->save_result.ulonglong_value;
- return 0;
-}
-
-
-void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- {
- my_bool not_used;
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset=
- getopt_ull_limit_value((ulonglong) option_limits->def_value,
- option_limits, &not_used);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-uchar *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type == OPT_GLOBAL)
- return (uchar*) &(global_system_variables.*offset);
- return (uchar*) &(thd->variables.*offset);
-}
-
-
-bool sys_var_thd_bool::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
- else
- thd->variables.*offset= (my_bool) var->save_result.ulong_value;
- return 0;
-}
-
-
-void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= (my_bool) option_limits->def_value;
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-uchar *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type == OPT_GLOBAL)
- return (uchar*) &(global_system_variables.*offset);
- return (uchar*) &(thd->variables.*offset);
-}
-
-
-bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
-{
- char buff[STRING_BUFFER_USUAL_SIZE];
- const char *value;
- String str(buff, sizeof(buff), system_charset_info), *res;
-
- if (var->value->result_type() == STRING_RESULT)
- {
- if (!(res=var->value->val_str(&str)) ||
- ((long) (var->save_result.ulong_value=
- (ulong) find_type(enum_names, res->ptr(),
- res->length(), FALSE) - 1)) < 0)
- {
- if (res)
- {
- ErrConvString err(res);
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, err.ptr());
- return 1;
- }
- value= "NULL";
- goto err;
- }
- }
- else
- {
- ulonglong tmp=var->value->val_int();
- if (tmp >= enum_names->count)
- {
- llstr(tmp,buff);
- value=buff; // Wrong value is here
- goto err;
- }
- var->save_result.ulong_value= (ulong) tmp; // Save for update
- }
- return 0;
-
-err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
- return 1;
-}
-
-
-bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
-{
- bool not_used;
- char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
- uint error_len= 0;
- String str(buff, sizeof(buff), system_charset_info), *res;
-
- if (var->value->result_type() == STRING_RESULT)
- {
- if (!(res= var->value->val_str(&str)))
- {
- strmov(buff, "NULL");
- goto err;
- }
-
- if (!m_allow_empty_value &&
- res->length() == 0)
- {
- buff[0]= 0;
- goto err;
- }
-
- var->save_result.ulong_value= ((ulong)
- find_set(enum_names, res->c_ptr(),
- res->length(),
- NULL,
- &error, &error_len,
- &not_used));
- if (error_len)
- {
- ErrConvString err(error, error_len, res->charset());
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, err.ptr());
- return 1;
- }
- }
- else
+ if (fixed)
{
- ulonglong tmp= var->value->val_int();
+ char buf[64];
- if (!m_allow_empty_value &&
- tmp == 0)
- {
- buff[0]= '0';
- buff[1]= 0;
- goto err;
- }
+ snprintf(buf, sizeof(buf)-1, "%g", v);
- /*
- For when the enum is made to contain 64 elements, as 1ULL<<64 is
- undefined, we guard with a "count<64" test.
- */
- if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
- (enum_names->count < 64)))
+ if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
{
- llstr(tmp, buff);
- goto err;
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
+ return true;
}
- var->save_result.ulong_value= (ulong) tmp; // Save for update
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
}
- return 0;
-
-err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
- return 1;
+ return false;
}
-
CHARSET_INFO *sys_var::charset(THD *thd)
{
- return is_os_charset ? thd->variables.character_set_filesystem :
+ return is_os_charset ? thd->variables.character_set_filesystem :
system_charset_info;
}
-
-bool sys_var_thd_enum::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.*offset= var->save_result.ulong_value;
- else
- thd->variables.*offset= var->save_result.ulong_value;
- return 0;
-}
-
-
-void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= (ulong) option_limits->def_value;
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- ulong tmp= ((type == OPT_GLOBAL) ?
- global_system_variables.*offset :
- thd->variables.*offset);
- return (uchar*) enum_names->type_names[tmp];
-}
-
-bool sys_var_thd_bit::check(THD *thd, set_var *var)
-{
- return (check_enum(thd, var, &bool_typelib) ||
- (check_func && (*check_func)(thd, var)));
-}
-
-bool sys_var_thd_bit::update(THD *thd, set_var *var)
-{
- int res= (*update_func)(thd, var);
- return res;
-}
-
-
-uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- /*
- If reverse is 0 (default) return 1 if bit is set.
- If reverse is 1, return 0 if bit is set
- */
- thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
- !reverse : reverse);
- return (uchar*) &thd->sys_var_tmp.my_bool_value;
-}
-
-
-/** Update a date_time format variable based on given value. */
-
-void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
- DATE_TIME_FORMAT *new_value)
-{
- DATE_TIME_FORMAT *old;
- DBUG_ENTER("sys_var_date_time_format::update2");
- DBUG_DUMP("positions", (uchar*) new_value->positions,
- sizeof(new_value->positions));
-
- if (type == OPT_GLOBAL)
- {
- pthread_mutex_lock(&LOCK_global_system_variables);
- old= (global_system_variables.*offset);
- (global_system_variables.*offset)= new_value;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- {
- old= (thd->variables.*offset);
- (thd->variables.*offset)= new_value;
- }
- my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR));
- DBUG_VOID_RETURN;
-}
-
-
-bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
-{
- DATE_TIME_FORMAT *new_value;
- /* We must make a copy of the last value to get it into normal memory */
- new_value= date_time_format_copy((THD*) 0,
- var->save_result.date_time_format);
- if (!new_value)
- return 1; // Out of memory
- update2(thd, var->type, new_value); // Can't fail
- return 0;
-}
-
-
-bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
-{
- char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
- DATE_TIME_FORMAT *format;
-
- if (!(res=var->value->val_str(&str)))
- res= &my_empty_string;
-
- if (!(format= date_time_format_make(date_time_type,
- res->ptr(), res->length())))
- {
- ErrConvString err(res);
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, err.ptr());
- return 1;
- }
-
- /*
- We must copy result to thread space to not get a memory leak if
- update is aborted
- */
- var->save_result.date_time_format= date_time_format_copy(thd, format);
- my_free((char*) format, MYF(0));
- return var->save_result.date_time_format == 0;
-}
-
-
-void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type)
-{
- DATE_TIME_FORMAT *res= 0;
-
- if (type == OPT_GLOBAL)
- {
- const char *format;
- if ((format= opt_date_time_formats[date_time_type]))
- res= date_time_format_make(date_time_type, format, strlen(format));
- }
- else
- {
- /* Make copy with malloc */
- res= date_time_format_copy((THD *) 0, global_system_variables.*offset);
- }
-
- if (res) // Should always be true
- update2(thd, type, res);
-}
-
-
-uchar *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type == OPT_GLOBAL)
- {
- char *res;
- /*
- We do a copy here just to be sure things will work even if someone
- is modifying the original string while the copy is accessed
- (Can't happen now in SQL SHOW, but this is a good safety for the future)
- */
- res= thd->strmake((global_system_variables.*offset)->format.str,
- (global_system_variables.*offset)->format.length);
- return (uchar*) res;
- }
- return (uchar*) (thd->variables.*offset)->format.str;
-}
-
-
typedef struct old_names_map_st
{
const char *old_name;
const char *new_name;
} my_old_conv;
-static my_old_conv old_conv[]=
-{
- { "cp1251_koi8" , "cp1251" },
- { "cp1250_latin2" , "cp1250" },
- { "kam_latin2" , "keybcs2" },
- { "mac_latin2" , "MacRoman" },
- { "macce_latin2" , "MacCE" },
- { "pc2_latin2" , "pclatin2" },
- { "vga_latin2" , "pclatin1" },
- { "koi8_cp1251" , "koi8r" },
- { "win1251ukr_koi8_ukr" , "win1251ukr" },
- { "koi8_ukr_win1251ukr" , "koi8u" },
- { NULL , NULL }
+static my_old_conv old_conv[]=
+{
+ { "cp1251_koi8" , "cp1251" },
+ { "cp1250_latin2" , "cp1250" },
+ { "kam_latin2" , "keybcs2" },
+ { "mac_latin2" , "MacRoman" },
+ { "macce_latin2" , "MacCE" },
+ { "pc2_latin2" , "pclatin2" },
+ { "vga_latin2" , "pclatin1" },
+ { "koi8_cp1251" , "koi8r" },
+ { "win1251ukr_koi8_ukr" , "win1251ukr" },
+ { "koi8_ukr_win1251ukr" , "koi8u" },
+ { NULL , NULL }
};
CHARSET_INFO *get_old_charset_by_name(const char *name)
{
my_old_conv *conv;
-
+
for (conv= old_conv; conv->old_name; conv++)
{
if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
@@ -2149,1169 +339,6 @@ CHARSET_INFO *get_old_charset_by_name(const char *name)
return NULL;
}
-
-bool sys_var_collation::check(THD *thd, set_var *var)
-{
- CHARSET_INFO *tmp;
- LINT_INIT(tmp);
-
- if (var->value->result_type() == STRING_RESULT)
- {
- char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
- if (!(res=var->value->val_str(&str)))
- {
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
- return 1;
- }
- if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
- {
- ErrConvString err(res);
- my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
- return 1;
- }
- }
- else // INT_RESULT
- {
- if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
- {
- char buf[20];
- int10_to_str((int) var->value->val_int(), buf, -10);
- my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
- return 1;
- }
- }
- var->save_result.charset= tmp; // Save for update
- return 0;
-}
-
-
-bool sys_var_character_set::check(THD *thd, set_var *var)
-{
- CHARSET_INFO *tmp;
- LINT_INIT(tmp);
-
- if (var->value->result_type() == STRING_RESULT)
- {
- char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
- if (!(res=var->value->val_str(&str)))
- {
- if (!nullable)
- {
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
- return 1;
- }
- tmp= NULL;
- }
- else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
- !(tmp=get_old_charset_by_name(res->c_ptr())))
- {
- ErrConvString err(res);
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr());
- return 1;
- }
- }
- else // INT_RESULT
- {
- if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
- {
- char buf[20];
- int10_to_str((int) var->value->val_int(), buf, -10);
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
- return 1;
- }
- }
- var->save_result.charset= tmp; // Save for update
- return 0;
-}
-
-
-bool sys_var_character_set::update(THD *thd, set_var *var)
-{
- ci_ptr(thd,var->type)[0]= var->save_result.charset;
- thd->update_charset();
- return 0;
-}
-
-
-uchar *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- CHARSET_INFO *cs= ci_ptr(thd,type)[0];
- return cs ? (uchar*) cs->csname : (uchar*) NULL;
-}
-
-
-void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= *global_default;
- else
- {
- thd->variables.*offset= global_system_variables.*offset;
- thd->update_charset();
- }
-}
-CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- return &(global_system_variables.*offset);
- else
- return &(thd->variables.*offset);
-}
-
-
-bool sys_var_character_set_client::check(THD *thd, set_var *var)
-{
- if (sys_var_character_set_sv::check(thd, var))
- return 1;
- /* Currently, UCS-2 cannot be used as a client character set */
- if (var->save_result.charset->mbminlen > 1)
- {
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name,
- var->save_result.charset->csname);
- return 1;
- }
- return 0;
-}
-
-
-CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
- enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- return &global_system_variables.collation_database;
- else
- return &thd->variables.collation_database;
-}
-
-
-void sys_var_character_set_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= thd->db_charset;
- thd->update_charset();
- }
-}
-
-
-bool sys_var_collation_sv::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.*offset= var->save_result.charset;
- else
- {
- thd->variables.*offset= var->save_result.charset;
- thd->update_charset();
- }
- return 0;
-}
-
-
-void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= *global_default;
- else
- {
- thd->variables.*offset= global_system_variables.*offset;
- thd->update_charset();
- }
-}
-
-
-uchar *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
- global_system_variables.*offset : thd->variables.*offset);
- return cs ? (uchar*) cs->name : (uchar*) "NULL";
-}
-
-
-LEX_STRING default_key_cache_base= {(char *) "default", 7 };
-
-static KEY_CACHE zero_key_cache;
-
-KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
-{
- safe_mutex_assert_owner(&LOCK_global_system_variables);
- if (!cache_name || ! cache_name->length)
- cache_name= &default_key_cache_base;
- return ((KEY_CACHE*) find_named(&key_caches,
- cache_name->str, cache_name->length, 0));
-}
-
-
-uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- KEY_CACHE *key_cache= get_key_cache(base);
- if (!key_cache)
- key_cache= &zero_key_cache;
- return (uchar*) key_cache + offset ;
-}
-
-
-bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
-{
- ulonglong tmp= var->save_result.ulonglong_value;
- LEX_STRING *base_name= &var->base;
- KEY_CACHE *key_cache;
- bool error= 0;
-
- /* If no basename, assume it's for the key cache named 'default' */
- if (!base_name->length)
- base_name= &default_key_cache_base;
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- key_cache= get_key_cache(base_name);
-
- if (!key_cache)
- {
- /* Key cache didn't exists */
- if (!tmp) // Tried to delete cache
- goto end; // Ok, nothing to do
- if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
- {
- error= 1;
- goto end;
- }
- }
-
- /*
- Abort if some other thread is changing the key cache
- TODO: This should be changed so that we wait until the previous
- assignment is done and then do the new assign
- */
- if (key_cache->in_init)
- goto end;
-
- if (!tmp) // Zero size means delete
- {
- if (key_cache == dflt_key_cache)
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_WARN_CANT_DROP_DEFAULT_KEYCACHE,
- ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE));
- goto end; // Ignore default key cache
- }
-
- if (key_cache->key_cache_inited) // If initied
- {
- /*
- Move tables using this key cache to the default key cache
- and clear the old key cache.
- */
- NAMED_LIST *list;
- key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
- base_name->length, &list);
- key_cache->in_init= 1;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
- pthread_mutex_lock(&LOCK_global_system_variables);
- key_cache->in_init= 0;
- }
- /*
- We don't delete the key cache as some running threads my still be
- in the key cache code with a pointer to the deleted (empty) key cache
- */
- goto end;
- }
-
- bound_unsigned(thd, &tmp, option_limits);
- key_cache->param_buff_size= (ulonglong) tmp;
-
- /* If key cache didn't exist initialize it, else resize it */
- key_cache->in_init= 1;
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
- if (!key_cache->key_cache_inited)
- error= (bool) (ha_init_key_cache("", key_cache));
- else
- error= (bool)(ha_resize_key_cache(key_cache));
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- key_cache->in_init= 0;
-
-end:
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return error;
-}
-
-
-/**
- @todo
- Abort if some other thread is changing the key cache.
- This should be changed so that we wait until the previous
- assignment is done and then do the new assign
-*/
-bool sys_var_key_cache_long::update(THD *thd, set_var *var)
-{
- ulonglong tmp= var->value->val_int();
- LEX_STRING *base_name= &var->base;
- bool error= 0;
-
- if (!base_name->length)
- base_name= &default_key_cache_base;
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- KEY_CACHE *key_cache= get_key_cache(base_name);
-
- if (!key_cache && !(key_cache= create_key_cache(base_name->str,
- base_name->length)))
- {
- error= 1;
- goto end;
- }
-
- /*
- Abort if some other thread is changing the key cache
- TODO: This should be changed so that we wait until the previous
- assignment is done and then do the new assign
- */
- if (key_cache->in_init)
- goto end;
-
- bound_unsigned(thd, &tmp, option_limits);
- *((ulong*) (((char*) key_cache) + offset))= (ulong) tmp;
-
- /*
- Don't create a new key cache if it didn't exist
- (key_caches are created only when the user sets block_size)
- */
- key_cache->in_init= 1;
-
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
- error= (bool) (ha_resize_key_cache(key_cache));
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- key_cache->in_init= 0;
-
-end:
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return error;
-}
-
-
-bool sys_var_log_state::update(THD *thd, set_var *var)
-{
- bool res;
-
- if (this == &sys_var_log)
- WARN_DEPRECATED(thd, 7, 0, "@@log", "'@@general_log'");
- else if (this == &sys_var_log_slow)
- WARN_DEPRECATED(thd, 7, 0, "@@log_slow_queries", "'@@slow_query_log'");
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- if (!var->save_result.ulong_value)
- {
- logger.deactivate_log_handler(thd, log_type);
- res= false;
- }
- else
- res= logger.activate_log_handler(thd, log_type);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return res;
-}
-
-void sys_var_log_state::set_default(THD *thd, enum_var_type type)
-{
- if (this == &sys_var_log)
- WARN_DEPRECATED(thd, 7, 0, "@@log", "'@@general_log'");
- else if (this == &sys_var_log_slow)
- WARN_DEPRECATED(thd, 7, 0, "@@log_slow_queries", "'@@slow_query_log'");
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- logger.deactivate_log_handler(thd, log_type);
- pthread_mutex_unlock(&LOCK_global_system_variables);
-}
-
-
-static int sys_check_log_path(THD *thd, set_var *var)
-{
- char path[FN_REFLEN], buff[FN_REFLEN];
- MY_STAT f_stat;
- String str(buff, sizeof(buff), system_charset_info), *res;
- const char *log_file_str;
- size_t path_length;
-
- if (!(res= var->value->val_str(&str)))
- goto err;
-
- log_file_str= res->c_ptr();
- bzero(&f_stat, sizeof(MY_STAT));
-
- path_length= unpack_filename(path, log_file_str);
-
- if (!path_length)
- {
- /* File name is empty. */
-
- goto err;
- }
-
- if (my_stat(path, &f_stat, MYF(0)))
- {
- /*
- A file system object exists. Check if argument is a file and we have
- 'write' permission.
- */
-
- if (!MY_S_ISREG(f_stat.st_mode) ||
- !(f_stat.st_mode & MY_S_IWRITE))
- goto err;
-
- return 0;
- }
-
- /* Get dirname of the file path. */
- (void) dirname_part(path, log_file_str, &path_length);
-
- /* Dirname is empty if file path is relative. */
- if (!path_length)
- return 0;
-
- /*
- Check if directory exists and we have permission to create file and
- write to file.
- */
- if (my_access(path, (F_OK|W_OK)))
- goto err;
-
- return 0;
-
-err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name,
- res ? log_file_str : "NULL");
- return 1;
-}
-
-
-bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
- set_var *var, const char *log_ext,
- bool log_state, uint log_type)
-{
- MYSQL_QUERY_LOG *file_log;
- char buff[FN_REFLEN];
- char *res= 0, *old_value= 0;
- bool result= 0;
- uint str_length= 0;
-
- if (var)
- {
- String str(buff, sizeof(buff), system_charset_info), *newval;
-
- newval= var->value->val_str(&str);
- old_value= newval->c_ptr_safe();
- str_length= strlen(old_value);
- }
-
-
-
- switch (log_type) {
- case QUERY_LOG_SLOW:
- file_log= logger.get_slow_log_file_handler();
- break;
- case QUERY_LOG_GENERAL:
- file_log= logger.get_log_file_handler();
- break;
- default:
- assert(0); // Impossible
- }
-
- if (!old_value)
- {
- old_value= make_default_log_name(buff, log_ext);
- str_length= strlen(old_value);
- }
- if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
- {
- result= 1;
- goto err;
- }
-
- pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock_exclusive();
-
- if (file_log && log_state)
- file_log->close(0);
- old_value= var_str->value;
- var_str->value= res;
- var_str->value_length= str_length;
- my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
- if (file_log && log_state)
- {
- switch (log_type) {
- case QUERY_LOG_SLOW:
- file_log->open_slow_log(sys_var_slow_log_path.value);
- break;
- case QUERY_LOG_GENERAL:
- file_log->open_query_log(sys_var_general_log_path.value);
- break;
- default:
- DBUG_ASSERT(0);
- }
- }
-
- logger.unlock();
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
-err:
- return result;
-}
-
-
-static bool sys_update_general_log_path(THD *thd, set_var * var)
-{
- return update_sys_var_str_path(thd, &sys_var_general_log_path,
- var, ".log", opt_log, QUERY_LOG_GENERAL);
-}
-
-
-static void sys_default_general_log_path(THD *thd, enum_var_type type)
-{
- (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
- 0, ".log", opt_log, QUERY_LOG_GENERAL);
-}
-
-
-static bool sys_update_slow_log_path(THD *thd, set_var * var)
-{
- return update_sys_var_str_path(thd, &sys_var_slow_log_path,
- var, "-slow.log", opt_slow_log,
- QUERY_LOG_SLOW);
-}
-
-
-static void sys_default_slow_log_path(THD *thd, enum_var_type type)
-{
- (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
- 0, "-slow.log", opt_slow_log,
- QUERY_LOG_SLOW);
-}
-
-
-bool sys_var_log_output::update(THD *thd, set_var *var)
-{
- pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock_exclusive();
- logger.init_slow_log(var->save_result.ulong_value);
- logger.init_general_log(var->save_result.ulong_value);
- *value= var->save_result.ulong_value;
- logger.unlock();
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return 0;
-}
-
-
-void sys_var_log_output::set_default(THD *thd, enum_var_type type)
-{
- pthread_mutex_lock(&LOCK_global_system_variables);
- logger.lock_exclusive();
- logger.init_slow_log(LOG_FILE);
- logger.init_general_log(LOG_FILE);
- *value= LOG_FILE;
- logger.unlock();
- pthread_mutex_unlock(&LOCK_global_system_variables);
-}
-
-
-uchar *sys_var_log_output::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- char buff[256];
- String tmp(buff, sizeof(buff), &my_charset_latin1);
- ulong length;
- ulong val= *value;
-
- tmp.length(0);
- for (uint i= 0; val; val>>= 1, i++)
- {
- if (val & 1)
- {
- tmp.append(log_output_typelib.type_names[i],
- log_output_typelib.type_lengths[i]);
- tmp.append(',');
- }
- }
-
- if ((length= tmp.length()))
- length--;
- return (uchar*) thd->strmake(tmp.ptr(), length);
-}
-
-
-/*****************************************************************************
- Functions to handle SET NAMES and SET CHARACTER SET
-*****************************************************************************/
-
-int set_var_collation_client::check(THD *thd)
-{
- /* Currently, UCS-2 cannot be used as a client character set */
- if (character_set_client->mbminlen > 1)
- {
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
- character_set_client->csname);
- return 1;
- }
- return 0;
-}
-
-int set_var_collation_client::update(THD *thd)
-{
- thd->variables.character_set_client= character_set_client;
- thd->variables.character_set_results= character_set_results;
- thd->variables.collation_connection= collation_connection;
- thd->update_charset();
- thd->protocol_text.init(thd);
- thd->protocol_binary.init(thd);
- return 0;
-}
-
-/****************************************************************************/
-
-bool sys_var_timestamp::update(THD *thd, set_var *var)
-{
- thd->set_time((time_t) var->save_result.ulonglong_value);
- return 0;
-}
-
-
-void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
-{
- thd->user_time=0;
-}
-
-
-uchar *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- thd->sys_var_tmp.long_value= (long) thd->start_time;
- return (uchar*) &thd->sys_var_tmp.long_value;
-}
-
-
-bool sys_var_last_insert_id::update(THD *thd, set_var *var)
-{
- thd->first_successful_insert_id_in_prev_stmt=
- var->save_result.ulonglong_value;
- return 0;
-}
-
-
-uchar *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- /*
- this tmp var makes it robust againt change of type of
- read_first_successful_insert_id_in_prev_stmt().
- */
- thd->sys_var_tmp.ulonglong_value=
- thd->read_first_successful_insert_id_in_prev_stmt();
- return (uchar*) &thd->sys_var_tmp.ulonglong_value;
-}
-
-
-bool sys_var_insert_id::update(THD *thd, set_var *var)
-{
- thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
- return 0;
-}
-
-
-uchar *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- thd->sys_var_tmp.ulonglong_value=
- thd->auto_inc_intervals_forced.minimum();
- return (uchar*) &thd->sys_var_tmp.ulonglong_value;
-}
-
-
-bool sys_var_rand_seed1::update(THD *thd, set_var *var)
-{
- thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
- return 0;
-}
-
-bool sys_var_rand_seed2::update(THD *thd, set_var *var)
-{
- thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
- return 0;
-}
-
-
-bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
-{
- char buff[MAX_TIME_ZONE_NAME_LENGTH];
- String str(buff, sizeof(buff), &my_charset_latin1);
- String *res= var->value->val_str(&str);
-
- if (!(var->save_result.time_zone= my_tz_find(thd, res)))
- {
- my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
- return 1;
- }
- return 0;
-}
-
-
-bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
-{
- /* We are using Time_zone object found during check() phase. */
- if (var->type == OPT_GLOBAL)
- {
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.time_zone= var->save_result.time_zone;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.time_zone= var->save_result.time_zone;
- return 0;
-}
-
-
-uchar *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- /*
- We can use ptr() instead of c_ptr() here because String contaning
- time zone name is guaranteed to be zero ended.
- */
- if (type == OPT_GLOBAL)
- return (uchar *)(global_system_variables.time_zone->get_name()->ptr());
- else
- {
- /*
- This is an ugly fix for replication: we don't replicate properly queries
- invoking system variables' values to update tables; but
- CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
- replicable (i.e. we tell the binlog code to store the session
- timezone). If it's the global value which was used we can't replicate
- (binlog code stores session value only).
- */
- thd->time_zone_used= 1;
- return (uchar *)(thd->variables.time_zone->get_name()->ptr());
- }
-}
-
-
-void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
-{
- pthread_mutex_lock(&LOCK_global_system_variables);
- if (type == OPT_GLOBAL)
- {
- if (default_tz_name)
- {
- String str(default_tz_name, &my_charset_latin1);
- /*
- We are guaranteed to find this time zone since its existence
- is checked during start-up.
- */
- global_system_variables.time_zone= my_tz_find(thd, &str);
- }
- else
- global_system_variables.time_zone= my_tz_SYSTEM;
- }
- else
- thd->variables.time_zone= global_system_variables.time_zone;
- pthread_mutex_unlock(&LOCK_global_system_variables);
-}
-
-
-bool sys_var_max_user_conn::check(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- return sys_var_thd::check(thd, var);
- else
- {
- /*
- Per-session values of max_user_connections can't be set directly.
- May be we should have a separate error message for this?
- */
- my_error(ER_GLOBAL_VARIABLE, MYF(0), name);
- return TRUE;
- }
-}
-
-bool sys_var_max_user_conn::update(THD *thd, set_var *var)
-{
- DBUG_ASSERT(var->type == OPT_GLOBAL);
- pthread_mutex_lock(&LOCK_global_system_variables);
- max_user_connections= (uint)var->save_result.ulonglong_value;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return 0;
-}
-
-
-void sys_var_max_user_conn::set_default(THD *thd, enum_var_type type)
-{
- DBUG_ASSERT(type == OPT_GLOBAL);
- pthread_mutex_lock(&LOCK_global_system_variables);
- max_user_connections= (ulong) option_limits->def_value;
- pthread_mutex_unlock(&LOCK_global_system_variables);
-}
-
-
-uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- if (type != OPT_GLOBAL &&
- thd->user_connect && thd->user_connect->user_resources.user_conn)
- return (uchar*) &(thd->user_connect->user_resources.user_conn);
- return (uchar*) &(max_user_connections);
-}
-
-
-bool sys_var_thd_ulong_session_readonly::check(THD *thd, set_var *var)
-{
- if (var->type != OPT_GLOBAL)
- {
- my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION", name, "GLOBAL");
- return TRUE;
- }
-
- return sys_var_thd_ulong::check(thd, var);
-}
-
-
-static MY_LOCALE *check_locale(THD *thd, const char *name, set_var *var)
-{
- MY_LOCALE *locale_match;
-
- if (var->value->result_type() == INT_RESULT)
- {
- if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
- {
- char buf[20];
- int10_to_str((int) var->value->val_int(), buf, -10);
- my_printf_error(ER_UNKNOWN_LOCALE, ER(ER_UNKNOWN_LOCALE), MYF(0), buf);
- return 0;
- }
- }
- else // STRING_RESULT
- {
- char buff[6];
- String str(buff, sizeof(buff), system_charset_info), *res;
- if (!(res=var->value->val_str(&str)))
- {
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
- return 0;
- }
- const char *locale_str= res->c_ptr();
- if (!(locale_match= my_locale_by_name(locale_str)))
- {
- my_printf_error(ER_UNKNOWN_LOCALE, ER(ER_UNKNOWN_LOCALE),
- MYF(0), locale_str);
- return 0;
- }
- }
-
- return var->save_result.locale_value= locale_match;
-}
-
-
-bool sys_var_thd_lc::check(THD *thd, set_var *var)
-{
- MY_LOCALE *locale_match;
-
- if (!(locale_match= check_locale(thd, name, var)))
- return 1;
- return 0;
-}
-
-
-bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
-{
- if (var->type == OPT_GLOBAL)
- global_system_variables.lc_time_names= var->save_result.locale_value;
- else
- thd->variables.lc_time_names= var->save_result.locale_value;
- return 0;
-}
-
-
-uchar *sys_var_thd_lc_time_names::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- return type == OPT_GLOBAL ?
- (uchar *) global_system_variables.lc_time_names->name :
- (uchar *) thd->variables.lc_time_names->name;
-}
-
-
-void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.lc_time_names= my_default_lc_time_names;
- else
- thd->variables.lc_time_names= global_system_variables.lc_time_names;
-}
-
-
-bool sys_var_thd_lc_messages::update(THD *thd, set_var *var)
-{
- MY_LOCALE *locale= var->save_result.locale_value;
-
- if (!locale->errmsgs->errmsgs)
- {
- pthread_mutex_lock(&LOCK_error_messages);
- if (!locale->errmsgs->errmsgs &&
- read_texts(ERRMSG_FILE, locale->errmsgs->language,
- &locale->errmsgs->errmsgs,
- ER_ERROR_LAST - ER_ERROR_FIRST + 1))
- {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_UNKNOWN_ERROR,
- "Can't process error message file for locale '%s'",
- locale->name);
- pthread_mutex_unlock(&LOCK_error_messages);
- return 0;
- }
- pthread_mutex_unlock(&LOCK_error_messages);
- }
-
- if (var->type == OPT_GLOBAL)
- global_system_variables.lc_messages= locale;
- else
- thd->variables.lc_messages= locale;
-
- return 0;
-}
-
-
-uchar *sys_var_thd_lc_messages::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- return type == OPT_GLOBAL ?
- (uchar *) global_system_variables.lc_messages->name :
- (uchar *) thd->variables.lc_messages->name;
-}
-
-
-void sys_var_thd_lc_messages::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.lc_messages= my_default_lc_messages;
- else
- thd->variables.lc_messages= global_system_variables.lc_messages;
-}
-
-
-/*
- Handling of microseoncds given as seconds.part_seconds
-
- NOTES
- The argument to long query time is in seconds in decimal
- which is converted to ulonglong integer holding microseconds for storage.
- This is used for handling long_query_time
-*/
-
-bool sys_var_microseconds::update(THD *thd, set_var *var)
-{
- double num= var->value->val_real();
- longlong microseconds;
- if (num > (double) option_limits->max_value)
- num= (double) option_limits->max_value;
- if (num < (double) option_limits->min_value)
- num= (double) option_limits->min_value;
- microseconds= (longlong) (num * 1000000.0 + 0.5);
- if (var->type == OPT_GLOBAL)
- {
- pthread_mutex_lock(&LOCK_global_system_variables);
- (global_system_variables.*offset)= microseconds;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= microseconds;
- return 0;
-}
-
-
-void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
-{
- longlong microseconds= (longlong) (option_limits->def_value * 1000000.0);
- if (type == OPT_GLOBAL)
- {
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.*offset= microseconds;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.*offset= microseconds;
-}
-
-
-uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
- global_system_variables.*offset :
- thd->variables.*offset) / 1000000.0;
- return (uchar*) &thd->tmp_double_value;
-}
-
-
-/*
- Functions to update thd->options bits
-*/
-
-static bool set_option_bit(THD *thd, set_var *var)
-{
- sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
- if ((var->save_result.ulong_value != 0) == sys_var->reverse)
- thd->options&= ~sys_var->bit_flag;
- else
- thd->options|= sys_var->bit_flag;
- return 0;
-}
-
-/*
- Functions to be only used to update thd->options OPTION_BIN_LOG bit
-*/
-static bool set_option_log_bin_bit(THD *thd, set_var *var)
-{
- set_option_bit(thd, var);
- if (!thd->in_sub_stmt)
- thd->sql_log_bin_toplevel= thd->options & OPTION_BIN_LOG;
- return 0;
-}
-
-static bool set_option_autocommit(THD *thd, set_var *var)
-{
- /* The test is negative as the flag we use is NOT autocommit */
-
- ulonglong org_options= thd->options;
-
- /*
- If we are setting AUTOCOMMIT=1 and it was not already 1, then we
- need to commit any outstanding transactions.
- */
- if (var->save_result.ulong_value != 0 &&
- (thd->options & OPTION_NOT_AUTOCOMMIT) &&
- ha_commit(thd))
- return 1;
-
- if (var->save_result.ulong_value != 0)
- thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
- else
- thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
-
- if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
- {
- if ((org_options & OPTION_NOT_AUTOCOMMIT))
- {
- /* We changed to auto_commit mode */
- thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
- thd->transaction.all.modified_non_trans_table= FALSE;
- thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- }
- else
- {
- thd->transaction.all.modified_non_trans_table= FALSE;
- thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
- }
- }
- return 0;
-}
-
-static int check_log_update(THD *thd, set_var *var)
-{
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (!(thd->security_ctx->master_access & SUPER_ACL))
- {
- my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
- return 1;
- }
-#endif
- return 0;
-}
-
-static bool set_log_update(THD *thd, set_var *var)
-{
- /*
- The update log is not supported anymore since 5.0.
- See sql/mysqld.cc/, comments in function init_server_components() for an
- explaination of the different warnings we send below
- */
-
- if (opt_sql_bin_update)
- {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
- ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
- }
- else
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_UPDATE_LOG_DEPRECATED_IGNORED,
- ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
- set_option_bit(thd, var);
- return 0;
-}
-
-
-static int check_pseudo_thread_id(THD *thd, set_var *var)
-{
- var->save_result.ulonglong_value= var->value->val_int();
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (thd->security_ctx->master_access & SUPER_ACL)
- return 0;
- else
- {
- my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
- return 1;
- }
-#else
- return 0;
-#endif
-}
-
-static uchar *get_warning_count(THD *thd)
-{
- thd->sys_var_tmp.long_value= thd->warning_info->warn_count();
- return (uchar*) &thd->sys_var_tmp.long_value;
-}
-
-static uchar *get_error_count(THD *thd)
-{
- thd->sys_var_tmp.long_value= thd->warning_info->error_count();
- return (uchar*) &thd->sys_var_tmp.long_value;
-}
-
-
-/**
- Get the tmpdir that was specified or chosen by default.
-
- This is necessary because if the user does not specify a temporary
- directory via the command line, one is chosen based on the environment
- or system defaults. But we can't just always use mysql_tmpdir, because
- that is actually a call to my_tmpdir() which cycles among possible
- temporary directories.
-
- @param thd thread handle
-
- @retval
- ptr pointer to NUL-terminated string
-*/
-static uchar *get_tmpdir(THD *thd)
-{
- if (opt_mysql_tmpdir)
- return (uchar *)opt_mysql_tmpdir;
- return (uchar*)mysql_tmpdir;
-}
-
-static uchar *get_myisam_mmap_size(THD *thd)
-{
- return (uchar *)&myisam_mmap_size;
-}
-
-
/****************************************************************************
Main handling of variables:
- Initialisation
@@ -3320,77 +347,31 @@ static uchar *get_myisam_mmap_size(THD *thd)
****************************************************************************/
/**
- Find variable name in option my_getopt structure used for
- command line args.
+ Add variables to the dynamic hash of system variables
- @param opt option structure array to search in
- @param name variable name
+ @param first Pointer to first system variable to add
@retval
- 0 Error
- @retval
- ptr pointer to option structure
-*/
-
-static struct my_option *find_option(struct my_option *opt, const char *name)
-{
- uint length=strlen(name);
- for (; opt->name; opt++)
- {
- if (!getopt_compare_strings(opt->name, name, length) &&
- !opt->name[length])
- {
- /*
- Only accept the option if one can set values through it.
- If not, there is no default value or limits in the option.
- */
- return (opt->value) ? opt : 0;
- }
- }
- return 0;
-}
-
-
-/**
- Return variable name and length for hashing of variables.
-*/
-
-static uchar *get_sys_var_length(const sys_var *var, size_t *length,
- my_bool first)
-{
- *length= var->name_length;
- return (uchar*) var->name;
-}
-
-
-/*
- 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
+ @retval
otherwise FAILURE
*/
-int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
+int mysql_add_sys_var_chain(sys_var *first)
{
sys_var *var;
-
+
/* A write lock should be held on LOCK_system_variables_hash */
-
+
for (var= first; var; var= var->next)
{
- var->name_length= strlen(var->name);
/* this fails if there is a conflicting variable name. see HASH_UNIQUE */
if (my_hash_insert(&system_variable_hash, (uchar*) var))
+ {
+ fprintf(stderr, "*** duplicate variable name '%s' ?\n", var->name.str);
goto error;
- if (long_options)
- var->option_limits= find_option(long_options, var->name);
+ }
}
return 0;
@@ -3399,53 +380,53 @@ error:
my_hash_delete(&system_variable_hash, (uchar*) 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|= my_hash_delete(&system_variable_hash, (uchar*) 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
+
+ @param thd current thread
+ @param sorted If TRUE, the system variables should be sorted
+ @param type OPT_GLOBAL or OPT_SESSION for SHOW GLOBAL|SESSION VARIABLES
+
+ @retval
pointer Array of SHOW_VAR elements for display
+ @retval
NULL FAILURE
*/
-SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
+SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted, enum enum_var_type type)
{
int count= system_variable_hash.records, i;
int size= sizeof(SHOW_VAR) * (count + 1);
@@ -3458,7 +439,12 @@ SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
for (i= 0; i < count; i++)
{
sys_var *var= (sys_var*) my_hash_element(&system_variable_hash, i);
- show->name= var->name;
+
+ // don't show session-only variables in SHOW GLOBAL VARIABLES
+ if (type == OPT_GLOBAL && var->check_type(type))
+ continue;
+
+ show->name= var->name.str;
show->value= (char*) var;
show->type= SHOW_SYS;
show++;
@@ -3466,79 +452,29 @@ SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
/* sort into order */
if (sorted)
- my_qsort(result, count, sizeof(SHOW_VAR),
+ my_qsort(result, show-result, 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_hash_init(&system_variable_hash, system_charset_info, count, 0,
- 0, (my_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
- a different name than the command line option.
- 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()
-{
- my_hash_free(&system_variable_hash);
-}
-
-
/**
Find a user set-table variable.
- @param str Name of system variable to find
+ @param str Name of system variable to find
@param length Length of variable. zero means that we should use strlen()
on the variable
- @param no_error Refuse to emit an error, even if one occurred.
@retval
- pointer pointer to variable definitions
+ pointer pointer to variable definitions
@retval
- 0 Unknown variable (error message is given)
+ 0 Unknown variable (error message is given)
*/
-sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
+sys_var *intern_find_sys_var(const char *str, uint length)
{
sys_var *var;
@@ -3547,10 +483,7 @@ sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
A lock on LOCK_system_variable_hash should be held
*/
var= (sys_var*) my_hash_search(&system_variable_hash,
- (uchar*) str, length ? length : strlen(str));
- if (!(var || no_error))
- my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
-
+ (uchar*) str, length ? length : strlen(str));
return var;
}
@@ -3564,13 +497,13 @@ sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
This should ensure that in all normal cases none all or variables are
updated.
- @param THD Thread id
+ @param THD Thread id
@param var_list List of variables to update
@retval
- 0 ok
+ 0 ok
@retval
- 1 ERROR, message sent (normally no variables was updated)
+ 1 ERROR, message sent (normally no variables was updated)
@retval
-1 ERROR, message not sent
*/
@@ -3599,36 +532,6 @@ err:
DBUG_RETURN(error);
}
-
-/**
- Say if all variables set by a SET support the ONE_SHOT keyword
- (currently, only character set and collation do; later timezones
- will).
-
- @param var_list List of variables to update
-
- @note
- It has a "not_" because it makes faster tests (no need to "!")
-
- @retval
- 0 all variables of the list support ONE_SHOT
- @retval
- 1 at least one does not support ONE_SHOT
-*/
-
-bool not_all_support_one_shot(List<set_var_base> *var_list)
-{
- List_iterator_fast<set_var_base> it(*var_list);
- set_var_base *var;
- while ((var= it++))
- {
- if (var->no_support_one_shot())
- return 1;
- }
- return 0;
-}
-
-
/*****************************************************************************
Functions to handle SET mysql_internal_variable=const_expr
*****************************************************************************/
@@ -3639,42 +542,35 @@ bool not_all_support_one_shot(List<set_var_base> *var_list)
@param thd Thread handler
@return status code
- @retval -1 Failure
- @retval 0 Success
-*/
+ @retval -1 Failure
+ @retval 0 Success
+ */
int set_var::check(THD *thd)
{
if (var->is_readonly())
{
- my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
+ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name.str, "read only");
return -1;
}
if (var->check_type(type))
{
int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
- my_error(err, MYF(0), var->name);
+ my_error(err, MYF(0), var->name.str);
return -1;
}
if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
return 1;
/* value is a NULL pointer if we are using SET ... = DEFAULT */
if (!value)
- {
- if (var->check_default(type))
- {
- my_error(ER_NO_DEFAULT, MYF(0), var->name);
- return -1;
- }
return 0;
- }
if ((!value->fixed &&
value->fix_fields(thd, &value)) || value->check_cols(1))
return -1;
if (var->check_update_type(value->result_type()))
{
- my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
+ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name.str);
return -1;
}
return var->check(thd, this) ? -1 : 0;
@@ -3684,12 +580,12 @@ int set_var::check(THD *thd)
/**
Check variable, but without assigning value (used by PS).
- @param thd thread handler
+ @param thd thread handler
@retval
- 0 ok
+ 0 ok
@retval
- 1 ERROR, message sent (normally no variables was updated)
+ 1 ERROR, message sent (normally no variables was updated)
@retval
-1 ERROR, message not sent
*/
@@ -3714,7 +610,7 @@ int set_var::light_check(THD *thd)
Update variable
@param thd thread handler
- @returns 0|1 ok or ERROR
+ @returns 0|1 ok or ERROR
@note ERROR can be only due to abnormal operations involving
the server's execution evironment such as
@@ -3724,13 +620,7 @@ int set_var::light_check(THD *thd)
*/
int set_var::update(THD *thd)
{
- if (!value)
- var->set_default(thd, type);
- else if (var->update(thd, this))
- return -1; // should never happen
- if (var->after_update)
- (*var->after_update)(thd, type);
- return 0;
+ return value ? var->update(thd, this) : var->set_default(thd, type);
}
@@ -3745,19 +635,19 @@ int set_var_user::check(THD *thd)
0 can be passed as last argument (reference on item)
*/
return (user_var_item->fix_fields(thd, (Item**) 0) ||
- user_var_item->check(0)) ? -1 : 0;
+ user_var_item->check(0)) ? -1 : 0;
}
/**
Check variable, but without assigning value (used by PS).
- @param thd thread handler
+ @param thd thread handler
@retval
- 0 ok
+ 0 ok
@retval
- 1 ERROR, message sent (normally no variables was updated)
+ 1 ERROR, message sent (normally no variables was updated)
@retval
-1 ERROR, message not sent
*/
@@ -3823,583 +713,36 @@ int set_var_password::update(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Returns 1 as the function sends error to client */
return change_password(thd, user->host.str, user->user.str, password) ?
- 1 : 0;
+ 1 : 0;
#else
return 0;
#endif
}
-/****************************************************************************
- Functions to handle table_type
-****************************************************************************/
-
-/* Based upon sys_var::check_enum() */
-
-bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
-{
- char buff[STRING_BUFFER_USUAL_SIZE];
- 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 engine_name;
- handlerton *hton;
- if (!(res=var->value->val_str(&str)) ||
- !(engine_name.str= (char *)res->ptr()) ||
- !(engine_name.length= res->length()) ||
- !(var->save_result.plugin= ha_resolve_by_name(thd, &engine_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;
- }
- return 0;
- }
- value= "unknown";
-
-err:
- my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
- return 1;
-}
-
-
-uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- uchar* result;
- handlerton *hton;
- LEX_STRING *engine_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*);
- engine_name= &hton2plugin[hton->slot]->name;
- result= (uchar *) thd->strmake(engine_name->str, engine_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)
- {
- value= &(global_system_variables.*offset);
- new_value= ha_lock_engine(NULL, myisam_hton);
- }
- else
- {
- 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)
-{
- 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;
-}
-
-/****************************************************************************
- Functions to handle sql_mode
-****************************************************************************/
-
-/**
- Make string representation of mode.
-
- @param[in] thd thread handler
- @param[in] val sql_mode value
- @param[out] len pointer on length of string
-
- @return
- pointer to string with sql_mode representation
-*/
-
-bool
-sys_var_thd_sql_mode::
-symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-{
- char buff[STRING_BUFFER_USUAL_SIZE*8];
- String tmp(buff, sizeof(buff), &my_charset_latin1);
-
- tmp.length(0);
-
- for (uint i= 0; val; val>>= 1, i++)
- {
- if (val & 1)
- {
- tmp.append(sql_mode_typelib.type_names[i],
- sql_mode_typelib.type_lengths[i]);
- tmp.append(',');
- }
- }
-
- if (tmp.length())
- tmp.length(tmp.length() - 1); /* trim the trailing comma */
-
- rep->str= thd->strmake(tmp.ptr(), tmp.length());
-
- rep->length= rep->str ? tmp.length() : 0;
-
- return rep->length != tmp.length();
-}
-
-
-uchar *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- LEX_STRING sql_mode;
- ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
- thd->variables.*offset);
- (void) symbolic_mode_representation(thd, val, &sql_mode);
- return (uchar *) sql_mode.str;
-}
-
-
-void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= 0;
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
-void fix_sql_mode_var(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.sql_mode=
- fix_sql_mode(global_system_variables.sql_mode);
- else
- {
- thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
- /*
- Update thd->server_status
- */
- if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
- thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
- else
- thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
- }
-}
-
-/** Map database specific bits to function bits. */
-
-ulong fix_sql_mode(ulong sql_mode)
-{
- /*
- Note that we dont set
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
- to allow one to get full use of MySQL in this mode.
- */
-
- if (sql_mode & MODE_ANSI)
- {
- sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE);
- /*
- MODE_ONLY_FULL_GROUP_BY removed from ANSI mode because it is currently
- overly restrictive (see BUG#8510).
- */
- }
- if (sql_mode & MODE_ORACLE)
- sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE |
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
- if (sql_mode & MODE_MSSQL)
- sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE |
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS);
- if (sql_mode & MODE_POSTGRESQL)
- sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE |
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS);
- if (sql_mode & MODE_DB2)
- sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE |
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS);
- if (sql_mode & MODE_MAXDB)
- sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
- MODE_IGNORE_SPACE |
- MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
- MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
- if (sql_mode & MODE_MYSQL40)
- sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
- if (sql_mode & MODE_MYSQL323)
- sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
- if (sql_mode & MODE_TRADITIONAL)
- sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
- MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
- MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER |
- MODE_NO_ENGINE_SUBSTITUTION);
- return sql_mode;
-}
-
-
-bool
-sys_var_thd_optimizer_switch::
-symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-{
- char buff[STRING_BUFFER_USUAL_SIZE*8];
- String tmp(buff, sizeof(buff), &my_charset_latin1);
- int i;
- ulonglong bit;
- tmp.length(0);
-
- for (i= 0, bit=1; bit != OPTIMIZER_SWITCH_LAST; i++, bit= bit << 1)
- {
- tmp.append(optimizer_switch_typelib.type_names[i],
- optimizer_switch_typelib.type_lengths[i]);
- tmp.append('=');
- tmp.append((val & bit)? "on":"off");
- tmp.append(',');
- }
-
- if (tmp.length())
- tmp.length(tmp.length() - 1); /* trim the trailing comma */
-
- rep->str= thd->strmake(tmp.ptr(), tmp.length());
-
- rep->length= rep->str ? tmp.length() : 0;
-
- return rep->length != tmp.length();
-}
-
-
-uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- LEX_STRING opts;
- ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
- thd->variables.*offset);
- (void) symbolic_mode_representation(thd, val, &opts);
- return (uchar *) opts.str;
-}
-
-
-/*
- Check (and actually parse) string representation of @@optimizer_switch.
-*/
-
-bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
-{
- bool not_used;
- char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
- uint error_len= 0;
- String str(buff, sizeof(buff), system_charset_info), *res;
-
- if (!(res= var->value->val_str(&str)))
- {
- strmov(buff, "NULL");
- goto err;
- }
-
- if (res->length() == 0)
- {
- buff[0]= 0;
- goto err;
- }
-
- var->save_result.ulong_value=
- (ulong)find_set_from_flags(&optimizer_switch_typelib,
- optimizer_switch_typelib.count,
- thd->variables.optimizer_switch,
- global_system_variables.optimizer_switch,
- res->c_ptr_safe(), res->length(), NULL,
- &error, &error_len, &not_used);
- if (error_len)
- {
- ErrConvString err(error, error_len, res->charset());
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, err.ptr());
- return TRUE;
- }
- return FALSE;
-err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
- return TRUE;
-}
-
-
-void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= OPTIMIZER_SWITCH_DEFAULT;
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-/****************************************************************************
- Named list handling
-****************************************************************************/
-
-uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
- NAMED_LIST **found)
-{
- I_List_iterator<NAMED_LIST> it(*list);
- NAMED_LIST *element;
- while ((element= it++))
- {
- if (element->cmp(name, length))
- {
- if (found)
- *found= element;
- return element->data;
- }
- }
- return 0;
-}
-
-
-void delete_elements(I_List<NAMED_LIST> *list,
- void (*free_element)(const char *name, uchar*))
-{
- NAMED_LIST *element;
- DBUG_ENTER("delete_elements");
- while ((element= list->get()))
- {
- (*free_element)(element->name, element->data);
- delete element;
- }
- DBUG_VOID_RETURN;
-}
-
-
-/* Key cache functions */
-
-static KEY_CACHE *create_key_cache(const char *name, uint length)
-{
- KEY_CACHE *key_cache;
- DBUG_ENTER("create_key_cache");
- DBUG_PRINT("enter",("name: %.*s", length, name));
-
- if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
- MYF(MY_ZEROFILL | MY_WME))))
- {
- if (!new NAMED_LIST(&key_caches, name, length, (uchar*) key_cache))
- {
- my_free((char*) key_cache, MYF(0));
- key_cache= 0;
- }
- else
- {
- /*
- Set default values for a key cache
- The values in dflt_key_cache_var is set by my_getopt() at startup
-
- We don't set 'buff_size' as this is used to enable the key cache
- */
- key_cache->param_block_size= dflt_key_cache_var.param_block_size;
- key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
- key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold;
- }
- }
- DBUG_RETURN(key_cache);
-}
-
-
-KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
-{
- LEX_STRING key_cache_name;
- KEY_CACHE *key_cache;
-
- key_cache_name.str= (char *) name;
- key_cache_name.length= length;
- pthread_mutex_lock(&LOCK_global_system_variables);
- if (!(key_cache= get_key_cache(&key_cache_name)))
- key_cache= create_key_cache(name, length);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- return key_cache;
-}
-
-
-void free_key_cache(const char *name, KEY_CACHE *key_cache)
-{
- ha_end_key_cache(key_cache);
- my_free((char*) key_cache, MYF(0));
-}
-
+/*****************************************************************************
+ Functions to handle SET NAMES and SET CHARACTER SET
+*****************************************************************************/
-bool process_key_caches(process_key_cache_t func)
+int set_var_collation_client::check(THD *thd)
{
- I_List_iterator<NAMED_LIST> it(key_caches);
- NAMED_LIST *element;
-
- while ((element= it++))
+ /* Currently, UCS-2 cannot be used as a client character set */
+ if (character_set_client->mbminlen > 1)
{
- KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
- func(element->name, key_cache);
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
+ character_set_client->csname);
+ return 1;
}
return 0;
}
-bool sys_var_opt_readonly::update(THD *thd, set_var *var)
-{
- bool result;
-
- DBUG_ENTER("sys_var_opt_readonly::update");
-
- /* Prevent self dead-lock */
- if (thd->locked_tables || thd->active_transaction())
- {
- my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
- DBUG_RETURN(true);
- }
-
- if (thd->global_read_lock)
- {
- /*
- This connection already holds the global read lock.
- This can be the case with:
- - FLUSH TABLES WITH READ LOCK
- - SET GLOBAL READ_ONLY = 1
- */
- result= sys_var_bool_ptr::update(thd, var);
- DBUG_RETURN(result);
- }
-
- /*
- Perform a 'FLUSH TABLES WITH READ LOCK'.
- This is a 3 step process:
- - [1] lock_global_read_lock()
- - [2] close_cached_tables()
- - [3] make_global_read_lock_block_commit()
- [1] prevents new connections from obtaining tables locked for write.
- [2] waits until all existing connections close their tables.
- [3] prevents transactions from being committed.
- */
-
- if (lock_global_read_lock(thd))
- DBUG_RETURN(true);
-
- /*
- This call will be blocked by any connection holding a READ or WRITE lock.
- Ideally, we want to wait only for pending WRITE locks, but since:
- con 1> LOCK TABLE T FOR READ;
- con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
- con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
- can cause to wait on a read lock, it's required for the client application
- to unlock everything, and acceptable for the server to wait on all locks.
- */
- if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)))
- goto end_with_read_lock;
-
- if ((result= make_global_read_lock_block_commit(thd)))
- goto end_with_read_lock;
-
- /* Change the opt_readonly system variable, safe because the lock is held */
- result= sys_var_bool_ptr::update(thd, var);
-
-end_with_read_lock:
- /* Release the lock */
- unlock_global_read_lock(thd);
- DBUG_RETURN(result);
-}
-
-
-#ifndef DBUG_OFF
-/* even session variable here requires SUPER, because of -#o,file */
-bool sys_var_thd_dbug::check(THD *thd, set_var *var)
-{
- return check_global_access(thd, SUPER_ACL);
-}
-
-bool sys_var_thd_dbug::update(THD *thd, set_var *var)
+int set_var_collation_client::update(THD *thd)
{
- if (var->type == OPT_GLOBAL)
- DBUG_SET_INITIAL(var ? var->value->str_value.c_ptr() : "");
- else
- DBUG_SET(var ? var->value->str_value.c_ptr() : "");
-
+ thd->variables.character_set_client= character_set_client;
+ thd->variables.character_set_results= character_set_results;
+ thd->variables.collation_connection= collation_connection;
+ thd->update_charset();
+ thd->protocol_text.init(thd);
+ thd->protocol_binary.init(thd);
return 0;
}
-
-uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
-{
- char buf[256];
- if (type == OPT_GLOBAL)
- DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
- else
- DBUG_EXPLAIN(buf, sizeof(buf));
- return (uchar*) thd->strdup(buf);
-}
-#endif /* DBUG_OFF */
-
-
-#ifdef HAVE_EVENT_SCHEDULER
-bool sys_var_event_scheduler::check(THD *thd, set_var *var)
-{
- return check_enum(thd, var, &Events::var_typelib);
-}
-
-/*
- The update method of the global variable event_scheduler.
- If event_scheduler is switched from 0 to 1 then the scheduler main
- thread is resumed and if from 1 to 0 the scheduler thread is suspended
-
- SYNOPSIS
- sys_var_event_scheduler::update()
- thd Thread context (unused)
- var The new value
-
- Returns
- FALSE OK
- TRUE Error
-*/
-
-bool
-sys_var_event_scheduler::update(THD *thd, set_var *var)
-{
- int res;
- /* here start the thread if not running. */
- DBUG_ENTER("sys_var_event_scheduler::update");
- DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
-
- enum Events::enum_opt_event_scheduler
- new_state=
- (enum Events::enum_opt_event_scheduler) var->save_result.ulong_value;
-
- res= Events::switch_event_scheduler_state(new_state);
-
- DBUG_RETURN((bool) res);
-}
-
-
-uchar *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- return (uchar *) Events::get_opt_event_scheduler_str();
-}
-#endif
-
-/****************************************************************************
- Used templates
-****************************************************************************/
-
-#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-template class List<set_var_base>;
-template class List_iterator_fast<set_var_base>;
-template class I_List_iterator<NAMED_LIST>;
-#endif
diff --git a/sql/set_var.h b/sql/set_var.h
index 120388415f5..d878e85cec0 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -1,7 +1,6 @@
#ifndef SET_VAR_INCLUDED
#define SET_VAR_INCLUDED
-
-/* Copyright (C) 2002-2006 MySQL AB
+/* Copyright 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,31 +15,23 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Classes to support the SET command */
+/**
+ @file
+ "public" interface to sys_var - server configuration variables.
+*/
#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
+#pragma interface /* gcc class implementation */
#endif
-/****************************************************************************
- Variables that are changable runtime are declared using the
- following classes
-****************************************************************************/
+#include <my_getopt.h>
class sys_var;
class set_var;
-class sys_var_pluginvar; /* opaque */
-typedef struct system_variables SV;
-typedef struct my_locale_st MY_LOCALE;
+class sys_var_pluginvar;
+class PolyLock;
-extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib,
- optimizer_switch_typelib, slave_exec_mode_typelib;
-
-typedef int (*sys_check_func)(THD *, set_var *);
-typedef bool (*sys_update_func)(THD *, set_var *);
-typedef void (*sys_after_update_func)(THD *,enum_var_type);
-typedef void (*sys_set_default_func)(THD *, enum_var_type);
-typedef uchar *(*sys_value_ptr_func)(THD *thd);
+extern TYPELIB bool_typelib;
struct sys_var_chain
{
@@ -48,1297 +39,165 @@ struct sys_var_chain
sys_var *last;
};
+int mysql_add_sys_var_chain(sys_var *chain);
+int mysql_del_sys_var_chain(sys_var *chain);
+
+/**
+ A class representing one system variable - that is something
+ that can be accessed as @@global.variable_name or @@session.variable_name,
+ visible in SHOW xxx VARIABLES and in INFORMATION_SCHEMA.xxx_VARIABLES,
+ optionally it can be assigned to, optionally it can have a command-line
+ counterpart with the same name.
+*/
class sys_var
{
public:
+ sys_var *next;
+ LEX_CSTRING name;
+ enum flag_enum { GLOBAL, SESSION, ONLY_SESSION, SCOPE_MASK=1023,
+ READONLY=1024, ALLOCATED=2048 };
+ /**
+ Enumeration type to indicate for a system variable whether
+ it will be written to the binlog or not.
+ */
+ enum binlog_status_enum { VARIABLE_NOT_IN_BINLOG,
+ SESSION_VARIABLE_IN_BINLOG } binlog_status;
+protected:
+ typedef bool (*on_check_function)(sys_var *self, THD *thd, set_var *var);
+ typedef bool (*on_update_function)(sys_var *self, THD *thd, enum_var_type type);
+
+ int flags; ///< or'ed flag_enum values
+ const SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc
+ my_option option; ///< min, max, default values are stored here
+ PolyLock *guard; ///< *second* lock that protects the variable
+ ptrdiff_t offset; ///< offset to the value from global_system_variables
+ on_check_function on_check;
+ on_update_function on_update;
+ struct { uint version; const char *substitute; } deprecated;
+ bool is_os_charset; ///< true if the value is in character_set_filesystem
+
+public:
+ sys_var(sys_var_chain *chain, const char *name_arg, const char *comment,
+ int flag_args, ptrdiff_t off, int getopt_id,
+ enum get_opt_arg_type getopt_arg_type, SHOW_TYPE show_val_type_arg,
+ longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg,
+ on_check_function on_check_func, on_update_function on_update_func,
+ uint deprecated_version, const char *substitute);
/**
- Enumeration type to indicate for a system variable whether it will be written to the binlog or not.
+ The instance should only be destroyed on shutdown, as it doesn't unlink
+ itself from the chain.
*/
- enum Binlog_status_enum
- {
- /* The variable value is not in the binlog. */
- NOT_IN_BINLOG,
- /* The value of the @@session variable is in the binlog. */
- SESSION_VARIABLE_IN_BINLOG
- /*
- Currently, no @@global variable is ever in the binlog, so we
- don't need an enumeration value for that.
- */
- };
-
- sys_var *next;
- struct my_option *option_limits; /* Updated by by set_var_init() */
- uint name_length; /* Updated by by set_var_init() */
- const char *name;
-
- sys_after_update_func after_update;
- bool no_support_one_shot;
- /*
- true if the value is in character_set_filesystem,
- false otherwise.
- Note that we can't use a pointer to the charset as the system var is
- instantiated in global scope and the charset pointers are initialized
- later.
- */
- bool is_os_charset;
- sys_var(const char *name_arg, sys_after_update_func func= NULL,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :name(name_arg), after_update(func), no_support_one_shot(1),
- is_os_charset (FALSE),
- binlog_status(binlog_status_arg),
- m_allow_empty_value(TRUE)
- {}
virtual ~sys_var() {}
- void chain_sys_var(sys_var_chain *chain_arg)
- {
- 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);
- bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
- bool is_written_to_binlog(enum_var_type type)
- {
- return (type == OPT_SESSION || type == OPT_DEFAULT) &&
- (binlog_status == SESSION_VARIABLE_IN_BINLOG);
- }
- virtual bool update(THD *thd, set_var *var)=0;
- virtual void set_default(THD *thd_arg, enum_var_type type) {}
- virtual SHOW_TYPE show_type() { return SHOW_UNDEF; }
- virtual uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return 0; }
- virtual bool check_type(enum_var_type type)
- { return type != OPT_GLOBAL; } /* Error if not GLOBAL */
- virtual bool check_update_type(Item_result type)
- { return type != INT_RESULT; } /* Assume INT */
- virtual bool check_default(enum_var_type type)
- { return option_limits == 0; }
- virtual bool is_struct() { return 0; }
- virtual bool is_readonly() const { return 0; }
- CHARSET_INFO *charset(THD *thd);
+ /**
+ downcast for sys_var_pluginvar. Returns this if it's an instance
+ of sys_var_pluginvar, and 0 otherwise.
+ */
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
-protected:
- void set_allow_empty_value(bool allow_empty_value)
- {
- m_allow_empty_value= allow_empty_value;
- }
-
-private:
- const Binlog_status_enum binlog_status;
-
- bool m_allow_empty_value;
-};
-
-
-/*
- A base class for all variables that require its access to
- be guarded with a mutex.
-*/
-
-class sys_var_global: public sys_var
-{
-protected:
- pthread_mutex_t *guard;
-public:
- sys_var_global(const char *name_arg, sys_after_update_func after_update_arg,
- pthread_mutex_t *guard_arg)
- :sys_var(name_arg, after_update_arg), guard(guard_arg) {}
-};
-
-
-/*
- A global-only ulong variable that requires its access to be
- protected with a mutex.
-*/
-
-class sys_var_long_ptr_global: public sys_var_global
-{
-public:
- ulong *value;
- 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);
- SHOW_TYPE show_type() { return SHOW_LONG; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return (uchar*) value; }
-};
-
-/**
- Unsigned int system variable class
- */
-class sys_var_uint_ptr :public sys_var
-{
-public:
- sys_var_uint_ptr(sys_var_chain *chain, const char *name_arg,
- uint *value_ptr_arg,
- sys_after_update_func after_update_arg= NULL)
- :sys_var(name_arg, after_update_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);
- SHOW_TYPE show_type() { return SHOW_INT; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return (uchar*) value; }
-private:
- uint *value;
-};
-
-/*
- A global ulong variable that is protected by LOCK_global_system_variables
-*/
-
-class sys_var_long_ptr :public sys_var_long_ptr_global
-{
-public:
- sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr,
- sys_after_update_func after_update_arg= NULL);
-};
-
-
-class sys_var_ulonglong_ptr :public sys_var
-{
-public:
- ulonglong *value;
- 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)
- { 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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return (uchar*) value; }
-};
-
-
-class sys_var_bool_ptr :public sys_var
-{
-public:
- my_bool *value;
- 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);
- }
- bool update(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_MY_BOOL; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return (uchar*) value; }
- bool check_update_type(Item_result type) { return 0; }
-};
-
-
-class sys_var_bool_ptr_readonly :public sys_var_bool_ptr
-{
-public:
- sys_var_bool_ptr_readonly(sys_var_chain *chain, const char *name_arg,
- my_bool *value_arg)
- :sys_var_bool_ptr(chain, name_arg, value_arg)
- {}
- bool is_readonly() const { return 1; }
-};
-
-
-class sys_var_str :public sys_var
-{
-public:
- char *value; // Pointer to allocated string
- uint value_length;
- sys_check_func check_func;
- sys_update_func update_func;
- sys_set_default_func set_default_func;
- 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)
- {
- return (*update_func)(thd, var);
- }
- void set_default(THD *thd, enum_var_type type)
- {
- (*set_default_func)(thd, type);
- }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- { return (uchar*) value; }
- bool check_update_type(Item_result type)
- {
- return type != STRING_RESULT; /* Only accept strings */
- }
- bool check_default(enum_var_type type) { return 0; }
-};
-
-
-class sys_var_const_str :public sys_var
-{
-public:
- char *value; // Pointer to const value
- sys_var_const_str(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;
- }
- bool update(THD *thd, set_var *var)
- {
- return 1;
- }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- {
- return (uchar*) value;
- }
- bool check_update_type(Item_result type)
- {
- return 1;
- }
- bool check_default(enum_var_type type) { return 1; }
- bool is_readonly() const { return 1; }
-};
-
-
-class sys_var_const_os_str: public sys_var_const_str
-{
-public:
- sys_var_const_os_str(sys_var_chain *chain, const char *name_arg,
- const char *value_arg)
- :sys_var_const_str(chain, name_arg, value_arg)
- {
- is_os_charset= TRUE;
- }
-};
-
-
-class sys_var_const_str_ptr :public sys_var
-{
-public:
- char **value; // Pointer to const value
- 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;
- }
- bool update(THD *thd, set_var *var)
- {
- return 1;
- }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- {
- return (uchar*) *value;
- }
- bool check_update_type(Item_result type)
- {
- return 1;
- }
- bool check_default(enum_var_type type) { return 1; }
- bool is_readonly() const { return 1; }
-};
-
-
-class sys_var_const_os_str_ptr :public sys_var_const_str_ptr
-{
-public:
- sys_var_const_os_str_ptr(sys_var_chain *chain, const char *name_arg,
- char **value_arg)
- :sys_var_const_str_ptr(chain, name_arg, value_arg)
- {
- is_os_charset= TRUE;
- }
-};
-
-
-class sys_var_enum :public sys_var
-{
- uint *value;
- TYPELIB *enum_names;
-public:
- 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);
- }
- bool update(THD *thd, set_var *var);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check_update_type(Item_result type) { return 0; }
-};
-
-
-class sys_var_enum_const :public sys_var
-{
- ulong SV::*offset;
- TYPELIB *enum_names;
-public:
- sys_var_enum_const(sys_var_chain *chain, const char *name_arg, ulong SV::*offset_arg,
- TYPELIB *typelib, sys_after_update_func func)
- :sys_var(name_arg,func), offset(offset_arg), enum_names(typelib)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var) { return 1; }
- bool update(THD *thd, set_var *var) { return 1; }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool check_update_type(Item_result type) { return 1; }
- bool is_readonly() const { return 1; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_thd :public sys_var
-{
-public:
- sys_var_thd(const char *name_arg,
- sys_after_update_func func= NULL,
- Binlog_status_enum binlog_status= NOT_IN_BINLOG)
- :sys_var(name_arg, func, binlog_status)
- {}
- bool check_type(enum_var_type type) { return 0; }
- bool check_default(enum_var_type type)
- {
- return type == OPT_GLOBAL && !option_limits;
- }
-};
-
-
-class sys_var_thd_ulong :public sys_var_thd
-{
- sys_check_func check_func;
-public:
- ulong SV::*offset;
- sys_var_thd_ulong(sys_var_chain *chain, const char *name_arg,
- ulong SV::*offset_arg,
- sys_check_func c_func= NULL,
- sys_after_update_func au_func= NULL,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_thd(name_arg, au_func, binlog_status_arg), check_func(c_func),
- offset(offset_arg)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var);
+ bool set_default(THD *thd, enum_var_type type);
bool update(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_LONG; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_thd_ha_rows :public sys_var_thd
-{
-public:
- ha_rows SV::*offset;
- 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)
- { 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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-class sys_var_thd_ulonglong :public sys_var_thd
-{
-public:
- ulonglong SV::*offset;
- bool only_global;
- sys_var_thd_ulonglong(sys_var_chain *chain, const char *name_arg,
- ulonglong SV::*offset_arg)
- :sys_var_thd(name_arg), offset(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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check(THD *thd, set_var *var);
- bool check_default(enum_var_type type)
- {
- return type == OPT_GLOBAL && !option_limits;
- }
+ SHOW_TYPE show_type() { return show_val_type; }
+ int scope() const { return flags & SCOPE_MASK; }
+ CHARSET_INFO *charset(THD *thd);
+ bool is_readonly() const { return flags & READONLY; }
+ /**
+ the following is only true for keycache variables,
+ that support the syntax @@keycache_name.variable_name
+ */
+ bool is_struct() { return option.var_type & GET_ASK_ADDR; }
+ bool is_written_to_binlog(enum_var_type type)
+ { return type != OPT_GLOBAL && binlog_status == SESSION_VARIABLE_IN_BINLOG; }
+ virtual bool check_update_type(Item_result type) = 0;
bool check_type(enum_var_type type)
{
- return (only_global && type != OPT_GLOBAL);
- }
-};
-
-
-class sys_var_thd_bool :public sys_var_thd
-{
-public:
- my_bool SV::*offset;
- 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)
- { 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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check(THD *thd, set_var *var)
- {
- return check_enum(thd, var, &bool_typelib);
- }
- bool check_update_type(Item_result type) { return 0; }
-};
-
-
-class sys_var_thd_enum :public sys_var_thd
-{
-protected:
- ulong SV::*offset;
- TYPELIB *enum_names;
- sys_check_func check_func;
-public:
- sys_var_thd_enum(sys_var_chain *chain, const char *name_arg,
- ulong SV::*offset_arg, TYPELIB *typelib,
- sys_after_update_func func= NULL,
- sys_check_func check= NULL)
- :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)
- {
- /*
- check_enum fails if the character representation supplied was wrong
- or that the integer value was wrong or missing.
- */
- if (check_enum(thd, var, enum_names))
- return TRUE;
- else if ((check_func && (*check_func)(thd, var)))
- return TRUE;
- else
- return FALSE;
- }
- bool update(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check_update_type(Item_result type) { return 0; }
-};
-
-
-class sys_var_thd_optimizer_switch :public sys_var_thd_enum
-{
-public:
- sys_var_thd_optimizer_switch(sys_var_chain *chain, const char *name_arg,
- ulong SV::*offset_arg)
- :sys_var_thd_enum(chain, name_arg, offset_arg, &optimizer_switch_typelib)
- {}
- bool check(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
- LEX_STRING *rep);
-};
-
-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(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)
- {
- return check_set(thd, var, enum_names);
- }
- void set_default(THD *thd, enum_var_type type);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
- LEX_STRING *rep);
-};
-
-
-class sys_var_thd_storage_engine :public sys_var_thd
-{
-protected:
- plugin_ref SV::*offset;
-public:
- 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)
- {
- return type != STRING_RESULT; /* Only accept strings */
- }
- void set_default(THD *thd, enum_var_type type);
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-class sys_var_thd_bit :public sys_var_thd
-{
- sys_check_func check_func;
- sys_update_func update_func;
-public:
- ulonglong bit_flag;
- bool reverse;
- 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,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_thd(name_arg, NULL, binlog_status_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; }
- bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
- SHOW_TYPE show_type() { return SHOW_MY_BOOL; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-#ifndef DBUG_OFF
-class sys_var_thd_dbug :public sys_var_thd
-{
-public:
- 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; }
- bool update(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type) { DBUG_POP(); }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *b);
-};
-#endif /* DBUG_OFF */
-
-#if defined(ENABLED_DEBUG_SYNC)
-/* Debug Sync Facility. Implemented in debug_sync.cc. */
-class sys_var_debug_sync :public sys_var_thd
-{
-public:
- sys_var_debug_sync(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);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool check_update_type(Item_result type) { return type != STRING_RESULT; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-#endif /* defined(ENABLED_DEBUG_SYNC) */
-
-/* some variables that require special handling */
-
-class sys_var_timestamp :public sys_var
-{
-public:
- sys_var_timestamp(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var(name_arg, NULL, binlog_status_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; }
- bool check_default(enum_var_type type) { return 0; }
- SHOW_TYPE show_type() { return SHOW_LONG; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_last_insert_id :public sys_var
-{
-public:
- sys_var_last_insert_id(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var(name_arg, NULL, binlog_status_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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_insert_id :public sys_var
-{
-public:
- 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; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_rand_seed1 :public sys_var
-{
-public:
- sys_var_rand_seed1(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var(name_arg, NULL, binlog_status_arg)
- { chain_sys_var(chain); }
- bool update(THD *thd, set_var *var);
- bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
-};
-
-class sys_var_rand_seed2 :public sys_var
-{
-public:
- sys_var_rand_seed2(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var(name_arg, NULL, binlog_status_arg)
- { chain_sys_var(chain); }
- bool update(THD *thd, set_var *var);
- bool check_type(enum_var_type type) { return type == OPT_GLOBAL; }
-};
-
-
-class sys_var_collation :public sys_var_thd
-{
-public:
- sys_var_collation(const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_thd(name_arg, NULL, binlog_status_arg)
- {
- no_support_one_shot= 0;
- }
- bool check(THD *thd, set_var *var);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool check_update_type(Item_result type)
- {
- return ((type != STRING_RESULT) && (type != INT_RESULT));
- }
- bool check_default(enum_var_type type) { return 0; }
- virtual void set_default(THD *thd, enum_var_type type)= 0;
-};
-
-class sys_var_character_set :public sys_var_thd
-{
-public:
- bool nullable;
- sys_var_character_set(const char *name_arg, bool is_nullable= 0,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_thd(name_arg, NULL, binlog_status_arg), nullable(is_nullable)
- {
- /*
- 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.
- */
- no_support_one_shot= 0;
- }
- bool check(THD *thd, set_var *var);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool check_update_type(Item_result type)
- {
- return ((type != STRING_RESULT) && (type != INT_RESULT));
- }
- bool check_default(enum_var_type type) { return 0; }
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- virtual void set_default(THD *thd, enum_var_type type)= 0;
- virtual CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type)= 0;
-};
-
-class sys_var_character_set_sv :public sys_var_character_set
-{
- CHARSET_INFO *SV::*offset;
- CHARSET_INFO **global_default;
-public:
- 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,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- : sys_var_character_set(name_arg, is_nullable, binlog_status_arg),
- 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_client: public sys_var_character_set_sv
-{
-public:
- sys_var_character_set_client(sys_var_chain *chain, const char *name_arg,
- CHARSET_INFO *SV::*offset_arg,
- CHARSET_INFO **global_default_arg,
- Binlog_status_enum binlog_status_arg)
- : sys_var_character_set_sv(chain, name_arg, offset_arg, global_default_arg,
- 0, binlog_status_arg)
- { }
- bool check(THD *thd, set_var *var);
-};
-
-
-class sys_var_character_set_database :public sys_var_character_set
-{
-public:
- sys_var_character_set_database(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg=
- NOT_IN_BINLOG)
- : sys_var_character_set(name_arg, 0, binlog_status_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_collation_sv :public sys_var_collation
-{
- CHARSET_INFO *SV::*offset;
- CHARSET_INFO **global_default;
-public:
- sys_var_collation_sv(sys_var_chain *chain, const char *name_arg,
- CHARSET_INFO *SV::*offset_arg,
- CHARSET_INFO **global_default_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_collation(name_arg, binlog_status_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);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-class sys_var_key_cache_param :public sys_var
-{
-protected:
- size_t offset;
-public:
- 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); }
- uchar *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; }
-};
-
-
-class sys_var_key_buffer_size :public sys_var_key_cache_param
-{
-public:
- 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; }
-};
-
-
-class sys_var_key_cache_long :public sys_var_key_cache_param
-{
-public:
- 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; }
-};
-
-
-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(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)
- {
- return type != STRING_RESULT; /* Only accept strings */
- }
- bool check_default(enum_var_type type) { return 0; }
- bool check(THD *thd, set_var *var);
- bool update(THD *thd, set_var *var);
- void update2(THD *thd, enum_var_type type, DATE_TIME_FORMAT *new_value);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- void set_default(THD *thd, enum_var_type type);
-};
-
-
-class sys_var_log_state :public sys_var_bool_ptr
-{
- uint log_type;
-public:
- 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);
-};
-
-
-class sys_var_set :public sys_var
-{
-protected:
- ulong *value;
- TYPELIB *enum_names;
-public:
- sys_var_set(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); }
- virtual bool check(THD *thd, set_var *var)
- {
- return check_set(thd, var, enum_names);
- }
- virtual void set_default(THD *thd, enum_var_type type)
- {
- *value= 0;
- }
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check_update_type(Item_result type) { return 0; }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
-};
-
-class sys_var_set_slave_mode :public sys_var_set
-{
-public:
- sys_var_set_slave_mode(sys_var_chain *chain, const char *name_arg,
- ulong *value_arg,
- TYPELIB *typelib, sys_after_update_func func) :
- sys_var_set(chain, name_arg, value_arg, typelib, func) {}
- void set_default(THD *thd, enum_var_type type);
- bool check(THD *thd, set_var *var);
- bool update(THD *thd, set_var *var);
-};
-
-class sys_var_log_output :public sys_var
-{
- ulong *value;
- TYPELIB *enum_names;
-public:
- 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);
- set_allow_empty_value(FALSE);
- }
- virtual bool check(THD *thd, set_var *var)
- {
- return check_set(thd, var, enum_names);
- }
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check_update_type(Item_result type) { return 0; }
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
-};
-
-
-/* Variable that you can only read from */
-
-class sys_var_readonly: public sys_var
-{
-public:
- enum_var_type var_type;
- SHOW_TYPE show_type_value;
- sys_value_ptr_func value_ptr_func;
- 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; }
- bool check_update_type(Item_result type) { return 1; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- {
- return (*value_ptr_func)(thd);
- }
- SHOW_TYPE show_type() { return show_type_value; }
- bool is_readonly() const { return 1; }
-};
-
-
-class sys_var_readonly_os: public sys_var_readonly
-{
-public:
- sys_var_readonly_os(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_readonly(chain, name_arg, type, show_type_arg, value_ptr_func_arg)
- {
- is_os_charset= TRUE;
- }
-};
-
-
-/**
- Global-only, read-only variable. E.g. command line option.
-*/
-
-class sys_var_const: public sys_var
-{
-public:
- enum_var_type var_type;
- SHOW_TYPE show_type_value;
- uchar *ptr;
- sys_var_const(sys_var_chain *chain, const char *name_arg, enum_var_type type,
- SHOW_TYPE show_type_arg, uchar *ptr_arg)
- :sys_var(name_arg), var_type(type),
- show_type_value(show_type_arg), ptr(ptr_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; }
- bool check_update_type(Item_result type) { return 1; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- {
- return ptr;
- }
- SHOW_TYPE show_type() { return show_type_value; }
- bool is_readonly() const { return 1; }
-};
-
-
-class sys_var_const_os: public sys_var_const
-{
-public:
- enum_var_type var_type;
- SHOW_TYPE show_type_value;
- uchar *ptr;
- sys_var_const_os(sys_var_chain *chain, const char *name_arg,
- enum_var_type type,
- SHOW_TYPE show_type_arg, uchar *ptr_arg)
- :sys_var_const(chain, name_arg, type, show_type_arg, ptr_arg)
- {
- is_os_charset= TRUE;
+ switch (scope())
+ {
+ case GLOBAL: return type != OPT_GLOBAL;
+ case SESSION: return false; // always ok
+ case ONLY_SESSION: return type == OPT_GLOBAL;
+ }
+ return true; // keep gcc happy
}
-};
+ bool register_option(DYNAMIC_ARRAY *array)
+ { return option.id != -1 && insert_dynamic(array, (uchar*)&option); }
-
-class sys_var_have_option: public sys_var
-{
+private:
+ virtual bool do_check(THD *thd, set_var *var) = 0;
+ /**
+ save the session default value of the variable in var
+ */
+ virtual void session_save_default(THD *thd, set_var *var) = 0;
+ /**
+ save the global default value of the variable in var
+ */
+ virtual void global_save_default(THD *thd, set_var *var) = 0;
+ virtual bool session_update(THD *thd, set_var *var) = 0;
+ virtual bool global_update(THD *thd, set_var *var) = 0;
+ void do_deprecated_warning(THD *thd);
protected:
- virtual SHOW_COMP_OPTION get_option() = 0;
-public:
- sys_var_have_option(sys_var_chain *chain, const char *variable_name):
- sys_var(variable_name)
- { chain_sys_var(chain); }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
- {
- return (uchar*) show_comp_option_name[get_option()];
- }
- 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 != OPT_GLOBAL; }
- bool check_update_type(Item_result type) { return 1; }
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool is_readonly() const { return 1; }
-};
-
-
-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(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- :sys_var_thd(name_arg, NULL, binlog_status_arg)
- {
- no_support_one_shot= 0;
- 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)
- {
- return type != STRING_RESULT; /* Only accept strings */
- }
- bool check_default(enum_var_type type) { return 0; }
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- virtual void set_default(THD *thd, enum_var_type type);
-};
-
-
-class sys_var_max_user_conn : public sys_var_thd
-{
-public:
- 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)
- {
- return type != OPT_GLOBAL || !option_limits;
- }
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_INT; }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-/**
- * @brief This is a specialization of sys_var_thd_ulong that implements a
- read-only session variable. The class overrides check() and check_default()
- to achieve the read-only property for the session part of the variable.
- */
-class sys_var_thd_ulong_session_readonly : public sys_var_thd_ulong
-{
-public:
- sys_var_thd_ulong_session_readonly(sys_var_chain *chain_arg,
- const char *name_arg, ulong SV::*offset_arg,
- sys_check_func c_func= NULL,
- sys_after_update_func au_func= NULL,
- Binlog_status_enum bl_status_arg= NOT_IN_BINLOG):
- sys_var_thd_ulong(chain_arg, name_arg, offset_arg, c_func, au_func, bl_status_arg)
- { }
- bool check(THD *thd, set_var *var);
- bool check_default(enum_var_type type)
- {
- return type != OPT_GLOBAL || !option_limits;
- }
-};
-
-
-class sys_var_microseconds :public sys_var_thd
-{
- ulonglong SV::*offset;
-public:
- sys_var_microseconds(sys_var_chain *chain, const char *name_arg,
- ulonglong SV::*offset_arg):
- sys_var_thd(name_arg), offset(offset_arg)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var) {return 0;}
- bool update(THD *thd, set_var *var);
- void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE show_type() { return SHOW_DOUBLE; }
- bool check_update_type(Item_result type)
- {
- return (type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT);
- }
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
-};
-
-
-/**
- Handler for setting the system variable --read-only.
-*/
-
-class sys_var_opt_readonly :public sys_var_bool_ptr
-{
-public:
- 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);
-};
-
-
-
-class sys_var_thd_lc: public sys_var_thd
-{
-public:
- sys_var_thd_lc(sys_var_chain *chain, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- : sys_var_thd(name_arg, NULL, binlog_status_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; }
- bool check_update_type(Item_result type)
- {
- return ((type != STRING_RESULT) && (type != INT_RESULT));
- }
- bool check_default(enum_var_type type) { return 0; }
-};
-
-
-class sys_var_thd_lc_time_names :public sys_var_thd_lc
-{
-public:
- sys_var_thd_lc_time_names(sys_var_chain *chain_arg, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- : sys_var_thd_lc(chain_arg, name_arg, binlog_status_arg)
- {}
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- void set_default(THD *thd, enum_var_type type);
-};
-
-
-class sys_var_thd_lc_messages :public sys_var_thd_lc
-{
-public:
- sys_var_thd_lc_messages(sys_var_chain *chain_arg, const char *name_arg,
- Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
- : sys_var_thd_lc(chain_arg, name_arg, binlog_status_arg)
- {}
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- void set_default(THD *thd, enum_var_type type);
-};
+ /**
+ A pointer to a value of the variable for SHOW.
+ It must be of show_val_type type (bool for SHOW_BOOL, int for SHOW_INT,
+ longlong for SHOW_LONGLONG, etc).
+ */
+ virtual uchar *session_value_ptr(THD *thd, LEX_STRING *base);
+ virtual uchar *global_value_ptr(THD *thd, LEX_STRING *base);
+ /**
+ A pointer to a storage area of the variable, to the raw data.
+ Typically it's the same as session_value_ptr(), but it's different,
+ for example, for ENUM, that is printed as a string, but stored as a number.
+ */
+ uchar *session_var_ptr(THD *thd)
+ { return ((uchar*)&(thd->variables)) + offset; }
-#ifdef HAVE_EVENT_SCHEDULER
-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(sys_var_chain *chain, const char *name_arg) :
- sys_var_long_ptr(chain, name_arg, NULL, NULL) {};
- bool update(THD *thd, set_var *var);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- SHOW_TYPE show_type() { return SHOW_CHAR; }
- bool check(THD *thd, set_var *var);
- bool check_update_type(Item_result type)
- {
- return type != STRING_RESULT && type != INT_RESULT;
- }
-};
-#endif
-
-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(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)
- {};
- bool check(THD *thd, set_var *var);
- bool is_readonly() const;
+ uchar *global_var_ptr()
+ { return ((uchar*)&global_system_variables) + offset; }
};
/****************************************************************************
Classes for parsing of the SET command
****************************************************************************/
+/**
+ A base class for everything that can be set with SET command.
+ It's similar to Items, an instance of this is created by the parser
+ for every assigmnent in SET (or elsewhere, e.g. in SELECT).
+*/
class set_var_base :public Sql_alloc
{
public:
set_var_base() {}
virtual ~set_var_base() {}
- virtual int check(THD *thd)=0; /* To check privileges etc. */
- virtual int update(THD *thd)=0; /* To set the value */
- /* light check for PS */
- virtual int light_check(THD *thd) { return check(thd); }
- virtual bool no_support_one_shot() { return 1; }
+ virtual int check(THD *thd)=0; /* To check privileges etc. */
+ virtual int update(THD *thd)=0; /* To set the value */
+ virtual int light_check(THD *thd) { return check(thd); } /* for PS */
};
-/* MySQL internal variables, like query_cache_size */
-
+/**
+ set_var_base descendant for assignments to the system variables.
+*/
class set_var :public set_var_base
{
public:
- sys_var *var;
- Item *value;
+ sys_var *var; ///< system variable to be updated
+ Item *value; ///< the expression that provides the new value of the variable
enum_var_type type;
- union
- {
- CHARSET_INFO *charset;
- ulong ulong_value;
- ulonglong ulonglong_value;
- plugin_ref plugin;
- DATE_TIME_FORMAT *date_time_format;
- Time_zone *time_zone;
- MY_LOCALE *locale_value;
+ union ///< temp storage to hold a value between sys_var::check and ::update
+ {
+ ulonglong ulonglong_value; ///< for all integer, set, enum sysvars
+ double double_value; ///< for Sys_var_double
+ plugin_ref plugin; ///< for Sys_var_plugin
+ Time_zone *time_zone; ///< for Sys_var_tz
+ LEX_STRING string_value; ///< for Sys_var_charptr and others
+ void *ptr; ///< for Sys_var_struct
} save_result;
- LEX_STRING base; /* for structs */
+ LEX_STRING base; /**< for structured variables, like keycache_name.variable_name */
set_var(enum_var_type type_arg, sys_var *var_arg,
const LEX_STRING *base_name_arg, Item *value_arg)
@@ -1351,10 +210,10 @@ public:
if (value_arg && value_arg->type() == Item::FIELD_ITEM)
{
Item_field *item= (Item_field*) value_arg;
- if (!(value=new Item_string(item->field_name,
+ if (!(value=new Item_string(item->field_name,
(uint) strlen(item->field_name),
- system_charset_info)))
- value=value_arg; /* Give error message later */
+ system_charset_info))) // names are utf8
+ value=value_arg; /* Give error message later */
}
else
value=value_arg;
@@ -1362,12 +221,10 @@ public:
int check(THD *thd);
int update(THD *thd);
int light_check(THD *thd);
- bool no_support_one_shot() { return var->no_support_one_shot; }
};
/* User variables like @my_own_variable */
-
class set_var_user: public set_var_base
{
Item_func_set_user_var *user_var_item;
@@ -1404,8 +261,8 @@ class set_var_collation_client: public set_var_base
CHARSET_INFO *collation_connection;
public:
set_var_collation_client(CHARSET_INFO *client_coll_arg,
- CHARSET_INFO *connection_coll_arg,
- CHARSET_INFO *result_coll_arg)
+ CHARSET_INFO *connection_coll_arg,
+ CHARSET_INFO *result_coll_arg)
:character_set_client(client_coll_arg),
character_set_results(result_coll_arg),
collation_connection(connection_coll_arg)
@@ -1414,86 +271,26 @@ public:
int update(THD *thd);
};
-
-extern "C"
-{
- typedef int (*process_key_cache_t) (const char *, KEY_CACHE *);
-}
-
-/* Named lists (used for keycaches) */
-
-class NAMED_LIST :public ilink
-{
- const char *name;
- uint name_length;
-public:
- uchar* data;
-
- NAMED_LIST(I_List<NAMED_LIST> *links, const char *name_arg,
- uint name_length_arg, uchar* data_arg)
- :name_length(name_length_arg), data(data_arg)
- {
- name= my_strndup(name_arg, name_length, MYF(MY_WME));
- links->push_back(this);
- }
- inline bool cmp(const char *name_cmp, uint length)
- {
- return length == name_length && !memcmp(name, name_cmp, length);
- }
- ~NAMED_LIST()
- {
- my_free((uchar*) name, MYF(0));
- }
- friend bool process_key_caches(process_key_cache_t func);
- friend void delete_elements(I_List<NAMED_LIST> *list,
- void (*free_element)(const char*, uchar*));
-};
-
-/* updated in sql_acl.cc */
-
-extern sys_var_thd_bool sys_old_alter_table;
-extern sys_var_thd_bool sys_old_passwords;
-extern LEX_STRING default_key_cache_base;
-
-/* For sql_yacc */
-struct sys_var_with_base
-{
- sys_var *var;
- LEX_STRING base_name;
-};
-
/*
Prototypes for helper functions
*/
-int set_var_init();
-void set_var_free();
-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);
+SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted, enum enum_var_type type);
+
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);
-void fix_slave_exec_mode(enum_var_type type);
-ulong fix_sql_mode(ulong sql_mode);
-extern sys_var_const_str sys_charset_system;
-extern sys_var_str sys_init_connect;
-extern sys_var_str sys_init_slave;
-extern sys_var_thd_time_zone sys_time_zone;
-extern sys_var_thd_bit sys_autocommit;
+
+bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type);
+
+ulong expand_sql_mode(ulonglong sql_mode);
+bool sql_mode_string_representation(THD *thd, ulong sql_mode, LEX_STRING *ls);
+
+extern sys_var *Sys_autocommit_ptr;
+
CHARSET_INFO *get_old_charset_by_name(const char *old_name);
-uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
- NAMED_LIST **found);
-extern sys_var_str sys_var_general_log_path, sys_var_slow_log_path;
+int sys_var_init(DYNAMIC_ARRAY *long_options);
+void sys_var_end(void);
-/* key_cache functions */
-KEY_CACHE *get_key_cache(LEX_STRING *cache_name);
-KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
-void free_key_cache(const char *name, KEY_CACHE *key_cache);
-bool process_key_caches(process_key_cache_t func);
-void delete_elements(I_List<NAMED_LIST> *list,
- void (*free_element)(const char*, uchar*));
+#endif
-#endif /* SET_VAR_INCLUDED */
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 03d7ff30f7e..09812583745 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6108,7 +6108,7 @@ ER_TRG_CANT_OPEN_TABLE
ER_CANT_CREATE_SROUTINE
eng "Cannot create stored routine `%-.64s`. Check warnings"
-ER_SLAVE_AMBIGOUS_EXEC_MODE
+ER_NEVER_USED
eng "Ambiguous slave modes combination. %s"
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
@@ -6260,3 +6260,9 @@ ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
eng "Field '%-.192s' is of a not allowed type for this type of partitioning"
ER_PARTITION_FIELDS_TOO_LONG
eng "The total length of the partitioning fields is too large"
+ER_PATH_LENGTH
+ eng "The path specified for %.64s is too long."
+ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT
+ eng "The syntax '%s' is deprecated and will be removed in MySQL %s."
+ ger "Die Syntax '%s' ist veraltet und wird in MySQL %s entfernt."
+
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index ab81c122497..84cd6247493 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6109,7 +6109,7 @@ ER_TRG_CANT_OPEN_TABLE
ER_CANT_CREATE_SROUTINE
eng "Cannot create stored routine `%-.64s`. Check warnings"
-ER_SLAVE_AMBIGOUS_EXEC_MODE
+ER_NEVER_USED
eng "Ambiguous slave modes combination. %s"
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
@@ -6260,3 +6260,9 @@ ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
eng "Field '%-.192s' is of a not allowed type for this type of partitioning"
ER_PARTITION_FIELDS_TOO_LONG
eng "The total length of the partitioning fields is too large"
+ER_PATH_LENGTH
+ eng "The path specified for %.64s is too long."
+ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT
+ eng "The syntax '%s' is deprecated and will be removed in MySQL %s."
+ ger "Die Syntax '%s' ist veraltet und wird in MySQL %s entfernt."
+
diff --git a/sql/slave.cc b/sql/slave.cc
index 1cfd54a7dc0..4dea78596ba 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -362,6 +362,9 @@ static void print_slave_skip_errors(void)
DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
+ /* Make @@slave_skip_errors show the nice human-readable value. */
+ opt_slave_skip_errors= slave_skip_error_names;
+
if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
{
/* purecov: begin tested */
@@ -1871,12 +1874,12 @@ void set_slave_thread_options(THD* thd)
when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
only for client threads.
*/
- ulonglong options= thd->options | OPTION_BIG_SELECTS;
+ ulonglong options= thd->variables.option_bits | OPTION_BIG_SELECTS;
if (opt_log_slave_updates)
options|= OPTION_BIN_LOG;
else
options&= ~OPTION_BIN_LOG;
- thd->options= options;
+ thd->variables.option_bits= options;
thd->variables.completion_type= 0;
DBUG_VOID_RETURN;
}
@@ -2187,8 +2190,8 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
ev->get_type_str(), ev->get_type_code(),
ev->server_id));
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
- FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
- FLAGSTR(thd->options, OPTION_BEGIN),
+ FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
rli->last_event_start_time));
/*
@@ -2224,7 +2227,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
int reason= ev->shall_skip(rli);
if (reason == Log_event::EVENT_SKIP_COUNT)
- --rli->slave_skip_counter;
+ sql_slave_skip_counter= --rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock);
if (reason == Log_event::EVENT_SKIP_NOT)
exec_res= ev->apply_event(rli);
@@ -2244,7 +2247,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
"skipped because event skip counter was non-zero"
};
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
- thd->options & OPTION_BEGIN ? 1 : 0,
+ test(thd->variables.option_bits & OPTION_BEGIN),
rli->get_flag(Relay_log_info::IN_STMT)));
DBUG_PRINT("skip_event", ("%s event was %s",
ev->get_type_str(), explain[reason]));
@@ -3133,9 +3136,9 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
}
/* execute init_slave variable */
- if (sys_init_slave.value_length)
+ if (opt_init_slave.length)
{
- execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave);
+ execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
if (thd->is_slave_error)
{
rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
diff --git a/sql/slave.h b/sql/slave.h
index 8fb44007032..69290ecac0a 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -115,6 +115,7 @@ extern char *master_info_file, *relay_log_info_file;
extern char *opt_relay_logname, *opt_relaylog_index_name;
extern my_bool opt_skip_slave_start, opt_reckless_slave;
extern my_bool opt_log_slave_updates;
+extern char *opt_slave_skip_errors;
extern ulonglong relay_log_space_limit;
/*
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 3f7d812384c..6e69b2e39a4 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -24,6 +24,7 @@
#include "sp_pcontext.h"
#include "sp_rcontext.h"
#include "sp_cache.h"
+#include "set_var.h"
/*
Sufficient max length of printed destinations and frame offsets (all uints).
@@ -1707,7 +1708,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
each substatement be binlogged its way.
*/
need_binlog_call= mysql_bin_log.is_open() &&
- (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
+ (thd->variables.option_bits & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
/*
Remember the original arguments for unrolled replication of functions
@@ -1770,8 +1771,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
q= global_query_id;
pthread_mutex_unlock(&LOCK_thread_count);
mysql_bin_log.start_union_events(thd, q + 1);
- binlog_save_options= thd->options;
- thd->options&= ~OPTION_BIN_LOG;
+ binlog_save_options= thd->variables.option_bits;
+ thd->variables.option_bits&= ~OPTION_BIN_LOG;
}
/*
@@ -1791,7 +1792,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
if (need_binlog_call)
{
mysql_bin_log.stop_union_events(thd);
- thd->options= binlog_save_options;
+ thd->variables.option_bits= binlog_save_options;
if (thd->binlog_evt_union.unioned_events)
{
int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
@@ -1984,12 +1985,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
save_enable_slow_log= true;
thd->enable_slow_log= FALSE;
}
- if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF))
+ if (!(m_flags & LOG_GENERAL_LOG) && !(thd->variables.option_bits & OPTION_LOG_OFF))
{
DBUG_PRINT("info", ("Disabling general log for the execution"));
save_log_general= true;
/* disable this bit */
- thd->options |= OPTION_LOG_OFF;
+ thd->variables.option_bits |= OPTION_LOG_OFF;
}
thd->spcont= nctx;
@@ -2003,7 +2004,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
err_status= execute(thd);
if (save_log_general)
- thd->options &= ~OPTION_LOG_OFF;
+ thd->variables.option_bits &= ~OPTION_LOG_OFF;
if (save_enable_slow_log)
thd->enable_slow_log= true;
/*
@@ -2441,8 +2442,7 @@ sp_head::show_create_routine(THD *thd, int type)
if (check_show_routine_access(thd, this, &full_access))
DBUG_RETURN(TRUE);
- sys_var_thd_sql_mode::symbolic_mode_representation(
- thd, m_sql_mode, &sql_mode);
+ sql_mode_string_representation(thd, m_sql_mode, &sql_mode);
/* Send header. */
@@ -2881,7 +2881,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
(the order of query cache and subst_spvars calls is irrelevant because
queries with SP vars can't be cached)
*/
- if (unlikely((thd->options & OPTION_LOG_OFF)==0))
+ if (unlikely((thd->variables.option_bits & OPTION_LOG_OFF)==0))
general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
if (query_cache_send_result_to_client(thd,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 05e8cee9151..4cbae0bbb5a 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -31,6 +31,8 @@
#include "sp_head.h"
#include "sp.h"
+bool mysql_user_table_is_in_short_password_format= false;
+
static const
TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT] = {
{
@@ -219,25 +221,6 @@ set_user_salt(ACL_USER *acl_user, const char *password, uint password_len)
}
/*
- This after_update function is used when user.password is less than
- SCRAMBLE_LENGTH bytes.
-*/
-
-static void restrict_update_of_old_passwords_var(THD *thd,
- enum_var_type var_type)
-{
- if (var_type == OPT_GLOBAL)
- {
- pthread_mutex_lock(&LOCK_global_system_variables);
- global_system_variables.old_passwords= 1;
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- thd->variables.old_passwords= 1;
-}
-
-
-/*
Initialize structures responsible for user/db-level privilege checking and
load privilege information for them from tables in the 'mysql' database.
@@ -398,7 +381,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
"but server started with --secure-auth option.");
goto end;
}
- sys_old_passwords.after_update= restrict_update_of_old_passwords_var;
+ mysql_user_table_is_in_short_password_format= true;
if (global_system_variables.old_passwords)
pthread_mutex_unlock(&LOCK_global_system_variables);
else
@@ -413,7 +396,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
}
else
{
- sys_old_passwords.after_update= 0;
+ mysql_user_table_is_in_short_password_format= false;
pthread_mutex_unlock(&LOCK_global_system_variables);
}
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 25a4766e58c..59409299f73 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -169,6 +169,7 @@ enum mysql_db_table_field
};
extern const TABLE_FIELD_DEF mysql_db_table_def;
+extern bool mysql_user_table_is_in_short_password_format;
/* Classes */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9a778e75a11..348f4305b02 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1365,7 +1365,7 @@ void close_thread_tables(THD *thd)
good idea to turn off OPTION_TABLE_LOCK flag.
*/
DBUG_ASSERT(thd->lex->requires_prelocking());
- thd->options&= ~(OPTION_TABLE_LOCK);
+ thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
DBUG_VOID_RETURN;
@@ -1445,7 +1445,7 @@ void close_temporary_tables(THD *thd)
TABLE *table;
TABLE *next= NULL;
TABLE *prev_table;
- /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
+ /* Assume thd->variables.option_bits has OPTION_QUOTE_SHOW_CREATE */
bool was_quote_show= TRUE;
if (!thd->temporary_tables)
@@ -1513,9 +1513,9 @@ void close_temporary_tables(THD *thd)
/* We always quote db,table names though it is slight overkill */
if (found_user_tables &&
- !(was_quote_show= test(thd->options & OPTION_QUOTE_SHOW_CREATE)))
+ !(was_quote_show= test(thd->variables.option_bits & OPTION_QUOTE_SHOW_CREATE)))
{
- thd->options |= OPTION_QUOTE_SHOW_CREATE;
+ thd->variables.option_bits |= OPTION_QUOTE_SHOW_CREATE;
}
/* scan sorted tmps to generate sequence of DROP */
@@ -1572,7 +1572,7 @@ void close_temporary_tables(THD *thd)
}
}
if (!was_quote_show)
- thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
+ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0;
}
@@ -4456,7 +4456,7 @@ bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table)
{
- bool log_on= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ bool log_on= mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG);
ulong binlog_format= thd->variables.binlog_format;
if ((log_on == FALSE) || (binlog_format == BINLOG_FORMAT_ROW) ||
(table->s->table_category == TABLE_CATEGORY_PERFORMANCE))
@@ -5151,7 +5151,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
This check here is needed to prevent some spurious error to be
raised in some cases (See BUG#42829).
*/
- if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
+ if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG) &&
(thd->variables.binlog_format != BINLOG_FORMAT_STMT ||
binlog_filter->db_ok(thd->db)))
{
@@ -5193,7 +5193,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables)
DBUG_PRINT("info", ("flags_some_set: %s%s",
FLAGSTR(flags_some_set, HA_BINLOG_STMT_CAPABLE),
FLAGSTR(flags_some_set, HA_BINLOG_ROW_CAPABLE)));
- DBUG_PRINT("info", ("thd->variables.binlog_format: %ld",
+ DBUG_PRINT("info", ("thd->variables.binlog_format: %u",
thd->variables.binlog_format));
DBUG_PRINT("info", ("multi_engine: %s",
multi_engine ? "TRUE" : "FALSE"));
@@ -5334,7 +5334,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
if (thd->lex->requires_prelocking())
{
thd->in_lock_tables=1;
- thd->options|= OPTION_TABLE_LOCK;
+ thd->variables.option_bits|= OPTION_TABLE_LOCK;
/*
A query that modifies autoinc column in sub-statement can make the
master and slave inconsistent.
@@ -5355,7 +5355,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
{
if (thd->lex->requires_prelocking())
{
- thd->options&= ~(OPTION_TABLE_LOCK);
+ thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
thd->in_lock_tables=0;
}
DBUG_RETURN(-1);
@@ -5398,7 +5398,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
{
mysql_unlock_tables(thd, thd->locked_tables);
thd->locked_tables= 0;
- thd->options&= ~(OPTION_TABLE_LOCK);
+ thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
DBUG_RETURN(-1);
}
}
diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in
index 3becdbaccfe..f8767949fe3 100644
--- a/sql/sql_builtin.cc.in
+++ b/sql/sql_builtin.cc.in
@@ -18,10 +18,16 @@
typedef struct st_mysql_plugin builtin_plugin[];
extern builtin_plugin
- builtin_binlog_plugin@mysql_plugin_defs@;
+ @mysql_mandatory_plugins@ @mysql_optional_plugins@ builtin_binlog_plugin;
-struct st_mysql_plugin *mysqld_builtins[]=
+struct st_mysql_plugin *mysql_optional_plugins[]=
{
- builtin_binlog_plugin@mysql_plugin_defs@,(struct st_mysql_plugin *)0
+ @mysql_optional_plugins@ 0
};
+struct st_mysql_plugin *mysql_mandatory_plugins[]=
+{
+ builtin_binlog_plugin, @mysql_mandatory_plugins@ 0
+};
+
+
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 40316299366..07d36b1551a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -407,13 +407,6 @@ static void debug_wait_for_kill(const char *info)
#define DUMP(C)
#endif
-const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
-TYPELIB query_cache_type_typelib=
-{
- array_elements(query_cache_type_names)-1,"", query_cache_type_names, NULL
-};
-
-
/**
Serialize access to the query cache.
If the lock cannot be granted the thread hangs in a conditional wait which
@@ -1074,12 +1067,12 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
:query_cache_size(0),
query_cache_limit(query_cache_limit_arg),
queries_in_cache(0), hits(0), inserts(0), refused(0),
- total_blocks(0), lowmem_prunes(0),
+ total_blocks(0), lowmem_prunes(0), m_query_cache_is_disabled(FALSE),
min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
def_table_hash_size(ALIGN_SIZE(def_table_hash_size_arg)),
- initialized(0), m_query_cache_is_disabled(FALSE)
+ initialized(0)
{
ulong min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_block_table)) +
@@ -1548,7 +1541,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
DBUG_PRINT("qcache", ("Query have result 0x%lx", (ulong) query));
- if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
(query->tables_type() & HA_CACHE_TBL_TRANSACT))
{
DBUG_PRINT("qcache",
@@ -1706,7 +1699,7 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
for (; tables_used; tables_used= tables_used->next_local)
{
DBUG_ASSERT(!using_transactions || tables_used->table!=0);
@@ -1791,7 +1784,7 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions &&
(table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
thd->add_changed_table(table);
@@ -1810,7 +1803,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions) // used for innodb => has_transactions() is TRUE
thd->add_changed_table(key, key_length);
else
@@ -2159,7 +2152,7 @@ ulong Query_cache::init_cache()
(void) my_hash_init(&queries, &my_charset_bin, def_query_hash_size, 0, 0,
query_cache_query_get_key, 0, 0);
-#ifndef FN_NO_CASE_SENCE
+#ifndef FN_NO_CASE_SENSE
/*
If lower_case_table_names!=0 then db and table names are already
converted to lower case and we can use binary collation for their
@@ -3580,7 +3573,7 @@ Query_cache::is_cacheable(THD *thd, size_t query_len, const char *query,
tables_type)))
DBUG_RETURN(0);
- if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
((*tables_type)&HA_CACHE_TBL_TRANSACT))
{
DBUG_PRINT("qcache", ("not in autocommin mode"));
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 695d6fb4db3..33e535b2580 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -503,5 +503,4 @@ protected:
};
extern Query_cache query_cache;
-extern TYPELIB query_cache_type_typelib;
#endif
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 019c22d9dd2..53a96f8b9d9 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -296,7 +296,7 @@ void **thd_ha_data(const THD *thd, const struct handlerton *hton)
extern "C"
long long thd_test_options(const THD *thd, long long test_options)
{
- return thd->options & test_options;
+ return thd->variables.option_bits & test_options;
}
extern "C"
@@ -684,7 +684,7 @@ void THD::raise_note(uint sql_errno)
{
DBUG_ENTER("THD::raise_note");
DBUG_PRINT("enter", ("code: %d", sql_errno));
- if (!(this->options & OPTION_SQL_NOTES))
+ if (!(variables.option_bits & OPTION_SQL_NOTES))
DBUG_VOID_RETURN;
const char* msg= ER(sql_errno);
(void) raise_condition(sql_errno,
@@ -700,7 +700,7 @@ void THD::raise_note_printf(uint sql_errno, ...)
char ebuff[MYSQL_ERRMSG_SIZE];
DBUG_ENTER("THD::raise_note_printf");
DBUG_PRINT("enter",("code: %u", sql_errno));
- if (!(this->options & OPTION_SQL_NOTES))
+ if (!(variables.option_bits & OPTION_SQL_NOTES))
DBUG_VOID_RETURN;
const char* format= ER(sql_errno);
va_start(args, sql_errno);
@@ -721,7 +721,7 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
MYSQL_ERROR *cond= NULL;
DBUG_ENTER("THD::raise_condition");
- if (!(this->options & OPTION_SQL_NOTES) &&
+ if (!(variables.option_bits & OPTION_SQL_NOTES) &&
(level == MYSQL_ERROR::WARN_LEVEL_NOTE))
DBUG_RETURN(NULL);
@@ -887,12 +887,6 @@ void THD::init(void)
{
pthread_mutex_lock(&LOCK_global_system_variables);
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,
- variables.date_format);
- variables.datetime_format= date_time_format_copy((THD*) 0,
- variables.datetime_format);
/*
variables= global_system_variables above has reset
variables.pseudo_thread_id to 0. We need to correct it here to
@@ -903,12 +897,6 @@ void THD::init(void)
server_status= SERVER_STATUS_AUTOCOMMIT;
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
- options= thd_startup_options;
-
- if (variables.max_join_size == HA_POS_ERROR)
- options |= OPTION_BIG_SELECTS;
- else
- options &= ~OPTION_BIG_SELECTS;
transaction.all.modified_non_trans_table= transaction.stmt.modified_non_trans_table= FALSE;
open_options=ha_open_options;
@@ -919,7 +907,7 @@ void THD::init(void)
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
- sql_log_bin_toplevel= options & OPTION_BIN_LOG;
+ sql_log_bin_toplevel= variables.option_bits & OPTION_BIN_LOG;
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
@@ -1012,10 +1000,6 @@ void THD::cleanup(void)
delete_dynamic(&user_var_events);
my_hash_free(&user_vars);
close_temporary_tables(this);
- my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
-
sp_cache_clear(&sp_proc_cache);
sp_cache_clear(&sp_func_cache);
@@ -1384,15 +1368,21 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
void THD::update_charset()
{
uint32 not_used;
- charset_is_system_charset= !String::needs_conversion(0,charset(),
- system_charset_info,
- &not_used);
+ charset_is_system_charset=
+ !String::needs_conversion(0,
+ variables.character_set_client,
+ system_charset_info,
+ &not_used);
charset_is_collation_connection=
- !String::needs_conversion(0,charset(),variables.collation_connection,
+ !String::needs_conversion(0,
+ variables.character_set_client,
+ variables.collation_connection,
&not_used);
charset_is_character_set_filesystem=
- !String::needs_conversion(0, charset(),
- variables.character_set_filesystem, &not_used);
+ !String::needs_conversion(0,
+ variables.character_set_client,
+ variables.character_set_filesystem,
+ &not_used);
}
@@ -1415,8 +1405,8 @@ void THD::add_changed_table(TABLE *table)
{
DBUG_ENTER("THD::add_changed_table(table)");
- DBUG_ASSERT((options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
- table->file->has_transactions());
+ DBUG_ASSERT(variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ DBUG_ASSERT(table->file->has_transactions());
add_changed_table(table->s->table_cache_key.str,
(long) table->s->table_cache_key.length);
DBUG_VOID_RETURN;
@@ -3100,7 +3090,7 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
extern "C" int thd_binlog_format(const MYSQL_THD thd)
{
- if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+ if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG))
return (int) thd->variables.binlog_format;
else
return BINLOG_FORMAT_UNSPEC;
@@ -3161,7 +3151,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
}
#endif
- backup->options= options;
+ backup->option_bits= variables.option_bits;
backup->in_sub_stmt= in_sub_stmt;
backup->enable_slow_log= enable_slow_log;
backup->limit_found_rows= limit_found_rows;
@@ -3178,10 +3168,10 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
!current_stmt_binlog_row_based)
{
- options&= ~OPTION_BIN_LOG;
+ variables.option_bits&= ~OPTION_BIN_LOG;
}
- if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
+ if ((backup->option_bits & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
!current_stmt_binlog_row_based)
mysql_bin_log.start_union_events(this, this->query_id);
@@ -3225,7 +3215,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
(void)ha_release_savepoint(this, sv);
}
transaction.savepoints= backup->savepoints;
- options= backup->options;
+ variables.option_bits= backup->option_bits;
in_sub_stmt= backup->in_sub_stmt;
enable_slow_log= backup->enable_slow_log;
first_successful_insert_id_in_prev_stmt=
@@ -3243,7 +3233,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
if (!in_sub_stmt)
is_fatal_sub_stmt_error= FALSE;
- if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
+ if ((variables.option_bits & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
!current_stmt_binlog_row_based)
mysql_bin_log.stop_union_events(this);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d3e3f2a48b6..03f06e5aa26 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -309,7 +309,7 @@ class Time_zone;
#define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC)
-struct system_variables
+typedef struct system_variables
{
/*
How dynamically allocated system variables are handled:
@@ -326,10 +326,12 @@ struct system_variables
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;
ulonglong tmp_table_size;
ulonglong long_query_time;
+ ulonglong optimizer_switch;
+ ulonglong sql_mode; ///< which non-standard SQL behaviour should be enabled
+ ulonglong option_bits; ///< OPTION_xxx constants, e.g. OPTION_PROFILING
ha_rows select_limit;
ha_rows max_join_size;
ulong auto_increment_increment, auto_increment_offset;
@@ -343,9 +345,6 @@ struct system_variables
ulong max_insert_delayed_threads;
ulong min_examined_row_limit;
ulong multi_range_count;
- ulong myisam_repair_threads;
- ulong myisam_sort_buff_size;
- ulong myisam_stats_method;
ulong net_buffer_length;
ulong net_interactive_timeout;
ulong net_read_timeout;
@@ -354,23 +353,13 @@ struct system_variables
ulong net_write_timeout;
ulong optimizer_prune_level;
ulong optimizer_search_depth;
- /* A bitmap for switching optimizations on/off */
- ulong optimizer_switch;
ulong preload_buff_size;
ulong profiling_history_size;
- ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
ulong div_precincrement;
ulong sortbuff_size;
- ulong thread_handling;
- ulong tx_isolation;
- ulong completion_type;
- /* Determines which non-standard SQL behaviour should be enabled */
- ulong sql_mode;
ulong max_sp_recursion_depth;
- /* check of key presence in updatable view */
- ulong updatable_views_with_limit;
ulong default_week_format;
ulong max_seeks_for_key;
ulong range_alloc_block_size;
@@ -380,11 +369,14 @@ struct system_variables
ulong trans_prealloc_size;
ulong log_warnings;
ulong group_concat_max_len;
- ulong ndb_autoincrement_prefetch_sz;
- ulong ndb_index_stat_cache_entries;
- ulong ndb_index_stat_update_freq;
- ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
- /*
+
+ uint binlog_format; ///< binlog format for this thd (see enum_binlog_format)
+ uint completion_type;
+ uint query_cache_type;
+ uint tx_isolation;
+ uint updatable_views_with_limit;
+ uint max_user_connections;
+ /**
In slave thread we need to know in behalf of which
thread the query is being run to replicate temp tables properly
*/
@@ -392,22 +384,13 @@ struct system_variables
my_bool low_priority_updates;
my_bool new_mode;
- /*
- compatibility option:
- - index usage hints (USE INDEX without a FOR clause) behave as in 5.0
- */
- my_bool old_mode;
my_bool query_cache_wlock_invalidate;
my_bool engine_condition_pushdown;
my_bool keep_files_on_create;
- my_bool ndb_force_send;
- my_bool ndb_use_copying_alter_table;
- my_bool ndb_use_exact_count;
- my_bool ndb_use_transactions;
- my_bool ndb_index_stat_enable;
my_bool old_alter_table;
my_bool old_passwords;
+ my_bool big_tables;
plugin_ref table_plugin;
@@ -428,12 +411,10 @@ struct system_variables
Time_zone *time_zone;
- /* DATE, DATETIME and MYSQL_TIME formats */
- DATE_TIME_FORMAT *date_format;
- DATE_TIME_FORMAT *datetime_format;
- DATE_TIME_FORMAT *time_format;
my_bool sysdate_is_now;
-};
+
+ double long_query_time_double;
+} SV;
/* per thread status variables */
@@ -1015,7 +996,7 @@ public:
class Sub_statement_state
{
public:
- ulonglong options;
+ ulonglong option_bits;
ulonglong first_successful_insert_id_in_prev_stmt;
ulonglong first_successful_insert_id_in_cur_stmt, insert_id_for_cur_row;
Discrete_interval auto_inc_interval_for_cur_row;
@@ -1307,7 +1288,6 @@ public:
*/
const char *where;
- double tmp_double_value; /* Used in set_var.cc */
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@@ -1618,7 +1598,6 @@ public:
}
ulonglong limit_found_rows;
- ulonglong options; /* Bitmap of states */
longlong row_count_func; /* For the ROW_COUNT() function */
ha_rows cuted_fields;
@@ -2371,10 +2350,10 @@ my_eof(THD *thd)
}
#define tmp_disable_binlog(A) \
- {ulonglong tmp_disable_binlog__save_options= (A)->options; \
- (A)->options&= ~OPTION_BIN_LOG
+ {ulonglong tmp_disable_binlog__save_options= (A)->variables.option_bits; \
+ (A)->variables.option_bits&= ~OPTION_BIN_LOG
-#define reenable_binlog(A) (A)->options= tmp_disable_binlog__save_options;}
+#define reenable_binlog(A) (A)->variables.option_bits= tmp_disable_binlog__save_options;}
/*
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 8ecafce6f93..a966d4a6bd4 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -121,8 +121,9 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
DBUG_ENTER("check_for_max_user_connections");
(void) pthread_mutex_lock(&LOCK_user_conn);
- if (max_user_connections && !uc->user_resources.user_conn &&
- max_user_connections < (uint) uc->connections)
+ if (global_system_variables.max_user_connections &&
+ !uc->user_resources.user_conn &&
+ global_system_variables.max_user_connections < (uint) uc->connections)
{
my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
error=1;
@@ -443,7 +444,7 @@ check_user(THD *thd, enum enum_server_command command,
/* Don't allow user to connect if he has done too many queries */
if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
- max_user_connections) &&
+ global_system_variables.max_user_connections) &&
get_or_create_user_conn(thd,
(opt_old_style_user_limits ? thd->main_security_ctx.user :
thd->main_security_ctx.priv_user),
@@ -457,7 +458,7 @@ check_user(THD *thd, enum enum_server_command command,
if (thd->user_connect &&
(thd->user_connect->user_resources.conn_per_hour ||
thd->user_connect->user_resources.user_conn ||
- max_user_connections) &&
+ global_system_variables.max_user_connections) &&
check_for_max_user_connections(thd, thd->user_connect))
{
/* The error is set in check_for_max_user_connections(). */
@@ -1052,8 +1053,6 @@ static void prepare_new_connection_state(THD* thd)
netware_reg_user(sctx->ip, sctx->user, "MySQL");
#endif
- if (thd->variables.max_join_size == HA_POS_ERROR)
- thd->options |= OPTION_BIG_SELECTS;
if (thd->client_capabilities & CLIENT_COMPRESS)
thd->net.compress=1; // Use compression
@@ -1068,9 +1067,9 @@ static void prepare_new_connection_state(THD* thd)
thd->set_time();
thd->init_for_queries();
- if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
+ if (opt_init_connect.length && !(sctx->master_access & SUPER_ACL))
{
- execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
+ execute_init_command(thd, &opt_init_connect, &LOCK_sys_init_connect);
if (thd->is_error())
{
thd->killed= THD::KILL_CONNECTION;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 533b47e61da..66c4460c1cd 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -721,7 +721,7 @@ bool Select_materialize::send_result_set_metadata(List<Item> &list, uint flags)
{
DBUG_ASSERT(table == 0);
if (create_result_table(unit->thd, unit->get_unit_column_types(),
- FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, ""))
+ FALSE, thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS, ""))
return TRUE;
materialized_cursor= new (&table->mem_root)
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index ab898950a1d..086aacb495e 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -92,7 +92,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
const_cond= (!conds || conds->const_item());
- safe_update=test(thd->options & OPTION_SAFE_UPDATES);
+ safe_update=test(thd->variables.option_bits & OPTION_SAFE_UPDATES);
if (safe_update && const_cond)
{
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
@@ -631,7 +631,7 @@ multi_delete::initialize_tables(JOIN *join)
Unique **tempfiles_ptr;
DBUG_ENTER("initialize_tables");
- if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
+ if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join))
DBUG_RETURN(1);
table_map tables_to_delete_from=0;
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 9b747759ece..24088872471 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -154,7 +154,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
if ((res= check_duplicate_names(unit->types, 0)))
goto exit;
- create_options= (first_select->options | thd->options |
+ create_options= (first_select->options | thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS);
/*
Temp table is created so that it hounours if UNION without ALL is to be
@@ -289,7 +289,7 @@ bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
(ORDER *) first_select->order_list.first,
(ORDER *) first_select->group_list.first,
first_select->having, (ORDER*) NULL,
- (first_select->options | thd->options |
+ (first_select->options | thd->variables.option_bits |
SELECT_NO_UNLOCK),
derived_result, unit, first_select);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 147e03ddf55..c774cb4f3ad 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -455,7 +455,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
return;
}
- bool log_on= (thd->options & OPTION_BIN_LOG ||
+ bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG ||
! (thd->security_ctx->master_access & SUPER_ACL));
if (global_system_variables.binlog_format == BINLOG_FORMAT_STMT &&
log_on && mysql_bin_log.is_open() && is_multi_insert)
@@ -607,7 +607,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
By default, both logs are enabled (this won't cause problems if the server
runs without --log-update or --log-bin).
*/
- bool log_on= ((thd->options & OPTION_BIN_LOG) ||
+ bool log_on= ((thd->variables.option_bits & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL)));
#endif
thr_lock_type lock_type;
@@ -976,7 +976,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (error)
goto abort;
- if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) ||
+ if (values_list.elements == 1 && (!(thd->variables.option_bits & OPTION_WARNINGS) ||
!thd->cuted_fields))
{
thd->row_count_func= info.copied + info.deleted +
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e80d9dfcb3f..27f099ef9ef 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -33,15 +33,23 @@ class sp_pcontext;
class st_alter_tablespace;
class partition_info;
class Event_parse_data;
+class set_var_base;
+class sys_var;
+
+/**
+ used by the parser to store internal variable name
+*/
+struct sys_var_with_base
+{
+ sys_var *var;
+ LEX_STRING base_name;
+};
#ifdef MYSQL_SERVER
/*
The following hack is needed because mysql_yacc.cc does not define
YYSTYPE before including this file
*/
-
-#include "set_var.h"
-
#ifdef MYSQL_YACC
#define LEX_YYSTYPE void *
#else
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0774e373908..63a8c17e145 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -30,6 +30,7 @@
#include "sql_trigger.h"
#include "sql_prepare.h"
#include "probes_mysql.h"
+#include "set_var.h"
/**
@defgroup Runtime_Environment Runtime Environment
@@ -134,7 +135,7 @@ static bool xa_trans_rollback(THD *thd)
bool status= test(ha_rollback(thd));
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->variables.option_bits&= ~(ulong) OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
@@ -169,18 +170,18 @@ bool end_active_trans(THD *thd)
xa_state_names[thd->transaction.xid_state.xa_state]);
DBUG_RETURN(1);
}
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
+ if (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
- DBUG_PRINT("info",("options: 0x%llx", thd->options));
+ DBUG_PRINT("info",("options: 0x%llx", thd->variables.option_bits));
/* Safety if one did "drop table" on locked tables */
if (!thd->locked_tables)
- thd->options&= ~OPTION_TABLE_LOCK;
+ thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
}
- thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
+ thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
DBUG_RETURN(error);
}
@@ -204,7 +205,7 @@ bool begin_trans(THD *thd)
error= -1;
else
{
- thd->options|= OPTION_BEGIN;
+ thd->variables.option_bits|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
}
return error;
@@ -374,25 +375,34 @@ bool is_log_table_write_query(enum enum_sql_command command)
return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
}
-void execute_init_command(THD *thd, sys_var_str *init_command_var,
- rw_lock_t *var_mutex)
+void execute_init_command(THD *thd, LEX_STRING *init_command,
+ rw_lock_t *var_lock)
{
Vio* save_vio;
ulong save_client_capabilities;
+ rw_rdlock(var_lock);
+ if (!init_command->length)
+ {
+ rw_unlock(var_lock);
+ return;
+ }
+
+ /*
+ copy the value under a lock, and release the lock.
+ init_command has to be executed without a lock held,
+ as it may try to change itself
+ */
+ size_t len= init_command->length;
+ char *buf= thd->strmake(init_command->str, len);
+ rw_unlock(var_lock);
+
#if defined(ENABLED_PROFILING)
thd->profiling.start_new_query();
- thd->profiling.set_query_source(init_command_var->value,
- init_command_var->value_length);
+ thd->profiling.set_query_source(buf, len);
#endif
thd_proc_info(thd, "Execution of init_command");
- /*
- We need to lock init_command_var because
- during execution of init_command_var query
- values of init_command_var can't be changed
- */
- rw_rdlock(var_mutex);
save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
/*
@@ -401,10 +411,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
*/
save_vio= thd->net.vio;
thd->net.vio= 0;
- dispatch_command(COM_QUERY, thd,
- init_command_var->value,
- init_command_var->value_length);
- rw_unlock(var_mutex);
+ dispatch_command(COM_QUERY, thd, buf, len);
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
@@ -427,9 +434,6 @@ static void handle_bootstrap_impl(THD *thd)
thd->thread_stack= (char*) &thd;
#endif /* EMBEDDED_LIBRARY */
- if (thd->variables.max_join_size == HA_POS_ERROR)
- thd->options |= OPTION_BIG_SELECTS;
-
thd_proc_info(thd, 0);
thd->version=refresh_version;
thd->security_ctx->priv_user=
@@ -657,7 +661,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
*/
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
res= ha_commit(thd);
- thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
+ thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
break;
case COMMIT_RELEASE:
@@ -675,7 +679,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_rollback(thd))
res= -1;
- thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
+ thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd);
@@ -728,7 +732,7 @@ bool do_command(THD *thd)
This thread will do a blocking read from the client which
will be interrupted when the next command is received from
the client, the connection is closed or "net_wait_timeout"
- number of seconds has passed
+ number of seconds has passed.
*/
my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
@@ -1847,8 +1851,6 @@ bool sp_process_definer(THD *thd)
TODO: this is workaround. right way will be move invalidating in
the unlock procedure.
- TODO: use check_change_password()
- - JOIN is not supported yet. TODO
- - SUSPEND and FOR MIGRATE are not supported yet. TODO
@retval
FALSE OK
@@ -2541,7 +2543,7 @@ case SQLCOM_PREPARE:
{
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
- thd->options|= OPTION_KEEP_LOG;
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
/* regular create */
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
res= mysql_create_like_table(thd, create_table, select_tables,
@@ -3262,7 +3264,7 @@ end_with_restore_list:
select_lex->where,
0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
(ORDER *)NULL,
- select_lex->options | thd->options |
+ select_lex->options | thd->variables.option_bits |
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
del_result, unit, select_lex);
@@ -3303,7 +3305,7 @@ end_with_restore_list:
lex->drop_if_exists= 1;
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
- thd->options|= OPTION_KEEP_LOG;
+ thd->variables.option_bits|= OPTION_KEEP_LOG;
}
/* DDL and binlog write order protected by LOCK_open */
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
@@ -3392,11 +3394,6 @@ end_with_restore_list:
if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, all_tables)))
goto error;
- if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
- {
- my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
- goto error;
- }
if (!(res= sql_set_variables(thd, lex_var_list)))
{
/*
@@ -3429,10 +3426,10 @@ end_with_restore_list:
false, mysqldump will not work.
*/
unlock_locked_tables(thd);
- if (thd->options & OPTION_TABLE_LOCK)
+ if (thd->variables.option_bits & OPTION_TABLE_LOCK)
{
end_active_trans(thd);
- thd->options&= ~(OPTION_TABLE_LOCK);
+ thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
}
if (thd->global_read_lock)
unlock_global_read_lock(thd);
@@ -3450,7 +3447,7 @@ end_with_restore_list:
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
goto error;
thd->in_lock_tables=1;
- thd->options|= OPTION_TABLE_LOCK;
+ thd->variables.option_bits |= OPTION_TABLE_LOCK;
if (!(res= simple_open_n_lock_tables(thd, all_tables)))
{
@@ -3471,7 +3468,6 @@ end_with_restore_list:
*/
ha_autocommit_or_rollback(thd, 1);
end_active_trans(thd);
- thd->options&= ~(OPTION_TABLE_LOCK);
}
thd->in_lock_tables=0;
break;
@@ -4037,7 +4033,7 @@ end_with_restore_list:
res= TRUE; // cannot happen
else
{
- if (((thd->options & OPTION_KEEP_LOG) ||
+ if (((thd->variables.option_bits & OPTION_KEEP_LOG) ||
thd->transaction.all.modified_non_trans_table) &&
!thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -4052,7 +4048,7 @@ end_with_restore_list:
break;
}
case SQLCOM_SAVEPOINT:
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+ if (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
thd->in_sub_stmt) || !opt_using_transactions)
my_ok(thd);
else
@@ -4609,7 +4605,7 @@ create_sp_error:
break;
}
if (thd->lex->xa_opt != XA_NONE)
- { // JOIN is not supported yet. TODO
+ { /// @todo JOIN is not supported yet.
my_error(ER_XAER_INVAL, MYF(0));
break;
}
@@ -4635,14 +4631,14 @@ create_sp_error:
thd->transaction.xid_state.xid.set(thd->lex->xid);
xid_cache_insert(&thd->transaction.xid_state);
thd->transaction.all.modified_non_trans_table= FALSE;
- thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
+ thd->variables.option_bits= ((thd->variables.option_bits & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
my_ok(thd);
break;
case SQLCOM_XA_END:
/* fake it */
if (thd->lex->xa_opt != XA_NONE)
- { // SUSPEND and FOR MIGRATE are not supported yet. TODO
+ { /// @todo SUSPEND and FOR MIGRATE are not supported yet.
my_error(ER_XAER_INVAL, MYF(0));
break;
}
@@ -4741,7 +4737,7 @@ create_sp_error:
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
- thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
+ thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
@@ -5470,7 +5466,7 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name,
0, no_errors, 0))
return TRUE;
- return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
+ return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
}
@@ -5694,9 +5690,9 @@ void mysql_reset_thd_for_next_command(THD *thd)
OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
in ha_rollback_trans() about some tables couldn't be rolled back.
*/
- if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ if (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
- thd->options&= ~OPTION_KEEP_LOG;
+ thd->variables.option_bits&= ~OPTION_KEEP_LOG;
thd->transaction.all.modified_non_trans_table= FALSE;
}
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
@@ -7305,7 +7301,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
}
thd->lex->query_tables_own_last= save_query_tables_own_last;
- if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
+ if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && !select_lex->where)
{
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index b6112e51565..a5ae5d24796 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1977,11 +1977,11 @@ static int add_part_field_list(File fptr, List<char> field_list)
const char *field_str= part_it++;
String field_string("", 0, system_charset_info);
THD *thd= current_thd;
- ulonglong save_options= thd->options;
- thd->options= 0;
+ ulonglong save_options= thd->variables.option_bits;
+ thd->variables.option_bits= 0;
append_identifier(thd, &field_string, field_str,
strlen(field_str));
- thd->options= save_options;
+ thd->variables.option_bits= save_options;
err+= add_string_object(fptr, &field_string);
if (i != (num_fields-1))
err+= add_comma(fptr);
@@ -1996,12 +1996,12 @@ static int add_name_string(File fptr, const char *name)
int err;
String name_string("", 0, system_charset_info);
THD *thd= current_thd;
- ulonglong save_options= thd->options;
+ ulonglong save_options= thd->variables.option_bits;
- thd->options= 0;
+ thd->variables.option_bits= 0;
append_identifier(thd, &name_string, name,
strlen(name));
- thd->options= save_options;
+ thd->variables.option_bits= save_options;
err= add_string_object(fptr, &name_string);
return err;
}
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 4d60caf2931..953f0b3c680 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -13,13 +13,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "mysql_priv.h"
+#include "sys_vars_shared.h"
#include <my_pthread.h>
#include <my_getopt.h>
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-extern struct st_mysql_plugin *mysqld_builtins[];
+extern struct st_mysql_plugin *mysql_optional_plugins[];
+extern struct st_mysql_plugin *mysql_mandatory_plugins[];
/**
@note The order of the enumeration is critical.
@@ -164,6 +165,8 @@ struct st_mysql_sys_var
MYSQL_PLUGIN_VAR_HEADER;
};
+static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var);
+
/*
sys_var class for access to all plugin variables visible to the user
@@ -173,28 +176,44 @@ class sys_var_pluginvar: public sys_var
public:
struct st_plugin_int *plugin;
struct st_mysql_sys_var *plugin_var;
+ /**
+ variable name from whatever is hard-coded in the plugin source
+ and doesn't have pluginname- prefix is replaced by an allocated name
+ with a plugin prefix. When plugin is uninstalled we need to restore the
+ pointer to point to the hard-coded value, because plugin may be
+ installed/uninstalled many times without reloading the shared object.
+ */
+ const char *orig_pluginvar_name;
static void *operator new(size_t size, MEM_ROOT *mem_root)
- { return (void*) alloc_root(mem_root, (uint) size); }
+ { return (void*) alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg,size_t size)
{ TRASH(ptr_arg, size); }
- sys_var_pluginvar(const char *name_arg,
+ sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
struct st_mysql_sys_var *plugin_var_arg)
- :sys_var(name_arg), plugin_var(plugin_var_arg) {}
+ :sys_var(chain, name_arg, plugin_var_arg->comment,
+ (plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) |
+ (plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0),
+ 0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0,
+ VARIABLE_NOT_IN_BINLOG, 0, 0, 0, 0),
+ plugin_var(plugin_var_arg), orig_pluginvar_name(plugin_var_arg->name)
+ { plugin_var->name= name_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();
uchar* real_value_ptr(THD *thd, enum_var_type type);
TYPELIB* plugin_var_typelib(void);
- uchar* value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- bool check(THD *thd, set_var *var);
- bool check_default(enum_var_type type) { return is_readonly(); }
- void set_default(THD *thd, enum_var_type type);
- bool update(THD *thd, set_var *var);
+ uchar* do_value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ uchar* session_value_ptr(THD *thd, LEX_STRING *base)
+ { return do_value_ptr(thd, OPT_SESSION, base); }
+ uchar* global_value_ptr(THD *thd, LEX_STRING *base)
+ { return do_value_ptr(thd, OPT_GLOBAL, base); }
+ bool do_check(THD *thd, set_var *var);
+ virtual void session_save_default(THD *thd, set_var *var) {}
+ virtual void global_save_default(THD *thd, set_var *var) {}
+ bool session_update(THD *thd, set_var *var);
+ bool global_update(THD *thd, set_var *var);
};
@@ -209,8 +228,9 @@ static bool register_builtin(struct st_mysql_plugin *, 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_vars_free_values(sys_var *vars);
-static void plugin_opt_set_limits(struct my_option *options,
- const struct st_mysql_sys_var *opt);
+static void restore_pluginvar_names(sys_var *first);
+static void plugin_opt_set_limits(struct my_option *,
+ const struct st_mysql_sys_var *);
#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
@@ -218,12 +238,6 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin
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);
-extern bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
- const char *name, longlong val);
-
#ifdef EMBEDDED_LIBRARY
/* declared in sql_base.cc */
extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
@@ -289,6 +303,11 @@ static int item_val_int(struct st_mysql_value *value, long long *buf)
return 0;
}
+static int item_is_unsigned(struct st_mysql_value *value)
+{
+ Item *item= ((st_item_value_holder*)value)->item;
+ return item->unsigned_flag;
+}
static int item_val_real(struct st_mysql_value *value, double *buf)
{
@@ -617,10 +636,10 @@ bool plugin_is_ready(const LEX_STRING *name, int type)
}
-SHOW_COMP_OPTION sys_var_have_plugin::get_option()
+SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type)
{
- LEX_STRING plugin_name= { (char *) plugin_name_str, plugin_name_len };
- return plugin_status(&plugin_name, plugin_type);
+ LEX_STRING plugin_name= { (char *) name, len };
+ return plugin_status(&plugin_name, type);
}
@@ -776,6 +795,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
tmp_plugin_ptr->state= PLUGIN_IS_FREED;
}
mysql_del_sys_var_chain(tmp.system_vars);
+ restore_pluginvar_names(tmp.system_vars);
goto err;
/* plugin was disabled */
@@ -802,12 +822,12 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
if (plugin->plugin->status_vars)
{
#ifdef FIX_LATER
- /*
- We have a problem right now where we can not prepend without
- breaking backwards compatibility. We will fix this shortly so
- that engines have "use names" and we wil use those for
- CREATE TABLE, and use the plugin name then for adding automatic
- variable names.
+ /**
+ @todo
+ unfortunately, status variables were introduced without a
+ pluginname_ namespace, that is pluginname_ was not added automatically
+ to status variable names. It should be fixed together with the next
+ incompatible API change.
*/
SHOW_VAR array[2]= {
{plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY},
@@ -847,21 +867,21 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check)
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);
/* Free allocated strings before deleting the plugin. */
+ rw_wrlock(&LOCK_system_variables_hash);
+ mysql_del_sys_var_chain(plugin->system_vars);
+ rw_unlock(&LOCK_system_variables_hash);
+ restore_pluginvar_names(plugin->system_vars);
plugin_vars_free_values(plugin->system_vars);
my_hash_delete(&plugin_hash[plugin->plugin->type], (uchar*)plugin);
if (plugin->plugin_dl)
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;
}
@@ -1002,6 +1022,7 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
static int plugin_initialize(struct st_plugin_int *plugin)
{
+ int ret= 1;
DBUG_ENTER("plugin_initialize");
safe_mutex_assert_owner(&LOCK_plugin);
@@ -1063,9 +1084,15 @@ static int plugin_initialize(struct st_plugin_int *plugin)
}
}
- DBUG_RETURN(0);
+ ret= 0;
+
err:
- DBUG_RETURN(1);
+ /* maintain the obsolete @@have_innodb variable */
+ if (!my_strcasecmp(&my_charset_latin1, plugin->name.str, "InnoDB"))
+ have_innodb= plugin->state & PLUGIN_IS_READY ? SHOW_OPTION_YES
+ : SHOW_OPTION_DISABLED;
+
+ DBUG_RETURN(ret);
}
@@ -1120,7 +1147,8 @@ int plugin_init(int *argc, char **argv, int flags)
struct st_mysql_plugin *plugin;
struct st_plugin_int tmp, *plugin_ptr, **reap;
MEM_ROOT tmp_root;
- bool reaped_mandatory_plugin= FALSE;
+ bool reaped_mandatory_plugin= false;
+ bool mandatory= true;
DBUG_ENTER("plugin_init");
if (initialized)
@@ -1156,8 +1184,15 @@ int plugin_init(int *argc, char **argv, int flags)
/*
First we register builtin plugins
*/
- for (builtins= mysqld_builtins; *builtins; builtins++)
+ for (builtins= mysql_mandatory_plugins; *builtins || mandatory; builtins++)
{
+ if (!*builtins)
+ {
+ builtins= mysql_optional_plugins;
+ mandatory= false;
+ if (!*builtins)
+ break;
+ }
for (plugin= *builtins; plugin->info; plugin++)
{
if (opt_ignore_builtin_innodb &&
@@ -1169,6 +1204,7 @@ int plugin_init(int *argc, char **argv, int flags)
tmp.name.str= (char *)plugin->name;
tmp.name.length= strlen(plugin->name);
tmp.state= 0;
+ tmp.is_mandatory= mandatory;
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (test_plugin_options(&tmp_root, &tmp, argc, argv))
tmp.state= PLUGIN_IS_DISABLED;
@@ -1183,7 +1219,7 @@ int plugin_init(int *argc, char **argv, int flags)
my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
continue;
- if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
+ if (plugin_ptr->state != PLUGIN_IS_UNINITIALIZED ||
plugin_initialize(plugin_ptr))
goto err_unlock;
@@ -1292,7 +1328,6 @@ static bool register_builtin(struct st_mysql_plugin *plugin,
DBUG_RETURN(0);
}
-
#ifdef NOT_USED_YET
/*
Register a plugin at run time. (note, this doesn't initialize a plugin)
@@ -1325,7 +1360,10 @@ bool plugin_register_builtin(THD *thd, struct st_mysql_plugin *plugin)
goto end;
tmp.state= PLUGIN_IS_UNINITIALIZED;
if ((result= register_builtin(plugin, &tmp, &ptr)))
+ {
mysql_del_sys_var_chain(tmp.system_vars);
+ restore_pluginvar_names(tmp.system_vars);
+ }
end:
rw_unlock(&LOCK_system_variables_hash);
@@ -1900,7 +1938,7 @@ 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;
+ const char *str;
int result, length;
long long tmp;
@@ -1909,28 +1947,19 @@ static int check_func_bool(THD *thd, struct st_mysql_sys_var *var,
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;
}
*(my_bool *) save= -result;
return 0;
err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
return 1;
}
@@ -1938,60 +1967,87 @@ err:
static int check_func_int(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(uint *)save= (uint) getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(int *)save= (int) getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_long(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(ulong *)save= (ulong) getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(long *)save= (long) getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
- my_bool fixed;
- long long tmp;
+ my_bool fixed1, fixed2;
+ long long orig, val;
struct my_option options;
- value->val_int(value, &tmp);
+ value->val_int(value, &orig);
+ val= orig;
plugin_opt_set_limits(&options, var);
if (var->flags & PLUGIN_VAR_UNSIGNED)
- *(ulonglong *)save= getopt_ull_limit_value((ulonglong) tmp, &options,
- &fixed);
+ {
+ if ((fixed1= (!value->is_unsigned(value) && val < 0)))
+ val=0;
+ *(ulonglong *)save= getopt_ull_limit_value((ulonglong) val, &options,
+ &fixed2);
+ }
else
- *(longlong *)save= getopt_ll_limit_value(tmp, &options, &fixed);
+ {
+ if ((fixed1= (value->is_unsigned(value) && val < 0)))
+ val=LONGLONG_MAX;
+ *(longlong *)save= getopt_ll_limit_value(val, &options, &fixed2);
+ }
- return throw_bounds_warning(thd, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
- var->name, (longlong) tmp);
+ return throw_bounds_warning(thd, var->name, fixed1 || fixed2,
+ value->is_unsigned(value), (longlong) orig);
}
static int check_func_str(THD *thd, struct st_mysql_sys_var *var,
@@ -2013,7 +2069,7 @@ 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;
+ const char *str;
TYPELIB *typelib;
long long tmp;
long result;
@@ -2029,28 +2085,20 @@ static int check_func_enum(THD *thd, struct st_mysql_sys_var *var,
length= sizeof(buff);
if (!(str= value->val_str(value, buff, &length)))
goto err;
- if ((result= (long)find_type(typelib, str, length, 1)-1) < 0)
- {
- strvalue= str;
+ if ((result= (long)find_type(typelib, str, length, 0) - 1) < 0)
goto err;
- }
}
else
{
if (value->val_int(value, &tmp))
goto err;
- if (tmp >= typelib->count)
- {
- llstr(tmp, buff);
- strvalue= buff;
+ if (tmp < 0 || tmp >= typelib->count)
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;
}
@@ -2059,7 +2107,7 @@ 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;
+ const char *str;
TYPELIB *typelib;
ulonglong result;
uint error_len= 0; // init as only set on error
@@ -2079,11 +2127,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
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
{
@@ -2091,16 +2135,11 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
goto err;
if (unlikely((result >= (ULL(1) << typelib->count)) &&
(typelib->count < sizeof(long)*8)))
- {
- llstr(result, buff);
- strvalue= buff;
goto err;
- }
}
*(ulonglong*)save= result;
return 0;
err:
- my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
return 1;
}
@@ -2160,7 +2199,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
pthread_mutex_lock(&LOCK_plugin);
rw_rdlock(&LOCK_system_variables_hash);
- if ((var= intern_find_sys_var(str, length, false)) &&
+ if ((var= intern_find_sys_var(str, length)) &&
(pi= var->cast_pluginvar()))
{
rw_unlock(&LOCK_system_variables_hash);
@@ -2183,7 +2222,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
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)
+ if (!var)
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
DBUG_RETURN(var);
}
@@ -2333,6 +2372,15 @@ static st_bookmark *register_var(const char *plugin, const char *name,
return result;
}
+static void restore_pluginvar_names(sys_var *first)
+{
+ for (sys_var *var= first; var; var= var->next)
+ {
+ sys_var_pluginvar *pv= var->cast_pluginvar();
+ pv->plugin_var->name= pv->orig_pluginvar_name;
+ }
+}
+
/*
returns a pointer to the memory which holds the thd-local variable or
@@ -2386,7 +2434,7 @@ static uchar *intern_sys_var_ptr(THD* thd, int offset, bool global_lock)
st_bookmark *v= (st_bookmark*) my_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)) ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pi= var->cast_pluginvar()) ||
v->key[0] != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
continue;
@@ -2479,7 +2527,7 @@ static void cleanup_variables(THD *thd, struct system_variables *vars)
{
v= (st_bookmark*) my_hash_element(&bookmark_hash, idx);
if (v->version > vars->dynamic_variables_version ||
- !(var= intern_find_sys_var(v->key + 1, v->name_len, true)) ||
+ !(var= intern_find_sys_var(v->key + 1, v->name_len)) ||
!(pivar= var->cast_pluginvar()) ||
v->key[0] != (pivar->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
continue;
@@ -2558,7 +2606,7 @@ static void plugin_vars_free_values(sys_var *vars)
/* Free the string from global_system_variables. */
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
DBUG_PRINT("plugin", ("freeing value for: '%s' addr: 0x%lx",
- var->name, (long) valptr));
+ var->name.str, (long) valptr));
my_free(*valptr, MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
*valptr= NULL;
}
@@ -2566,43 +2614,44 @@ static void plugin_vars_free_values(sys_var *vars)
DBUG_VOID_RETURN;
}
-
-bool sys_var_pluginvar::check_update_type(Item_result type)
+static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var)
{
- if (is_readonly())
- return 1;
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 type != INT_RESULT;
+ return SHOW_LONGLONG;
case PLUGIN_VAR_STR:
- return type != STRING_RESULT;
+ return SHOW_CHAR_PTR;
+ case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_SET:
+ return SHOW_CHAR;
default:
- return 0;
+ DBUG_ASSERT(0);
+ return SHOW_UNDEF;
}
}
-SHOW_TYPE sys_var_pluginvar::show_type()
+bool sys_var_pluginvar::check_update_type(Item_result 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;
+ return type != INT_RESULT;
case PLUGIN_VAR_STR:
- return SHOW_CHAR_PTR;
+ return type != STRING_RESULT;
case PLUGIN_VAR_ENUM:
+ case PLUGIN_VAR_BOOL:
case PLUGIN_VAR_SET:
- return SHOW_CHAR;
+ return type != STRING_RESULT && type != INT_RESULT;
default:
- DBUG_ASSERT(0);
- return SHOW_UNDEF;
+ return true;
}
}
@@ -2639,8 +2688,8 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
}
-uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
+uchar* sys_var_pluginvar::do_value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
{
uchar* result;
@@ -2649,139 +2698,104 @@ uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
if ((plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_ENUM)
result= (uchar*) 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();
- ulonglong mask= 1, value= *(ulonglong*) 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
- ? typelib->type_lengths[i]
- : strlen(typelib->type_names[i]));
- str.append(',');
- }
-
- result= (uchar*) "";
- if (str.length())
- result= (uchar*) thd->strmake(str.ptr(), str.length()-1);
- }
+ result= (uchar*) set_to_string(thd, 0, *(ulonglong*) result,
+ plugin_var_typelib()->type_names);
return result;
}
-
-bool sys_var_pluginvar::check(THD *thd, set_var *var)
+bool sys_var_pluginvar::do_check(THD *thd, set_var *var)
{
st_item_value_holder value;
- DBUG_ASSERT(is_readonly() || plugin_var->check);
+ DBUG_ASSERT(!is_readonly());
+ DBUG_ASSERT(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.is_unsigned= item_is_unsigned;
value.item= var->value;
- return is_readonly() ||
- plugin_var->check(thd, plugin_var, &var->save_result, &value);
+ return plugin_var->check(thd, plugin_var, &var->save_result, &value);
}
-
-void sys_var_pluginvar::set_default(THD *thd, enum_var_type type)
+bool sys_var_pluginvar::session_update(THD *thd, set_var *var)
{
- const void *src;
- void *tgt;
-
- DBUG_ASSERT(is_readonly() || plugin_var->update);
-
- if (is_readonly())
- return;
+ DBUG_ASSERT(!is_readonly());
+ DBUG_ASSERT(plugin_var->flags & PLUGIN_VAR_THDLOCAL);
+ DBUG_ASSERT(thd == current_thd);
pthread_mutex_lock(&LOCK_global_system_variables);
- tgt= real_value_ptr(thd, type);
- src= ((void **) (plugin_var + 1) + 1);
+ void *tgt= real_value_ptr(thd, var->type);
+ const void *src= var->value ? (void*)&var->save_result
+ : (void*)real_value_ptr(thd, OPT_GLOBAL);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ plugin_var->update(thd, plugin_var, tgt, src);
- if (plugin_var->flags & PLUGIN_VAR_THDLOCAL)
- {
- if (type != OPT_GLOBAL)
- src= real_value_ptr(thd, OPT_GLOBAL);
- else
- switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
- case PLUGIN_VAR_INT:
- src= &((thdvar_uint_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_LONG:
- src= &((thdvar_ulong_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_LONGLONG:
- src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_ENUM:
- src= &((thdvar_enum_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_SET:
- src= &((thdvar_set_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_BOOL:
- src= &((thdvar_bool_t*) plugin_var)->def_val;
- break;
- case PLUGIN_VAR_STR:
- src= &((thdvar_str_t*) plugin_var)->def_val;
- break;
- default:
- DBUG_ASSERT(0);
- }
- }
-
- /* 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)
- {
- plugin_var->update(thd, plugin_var, tgt, src);
- pthread_mutex_unlock(&LOCK_global_system_variables);
- }
- else
- {
- pthread_mutex_unlock(&LOCK_global_system_variables);
- plugin_var->update(thd, plugin_var, tgt, src);
- }
+ return false;
}
-
-bool sys_var_pluginvar::update(THD *thd, set_var *var)
+bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
{
- void *tgt;
-
- DBUG_ASSERT(is_readonly() || plugin_var->update);
+ DBUG_ASSERT(!is_readonly());
+ safe_mutex_assert_owner(&LOCK_global_system_variables);
- /* thd must equal current_thd if PLUGIN_VAR_THDLOCAL flag is set */
- DBUG_ASSERT(!(plugin_var->flags & PLUGIN_VAR_THDLOCAL) ||
- thd == current_thd);
+ void *tgt= real_value_ptr(thd, var->type);
+ const void *src= &var->save_result;
- 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
+ if (!var->value)
{
- pthread_mutex_unlock(&LOCK_global_system_variables);
- plugin_var->update(thd, plugin_var, tgt, &var->save_result);
+ switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
+ case PLUGIN_VAR_INT:
+ src= &((sysvar_uint_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONG:
+ src= &((sysvar_ulong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONGLONG:
+ src= &((sysvar_ulonglong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_ENUM:
+ src= &((sysvar_enum_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_SET:
+ src= &((sysvar_set_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_BOOL:
+ src= &((sysvar_bool_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_STR:
+ src= &((sysvar_str_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_uint_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_ulong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_ulonglong_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_enum_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_set_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_bool_t*) plugin_var)->def_val;
+ break;
+ case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_str_t*) plugin_var)->def_val;
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
}
- return 0;
+
+ plugin_var->update(thd, plugin_var, tgt, src);
+
+ return false;
}
@@ -2944,40 +2958,48 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
DBUG_ENTER("construct_options");
- options[0].name= plugin_name_ptr= (char*) alloc_root(mem_root,
- plugin_name_len + 1);
+ plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1);
strcpy(plugin_name_ptr, plugin_name);
my_casedn_str(&my_charset_latin1, plugin_name_ptr);
convert_underscore_to_dash(plugin_name_ptr, plugin_name_len);
- /* support --skip-plugin-foo syntax */
- options[1].name= plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root,
- plugin_name_len +
- plugin_dash.length + 1);
- strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, options[0].name, NullS);
-
- options[0].id= options[1].id= 256; /* must be >255. dup id ok */
- options[0].var_type= options[1].var_type= GET_ENUM;
- options[0].arg_type= options[1].arg_type= OPT_ARG;
- options[0].def_value= options[1].def_value= 1; /* ON */
- options[0].typelib= options[1].typelib= &global_plugin_typelib;
-
- strxnmov(comment, max_comment_len, "Enable or disable ", plugin_name,
- " plugin. Possible values are ON, OFF, FORCE (don't start "
- "if the plugin fails to load).", NullS);
- options[0].comment= comment;
+ plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root,
+ plugin_name_len +
+ plugin_dash.length + 1);
+ strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
+
+ if (!tmp->is_mandatory)
+ {
+ /* support --skip-plugin-foo syntax */
+ options[0].name= plugin_name_ptr;
+ options[1].name= plugin_name_with_prefix_ptr;
+ options[0].id= options[1].id= 0;
+ options[0].var_type= options[1].var_type= GET_ENUM;
+ options[0].arg_type= options[1].arg_type= OPT_ARG;
+ options[0].def_value= options[1].def_value= 1; /* ON */
+ options[0].typelib= options[1].typelib= &global_plugin_typelib;
+
+ strxnmov(comment, max_comment_len, "Enable or disable ", plugin_name,
+ " plugin. Possible values are ON, OFF, FORCE (don't start "
+ "if the plugin fails to load).", NullS);
+ options[0].comment= comment;
+ /*
+ Allocate temporary space for the value of the tristate.
+ This option will have a limited lifetime and is not used beyond
+ server initialization.
+ GET_ENUM value is an unsigned integer.
+ */
+ options[0].value= options[1].value=
+ (uchar **)alloc_root(mem_root, sizeof(uint));
+ *((uint*) options[0].value)= (uint) options[0].def_value;
- /*
- Allocate temporary space for the value of the tristate.
- This option will have a limited lifetime and is not used beyond
- server initialization.
- GET_ENUM value is an integer.
- */
- options[0].value= options[1].value= (uchar **)alloc_root(mem_root,
- sizeof(int));
- *((uint*) options[0].value)= *((uint*) options[1].value)=
- (uint) options[0].def_value;
+ options+= 2;
+ }
- options+= 2;
+ if (!my_strcasecmp(&my_charset_latin1, plugin_name_ptr, "NDBCLUSTER"))
+ {
+ plugin_name_ptr= const_cast<char*>("ndb"); // Use legacy "ndb" prefix
+ plugin_name_len= 3;
+ }
/*
Two passes as the 2nd pass will take pointer addresses for use
@@ -3125,7 +3147,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
options->name= optname;
options->comment= opt->comment;
options->app_type= opt;
- options->id= (options-1)->id + 1;
+ options->id= 0;
plugin_opt_set_limits(options, opt);
@@ -3166,13 +3188,20 @@ static my_option *construct_help_options(MEM_ROOT *mem_root,
bzero(opts, sizeof(my_option) * count);
+ /**
+ some plugin variables (those that don't have PLUGIN_VAR_NOSYSVAR flag)
+ have their names prefixed with the plugin name. Restore the names here
+ to get the correct (not double-prefixed) help text.
+ We won't need @@sysvars anymore and don't care about their proper names.
+ */
+ restore_pluginvar_names(p->system_vars);
+
if (construct_options(mem_root, p, opts))
DBUG_RETURN(NULL);
DBUG_RETURN(opts);
}
-
/**
Create and register system variables supplied from the plugin and
assigns initial values from corresponding command line arguments.
@@ -3197,18 +3226,17 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
int *argc, char **argv)
{
struct sys_var_chain chain= { NULL, NULL };
- my_bool can_disable;
bool disable_plugin;
- enum_plugin_load_policy plugin_load_policy= PLUGIN_ON;
+ enum_plugin_load_policy plugin_load_policy= tmp->is_mandatory ? PLUGIN_FORCE : PLUGIN_ON;
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
&tmp->mem_root : &plugin_mem_root;
st_mysql_sys_var **opt;
my_option *opts= NULL;
+ LEX_STRING plugin_name;
char *varname;
int error;
- st_mysql_sys_var *o;
- sys_var *v;
+ sys_var *v __attribute__((unused));
struct st_bookmark *var;
uint len, count= EXTRA_OPTIONS;
DBUG_ENTER("test_plugin_options");
@@ -3244,7 +3272,8 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
We adjust the default value to account for the hardcoded exceptions
we have set for the federated and ndbcluster storage engines.
*/
- opts[0].def_value= opts[1].def_value= (int)plugin_load_policy;
+ if (!tmp->is_mandatory)
+ opts[0].def_value= opts[1].def_value= plugin_load_policy;
error= handle_options(argc, &argv, opts, get_one_plugin_option);
(*argc)++; /* add back one for the program name */
@@ -3259,24 +3288,12 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
Set plugin loading policy from option value. First element in the option
list is always the <plugin name> option value.
*/
- plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value;
+ if (!tmp->is_mandatory)
+ plugin_load_policy= (enum_plugin_load_policy)*(uint*)opts[0].value;
}
disable_plugin= (plugin_load_policy == PLUGIN_OFF);
- /*
- The 'MyISAM' and 'Memory' storage engines currently can't be disabled.
- */
- can_disable=
- my_strcasecmp(&my_charset_latin1, tmp->name.str, "MyISAM") &&
- my_strcasecmp(&my_charset_latin1, tmp->name.str, "MEMORY");
-
- tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE) || !can_disable;
-
- if (disable_plugin && !can_disable)
- {
- sql_print_warning("Plugin '%s' cannot be disabled", tmp->name.str);
- disable_plugin= FALSE;
- }
+ tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE);
/*
If the plugin is disabled it should not be initialized.
@@ -3291,34 +3308,37 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
DBUG_RETURN(1);
}
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "NDBCLUSTER"))
+ {
+ plugin_name.str= const_cast<char*>("ndb"); // Use legacy "ndb" prefix
+ plugin_name.length= 3;
+ }
+ else
+ plugin_name= tmp->name;
+
error= 1;
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
{
+ st_mysql_sys_var *o;
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);
+ if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
+ v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o);
else
{
- len= tmp->name.length + strlen(o->name) + 2;
+ len= plugin_name.length + strlen(o->name) + 2;
varname= (char*) alloc_root(mem_root, len);
- strxmov(varname, tmp->name.str, "-", o->name, NullS);
+ strxmov(varname, plugin_name.str, "-", o->name, NullS);
my_casedn_str(&my_charset_latin1, varname);
convert_dash_to_underscore(varname, len-1);
- v= new (mem_root) sys_var_pluginvar(varname, o);
+ v= new (mem_root) sys_var_pluginvar(&chain, 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);
} /* end for */
if (chain.first)
{
chain.last->next = NULL;
- if (mysql_add_sys_var_chain(chain.first, NULL))
+ if (mysql_add_sys_var_chain(chain.first))
{
sql_print_error("Plugin '%s' has conflicting system variables",
tmp->name.str);
@@ -3339,49 +3359,26 @@ err:
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)
+void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root)
{
- 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, (uchar*) opt);
- }
-
- for (;main_options->id; main_options++)
- insert_dynamic(&all_options, (uchar*) main_options);
-
- sort_dynamic(&all_options, (qsort_cmp) option_cmp);
+ if (!initialized)
+ return;
- /* main_options now points to the empty option terminator */
- insert_dynamic(&all_options, (uchar*) main_options);
+ for (uint idx= 0; idx < plugin_array.elements; idx++)
+ {
+ p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
- my_print_help((my_option*) all_options.buffer);
- my_print_variables((my_option*) all_options.buffer);
+ if (!(opt= construct_help_options(mem_root, p)))
+ continue;
- delete_dynamic(&all_options);
- free_root(&mem_root, MYF(0));
+ /* Only options with a non-NULL comment are displayed in help text */
+ for (;opt->name; opt++)
+ if (opt->comment)
+ insert_dynamic(options, (uchar*) opt);
+ }
}
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 23ce85c994b..bec880b21d2 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -17,6 +17,9 @@
#define _sql_plugin_h
class sys_var;
+enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
+
+#include <my_sys.h>
#ifdef DBUG_OFF
#define plugin_ref_to_int(A) A
@@ -37,6 +40,7 @@ class sys_var;
typedef enum enum_mysql_show_type SHOW_TYPE;
typedef struct st_mysql_show_var SHOW_VAR;
+typedef struct st_mysql_lex_string LEX_STRING;
#define MYSQL_ANY_PLUGIN -1
@@ -112,7 +116,7 @@ extern const LEX_STRING plugin_type_names[];
extern int plugin_init(int *argc, char **argv, int init_flags);
extern void plugin_shutdown(void);
-extern void my_print_help_inc_plugins(struct my_option *options, uint size);
+void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root);
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)
@@ -129,6 +133,7 @@ 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);
+extern SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type);
typedef my_bool (plugin_foreach_func)(THD *thd,
plugin_ref plugin,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d624c22f43a..f19f12ddc13 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -84,6 +84,7 @@ When one supplies long data for a placeholder:
*/
#include "mysql_priv.h"
+#include "set_var.h"
#include "sql_prepare.h"
#include "sql_select.h" // for JOIN
#include "sql_cursor.h"
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 69e5bc3cbb4..84ee0768b25 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -341,7 +341,7 @@ void PROFILING::start_new_query(const char *initial_state)
finish_current_query();
}
- enabled= (((thd)->options & OPTION_PROFILING) != 0);
+ enabled= ((thd->variables.option_bits & OPTION_PROFILING) != 0);
if (! enabled) DBUG_VOID_RETURN;
@@ -379,7 +379,7 @@ void PROFILING::finish_current_query()
status_change("ending", NULL, NULL, 0);
if ((enabled) && /* ON at start? */
- ((thd->options & OPTION_PROFILING) != 0) && /* and ON at end? */
+ ((thd->variables.option_bits & OPTION_PROFILING) != 0) && /* and ON at end? */
(current->query_source != NULL) &&
(! current->entries.is_empty()))
{
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index aa06b1cfb0e..517fbb97b73 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -29,6 +29,14 @@ my_bool opt_sporadic_binlog_dump_fail = 0;
static int binlog_dump_count = 0;
#endif
+/**
+ a copy of active_mi->rli->slave_skip_counter, for showing in SHOW VARIABLES,
+ INFORMATION_SCHEMA.GLOBAL_VARIABLES and @@sql_slave_skip_counter without
+ taking all the mutexes needed to access active_mi->rli->slave_skip_counter
+ properly.
+*/
+uint sql_slave_skip_counter;
+
/*
fake_rotate_event() builds a fake (=which does not exist physically in any
binlog) Rotate event, which contains the name of the binlog we are going to
@@ -1985,147 +1993,4 @@ int log_loaded_block(IO_CACHE* file)
DBUG_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 void fix_slave_net_timeout(THD *thd, enum_var_type type)
-{
- DBUG_ENTER("fix_slave_net_timeout");
-#ifdef HAVE_REPLICATION
- pthread_mutex_lock(&LOCK_active_mi);
- DBUG_PRINT("info",("slave_net_timeout=%lu mi->heartbeat_period=%.3f",
- slave_net_timeout,
- (active_mi? active_mi->heartbeat_period : 0.0)));
- if (active_mi && slave_net_timeout < active_mi->heartbeat_period)
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE,
- "The currect value for master_heartbeat_period"
- " exceeds the new value of `slave_net_timeout' sec."
- " A sensible value for the period should be"
- " less than the timeout.");
- pthread_mutex_unlock(&LOCK_active_mi);
-#endif
- DBUG_VOID_RETURN;
-}
-
-static sys_var_chain vars = { NULL, NULL };
-
-static sys_var_const sys_log_slave_updates(&vars, "log_slave_updates",
- OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*) &opt_log_slave_updates);
-static sys_var_const sys_relay_log(&vars, "relay_log",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &opt_relay_logname);
-static sys_var_const sys_relay_log_index(&vars, "relay_log_index",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &opt_relaylog_index_name);
-static sys_var_const sys_relay_log_info_file(&vars, "relay_log_info_file",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &relay_log_info_file);
-static sys_var_bool_ptr sys_relay_log_purge(&vars, "relay_log_purge",
- &relay_log_purge);
-static sys_var_bool_ptr sys_relay_log_recovery(&vars, "relay_log_recovery",
- &relay_log_recovery);
-static sys_var_uint_ptr sys_sync_binlog_period(&vars, "sync_binlog",
- &sync_binlog_period);
-static sys_var_uint_ptr sys_sync_relaylog_period(&vars, "sync_relay_log",
- &sync_relaylog_period);
-static sys_var_uint_ptr sys_sync_relayloginfo_period(&vars, "sync_relay_log_info",
- &sync_relayloginfo_period);
-static sys_var_uint_ptr sys_sync_masterinfo_period(&vars, "sync_master_info",
- &sync_masterinfo_period);
-static sys_var_const sys_relay_log_space_limit(&vars,
- "relay_log_space_limit",
- OPT_GLOBAL, SHOW_LONGLONG,
- (uchar*)
- &relay_log_space_limit);
-static sys_var_const sys_slave_load_tmpdir(&vars, "slave_load_tmpdir",
- OPT_GLOBAL, SHOW_CHAR_PTR,
- (uchar*) &slave_load_tmpdir);
-static sys_var_long_ptr sys_slave_net_timeout(&vars, "slave_net_timeout",
- &slave_net_timeout,
- fix_slave_net_timeout);
-static sys_var_const sys_slave_skip_errors(&vars, "slave_skip_errors",
- OPT_GLOBAL, SHOW_CHAR,
- (uchar*) slave_skip_error_names);
-static sys_var_long_ptr sys_slave_trans_retries(&vars, "slave_transaction_retries",
- &slave_trans_retries);
-static sys_var_slave_skip_counter sys_slave_skip_counter(&vars, "sql_slave_skip_counter");
-
-
-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;
-}
-
-
-int init_replication_sys_vars()
-{
- 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_select.cc b/sql/sql_select.cc
index 5f52ef9f856..5f1c5ac2a34 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -120,8 +120,7 @@ static COND *optimize_cond(JOIN *join, COND *conds,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
-static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options);
+static bool create_myisam_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong, my_bool);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@@ -267,7 +266,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) lex->proc_list.first,
- select_lex->options | thd->options |
+ select_lex->options | thd->variables.option_bits |
setup_tables_done_option,
result, unit, select_lex);
}
@@ -1017,7 +1016,7 @@ JOIN::optimize()
error= 0;
DBUG_RETURN(0);
}
- if (!(thd->options & OPTION_BIG_SELECTS) &&
+ if (!(thd->variables.option_bits & OPTION_BIG_SELECTS) &&
best_read > (double) thd->variables.max_join_size &&
!(select_options & SELECT_DESCRIBE))
{ /* purecov: inspected */
@@ -1505,15 +1504,10 @@ JOIN::optimize()
if (!(exec_tmp_table1=
create_tmp_table(thd, &tmp_table_param, all_fields,
- tmp_group,
- group_list ? 0 : select_distinct,
+ tmp_group, group_list ? 0 : select_distinct,
group_list && simple_group,
- select_options,
- tmp_rows_limit,
- (char *) "")))
- {
+ select_options, tmp_rows_limit, "")))
DBUG_RETURN(1);
- }
/*
We don't have to store rows in temp table that doesn't match HAVING if:
@@ -1987,8 +1981,7 @@ JOIN::exec()
curr_join->select_distinct &&
!curr_join->group_list,
1, curr_join->select_options,
- HA_POS_ERROR,
- (char *) "")))
+ HA_POS_ERROR, "")))
DBUG_VOID_RETURN;
curr_join->exec_tmp_table2= exec_tmp_table2;
}
@@ -2834,8 +2827,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
!table->fulltext_searched &&
!table->pos_in_table_list->embedding)
{
- if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
- == HA_NOSAME)
+ if (table->key_info[key].flags & HA_NOSAME)
{
if (const_ref == eq_part)
{ // Found everything for ref.
@@ -5815,8 +5807,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
DBUG_RETURN(0);
if (j->type == JT_CONST)
j->table->const_table= 1;
- else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
- HA_END_SPACE_KEY)) != HA_NOSAME) ||
+ else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) ||
keyparts != keyinfo->key_parts || null_ref_key)
{
/* Must read with repeat */
@@ -9373,7 +9364,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{
Field *field=((Item_field*) args[0])->field;
if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
- (thd->options & OPTION_AUTO_IS_NULL) &&
+ (thd->variables.option_bits & OPTION_AUTO_IS_NULL) &&
(thd->first_successful_insert_id_in_prev_stmt > 0 &&
thd->substitute_null_with_insert_id))
{
@@ -9923,7 +9914,7 @@ TABLE *
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- char *table_alias)
+ const char *table_alias)
{
MEM_ROOT *mem_root_save, own_root;
TABLE *table;
@@ -10238,9 +10229,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* 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))
+ if (blob_count || using_unique_constraint
+ || (thd->variables.big_tables && !(select_options & SELECT_SMALL_RESULT))
+ || (select_options & TMP_TABLE_FORCE_MYISAM))
{
share->db_plugin= ha_lock_engine(0, myisam_hton);
table->file= get_new_handler(share, &table->mem_root,
@@ -10567,7 +10558,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
share->db_record_offset= 1;
if (share->db_type() == myisam_hton)
{
- if (create_myisam_tmp_table(table,param,select_options))
+ if (create_myisam_tmp_table(table, param, select_options,
+ thd->variables.big_tables))
goto err;
}
if (open_tmp_table(table))
@@ -10731,7 +10723,7 @@ static bool open_tmp_table(TABLE *table)
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+ ulonglong options, my_bool big_tables)
{
int error;
MI_KEYDEF keydef;
@@ -10818,8 +10810,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
MI_CREATE_INFO create_info;
bzero((char*) &create_info,sizeof(create_info));
- if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
- OPTION_BIG_TABLES)
+ if (big_tables && !(options & SELECT_SMALL_RESULT))
create_info.data_file_length= ~(ulonglong) 0;
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
@@ -10920,7 +10911,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
thd_proc_info(thd, "converting HEAP to MyISAM");
if (create_myisam_tmp_table(&new_table, param,
- thd->lex->select_lex.options | thd->options))
+ thd->lex->select_lex.options | thd->variables.option_bits,
+ thd->variables.big_tables))
goto err2;
if (open_tmp_table(&new_table))
goto err1;
@@ -16786,7 +16778,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
(ORDER*) first->group_list.first,
first->having,
(ORDER*) thd->lex->proc_list.first,
- first->options | thd->options | SELECT_DESCRIBE,
+ first->options | thd->variables.option_bits | SELECT_DESCRIBE,
result, unit, first);
}
DBUG_RETURN(res || thd->is_error());
diff --git a/sql/sql_select.h b/sql/sql_select.h
index bdca4b196bc..3a664546397 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -578,7 +578,7 @@ bool store_val_in_field(Field *field, Item *val, enum_check_fields check_flag);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
- char* alias);
+ const char* alias);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
List<Item> &fields, bool reset_with_sum_func);
@@ -644,7 +644,7 @@ public:
enum store_key_result result;
THD *thd= to_field->table->in_use;
enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields;
- ulong sql_mode= thd->variables.sql_mode;
+ ulonglong sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index cb77f2b2a1d..92366b4bc1a 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -22,6 +22,7 @@
#include "repl_failsafe.h"
#include "sp.h"
#include "sp_head.h"
+#include "set_var.h"
#include "sql_trigger.h"
#include "authors.h"
#include "contributors.h"
@@ -960,7 +961,7 @@ int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
if (length &&
!is_keyword(name,length) &&
!require_quotes(name, length) &&
- !(thd->options & OPTION_QUOTE_SHOW_CREATE))
+ !(thd->variables.option_bits & OPTION_QUOTE_SHOW_CREATE))
return EOF;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
return '"';
@@ -2214,6 +2215,15 @@ static bool show_status_array(THD *thd, const char *wild,
end= strend(pos);
break;
}
+ case SHOW_LEX_STRING:
+ {
+ LEX_STRING *ls=(LEX_STRING*)value;
+ if (!(pos= ls->str))
+ end= pos= "";
+ else
+ end= pos + ls->length;
+ break;
+ }
case SHOW_KEY_CACHE_LONG:
value= (char*) dflt_key_cache + (ulong)value;
end= int10_to_str(*(long*) value, buff, 10);
@@ -4589,8 +4599,7 @@ static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
- sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
- &sql_mode_rep);
+ sql_mode_string_representation(thd, sql_mode, &sql_mode_rep);
table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
@@ -5321,8 +5330,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
/* SQL_MODE */
{
LEX_STRING sql_mode;
- sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
- &sql_mode);
+ sql_mode_string_representation(thd, et.sql_mode, &sql_mode);
sch_table->field[ISE_SQL_MODE]->
store(sql_mode.str, sql_mode.length, scs);
}
@@ -5486,7 +5494,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
option_type= OPT_GLOBAL;
rw_rdlock(&LOCK_system_variables_hash);
- res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
+ res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, option_type),
option_type, NULL, "", tables->table, upper_case_names, cond);
rw_unlock(&LOCK_system_variables_hash);
DBUG_RETURN(res);
@@ -5811,7 +5819,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
SELECT_LEX *select_lex= thd->lex->current_select;
if (!(table= create_tmp_table(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0,
- (select_lex->options | thd->options |
+ (select_lex->options | thd->variables.option_bits |
TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, table_list->alias)))
DBUG_RETURN(0);
@@ -7057,9 +7065,7 @@ static bool show_create_trigger_impl(THD *thd,
&trg_connection_cl_name,
&trg_db_cl_name);
- sys_var_thd_sql_mode::symbolic_mode_representation(thd,
- trg_sql_mode,
- &trg_sql_mode_str);
+ sql_mode_string_representation(thd, trg_sql_mode, &trg_sql_mode_str);
/* Resolve trigger client character set. */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c4904feffa6..633c405ea25 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -22,6 +22,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_show.h"
+#include "keycaches.h"
#ifdef __WIN__
#include <io.h>
@@ -2214,10 +2215,10 @@ static int sort_keys(KEY *a, KEY *b)
{
if (!(b_flags & HA_NOSAME))
return -1;
- if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
+ if ((a_flags ^ b_flags) & HA_NULL_PART_KEY)
{
/* Sort NOT NULL keys before other keys */
- return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
+ return (a_flags & HA_NULL_PART_KEY) ? 1 : -1;
}
if (a->name == primary_key_name)
return -1;
@@ -5057,45 +5058,6 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
/*
- Reassign all tables assigned to a key cache to another key cache
-
- SYNOPSIS
- reassign_keycache_tables()
- thd Thread object
- src_cache Reference to the key cache to clean up
- dest_cache New key cache
-
- NOTES
- This is called when one sets a key cache size to zero, in which
- case we have to move the tables associated to this key cache to
- the "default" one.
-
- One has to ensure that one never calls this function while
- some other thread is changing the key cache. This is assured by
- the caller setting src_cache->in_init before calling this function.
-
- We don't delete the old key cache as there may still be pointers pointing
- to it for a while after this function returns.
-
- RETURN VALUES
- 0 ok
-*/
-
-int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
- KEY_CACHE *dst_cache)
-{
- DBUG_ENTER("reassign_keycache_tables");
-
- DBUG_ASSERT(src_cache != dst_cache);
- DBUG_ASSERT(src_cache->in_init);
- src_cache->param_buff_size= 0; // Free key cache
- ha_resize_key_cache(src_cache);
- ha_change_key_cache(src_cache, dst_cache);
- DBUG_RETURN(0);
-}
-
-
-/*
Preload specified indexes for a table into key cache
SYNOPSIS
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index ac1dae3197d..8dc4b4ffeb6 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -19,6 +19,7 @@
#include "mysql_priv.h"
#include "sql_select.h"
+#include "keycaches.h"
#include <hash.h>
#include <thr_alarm.h>
#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H)
@@ -442,8 +443,10 @@ writes: %10s\n\
r_requests: %10s\n\
reads: %10s\n\n",
name,
- (ulong) key_cache->param_buff_size, key_cache->param_block_size,
- key_cache->param_division_limit, key_cache->param_age_threshold,
+ (ulong) key_cache->param_buff_size,
+ (ulong)key_cache->param_block_size,
+ (ulong)key_cache->param_division_limit,
+ (ulong)key_cache->param_age_threshold,
key_cache->blocks_used,key_cache->global_blocks_changed,
llstr(key_cache->global_cache_w_requests,llbuff1),
llstr(key_cache->global_cache_write,llbuff2),
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index cbf94ad7181..5bdff4dc9bf 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -121,7 +121,7 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1,
- options, HA_POS_ERROR, (char*) alias)))
+ options, HA_POS_ERROR, alias)))
return TRUE;
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -232,7 +232,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
bool can_skip_order_by;
sl->options|= SELECT_NO_UNLOCK;
JOIN *join= new JOIN(thd_arg, sl->item_list,
- sl->options | thd_arg->options | additional_options,
+ sl->options | thd_arg->variables.option_bits | additional_options,
tmp_result);
/*
setup_tables_done_option should be set only for very first SELECT,
@@ -335,7 +335,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
- create_options= (first_sl->options | thd_arg->options |
+ create_options= (first_sl->options | thd_arg->variables.option_bits |
TMP_TABLE_ALL_COLUMNS);
/*
Force the temporary table to be a MyISAM table if we're going to use
@@ -376,7 +376,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
init_prepare_fake_select_lex(thd);
/* Should be done only once (the only item_list per statement) */
DBUG_ASSERT(fake_select_lex->join == 0);
- if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,
+ if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->variables.option_bits,
result)))
{
fake_select_lex->table_list.empty();
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index cc92d224cd9..b197434d798 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -185,7 +185,7 @@ int mysql_update(THD *thd,
ha_rows *found_return, ha_rows *updated_return)
{
bool using_limit= limit != HA_POS_ERROR;
- bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
+ bool safe_update= test(thd->variables.option_bits & OPTION_SAFE_UPDATES);
bool used_key_is_modified, transactional_table, will_batch;
bool can_compare_record;
int res;
@@ -1493,7 +1493,7 @@ multi_update::initialize_tables(JOIN *join)
TABLE_LIST *table_ref;
DBUG_ENTER("initialize_tables");
- if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
+ if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join))
DBUG_RETURN(1);
main_table=join->join_tab->table;
table_to_update= 0;
@@ -1617,13 +1617,14 @@ loop_end:
tmp_param->field_count=temp_fields.elements;
tmp_param->group_parts=1;
tmp_param->group_length= table->file->ref_length;
- if (!(tmp_tables[cnt]=create_tmp_table(thd,
- tmp_param,
- temp_fields,
- (ORDER*) &group, 0, 0,
- TMP_TABLE_ALL_COLUMNS,
- HA_POS_ERROR,
- (char *) "")))
+ /* small table, ignore SQL_BIG_TABLES */
+ my_bool save_big_tables= thd->variables.big_tables;
+ thd->variables.big_tables= FALSE;
+ tmp_tables[cnt]=create_tmp_table(thd, tmp_param, temp_fields,
+ (ORDER*) &group, 0, 0,
+ TMP_TABLE_ALL_COLUMNS, HA_POS_ERROR, "");
+ thd->variables.big_tables= save_big_tables;
+ if (!tmp_tables[cnt])
DBUG_RETURN(1);
tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 8305303f351..cb60c3b34e4 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -29,15 +29,6 @@ const LEX_STRING view_type= { C_STRING_WITH_LEN("VIEW") };
static int mysql_register_view(THD *thd, TABLE_LIST *view,
enum_view_create_mode mode);
-const char *updatable_views_with_limit_names[]= { "NO", "YES", NullS };
-TYPELIB updatable_views_with_limit_typelib=
-{
- array_elements(updatable_views_with_limit_names)-1, "",
- updatable_views_with_limit_names,
- 0
-};
-
-
/*
Make a unique name for an anonymous view column
SYNOPSIS
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 0d3610ccee1..296316896c9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -47,6 +47,8 @@
#include "event_parse_data.h"
#include <myisam.h>
#include <myisammrg.h>
+#include "keycaches.h"
+#include "set_var.h"
/* this is to get the bison compilation windows warnings out */
#ifdef _MSC_VER
@@ -426,7 +428,7 @@ set_system_variable(THD *thd, struct sys_var_with_base *tmp,
LEX *lex= thd->lex;
/* No AUTOCOMMIT from a stored function or trigger. */
- if (lex->spcont && tmp->var == &sys_autocommit)
+ if (lex->spcont && tmp->var == Sys_autocommit_ptr)
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
if (! (var= new set_var(var_type, tmp->var, &tmp->base_name, val)))
@@ -4719,7 +4721,6 @@ part_value_item:
part_value_item_list {}
')'
{
- LEX *lex= Lex;
partition_info *part_info= Lex->part_info;
part_info->print_debug(") part_value_item", NULL);
if (part_info->num_columns == 0)
@@ -4750,7 +4751,6 @@ part_value_expr_item:
MAX_VALUE_SYM
{
partition_info *part_info= Lex->part_info;
- part_column_list_val *col_val;
if (part_info->part_type == LIST_PARTITION)
{
my_parse_error(ER(ER_MAXVALUE_IN_VALUES_IN));
@@ -7019,7 +7019,7 @@ cache_keys_spec:
{
Lex->select_lex.alloc_index_hints(YYTHD);
Select->set_index_hint_type(INDEX_HINT_USE,
- global_system_variables.old_mode ?
+ old_mode ?
INDEX_HINT_MASK_JOIN :
INDEX_HINT_MASK_ALL);
}
@@ -9372,8 +9372,7 @@ opt_outer:
index_hint_clause:
/* empty */
{
- $$= global_system_variables.old_mode ?
- INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
+ $$= 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; }
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 56fa4a380ea..d7ab102b225 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -45,6 +45,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
const char *end= str + strip->cset->lengthsp(strip, str, length);
ulonglong found= 0;
*err_pos= 0; // No error yet
+ *err_len= 0;
if (str != end)
{
const char *start= str;
@@ -71,7 +72,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
var_len= (uint) (pos - start);
uint find= cs ? find_type2(lib, start, var_len, cs) :
find_type(lib, start, var_len, (bool) 0);
- if (!find)
+ if (!find && *err_len == 0) // report the first error with length > 0
{
*err_pos= (char*) start;
*err_len= var_len;
@@ -87,209 +88,6 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
return found;
}
-
-static const char *on_off_default_names[]=
-{
- "off","on","default", NullS
-};
-
-static const unsigned int on_off_default_names_len[]=
-{
- sizeof("off") - 1,
- sizeof("on") - 1,
- sizeof("default") - 1
-};
-
-static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
- "", on_off_default_names,
- (unsigned int *)on_off_default_names_len};
-
-
-/*
- Parse a TYPELIB name from the buffer
-
- SYNOPSIS
- parse_name()
- lib Set of names to scan for.
- strpos INOUT Start of the buffer (updated to point to the next
- character after the name)
- end End of the buffer
- cs Charset used in the buffer
-
- DESCRIPTION
- Parse a TYPELIB name from the buffer. The buffer is assumed to contain
- one of the names specified in the TYPELIB, followed by comma, '=', or
- end of the buffer.
-
- RETURN
- 0 No matching name
- >0 Offset+1 in typelib for matched name
-*/
-
-static uint parse_name(TYPELIB *lib, const char **strpos, const char *end,
- CHARSET_INFO *cs)
-{
- const char *pos= *strpos;
- const char *start= pos;
-
- /* Find the length */
- if (cs && cs->mbminlen > 1)
- {
- int mblen= 0;
- for ( ; pos < end; pos+= mblen)
- {
- my_wc_t wc;
- if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) pos,
- (const uchar *) end)) < 1)
- mblen= 1; // Not to hang on a wrong multibyte sequence
- if (wc == (my_wc_t) '=' || wc == (my_wc_t) ',')
- break;
- }
- }
- else
- for (; pos != end && *pos != '=' && *pos !=',' ; pos++) ;
-
- uint var_len= (uint) (pos - start);
- /* Determine which flag it is */
- uint find= cs ? find_type2(lib, start, var_len, cs) :
- find_type(lib, start, var_len, (bool) 0);
- *strpos= pos;
- return find;
-}
-
-
-/* Read next character from the buffer in a charset-aware way */
-
-static my_wc_t get_next_char(const char **pos, const char *end, CHARSET_INFO *cs)
-{
- my_wc_t wc;
- if (*pos == end)
- return (my_wc_t)-1;
-
- if (cs && cs->mbminlen > 1)
- {
- int mblen;
- if ((mblen= cs->cset->mb_wc(cs, &wc, (const uchar *) *pos,
- (const uchar *) end)) < 1)
- mblen= 1; // Not to hang on a wrong multibyte sequence
- *pos += mblen;
- return wc;
- }
- else
- return *((*pos)++);
-}
-
-
-/*
- Parse and apply a set of flag assingments
-
- SYNOPSIS
- find_set_from_flags()
- lib Flag names
- default_name Number of "default" in the typelib
- cur_set Current set of flags (start from this state)
- default_set Default set of flags (use this for assign-default
- keyword and flag=default assignments)
- str String to be parsed
- length Length of the string
- cs String charset
- err_pos OUT If error, set to point to start of wrong set string
- NULL on success
- err_len OUT If error, set to the length of wrong set string
- set_warning OUT TRUE <=> Some string in set couldn't be used
-
- DESCRIPTION
- Parse a set of flag assignments, that is, parse a string in form:
-
- param_name1=value1,param_name2=value2,...
-
- where the names are specified in the TYPELIB, and each value can be
- either 'on','off', or 'default'. Setting the same name twice is not
- allowed.
-
- Besides param=val assignments, we support the "default" keyword (keyword
- #default_name in the typelib). It can be used one time, if specified it
- causes us to build the new set over the default_set rather than cur_set
- value.
-
- RETURN
- Parsed set value if (*errpos == NULL)
- Otherwise undefined
-*/
-
-ulonglong find_set_from_flags(TYPELIB *lib, uint default_name,
- ulonglong cur_set, ulonglong default_set,
- const char *str, uint length, CHARSET_INFO *cs,
- char **err_pos, uint *err_len, bool *set_warning)
-{
- CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
- const char *end= str + strip->cset->lengthsp(strip, str, length);
- ulonglong flags_to_set= 0, flags_to_clear= 0;
- bool set_defaults= 0;
- *err_pos= 0; // No error yet
- if (str != end)
- {
- const char *start= str;
- for (;;)
- {
- const char *pos= start;
- uint flag_no, value;
-
- if (!(flag_no= parse_name(lib, &pos, end, cs)))
- goto err;
-
- if (flag_no == default_name)
- {
- /* Using 'default' twice isn't allowed. */
- if (set_defaults)
- goto err;
- set_defaults= TRUE;
- }
- else
- {
- ulonglong bit= ((longlong) 1 << (flag_no - 1));
- /* parse the '=on|off|default' */
- if ((flags_to_clear | flags_to_set) & bit ||
- get_next_char(&pos, end, cs) != '=' ||
- !(value= parse_name(&on_off_default_typelib, &pos, end, cs)))
- {
- goto err;
- }
-
- if (value == 1) // this is '=off'
- flags_to_clear|= bit;
- else if (value == 2) // this is '=on'
- flags_to_set|= bit;
- else // this is '=default'
- {
- if (default_set & bit)
- flags_to_set|= bit;
- else
- flags_to_clear|= bit;
- }
- }
- if (pos >= end)
- break;
-
- if (get_next_char(&pos, end, cs) != ',')
- goto err;
-
- start=pos;
- continue;
- err:
- *err_pos= (char*)start;
- *err_len= end - start;
- *set_warning= TRUE;
- break;
- }
- }
- ulonglong res= set_defaults? default_set : cur_set;
- res|= flags_to_set;
- res&= ~flags_to_clear;
- return res;
-}
-
-
/*
Function to find a string in a TYPELIB
(Same format as mysys/typelib.c)
@@ -543,3 +341,60 @@ int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
}
return -1;
}
+
+
+char *set_to_string(THD *thd, LEX_STRING *result, ulonglong set,
+ const char *lib[])
+{
+ char buff[STRING_BUFFER_USUAL_SIZE*8];
+ String tmp(buff, sizeof(buff), &my_charset_latin1);
+ LEX_STRING unused;
+
+ if (!result)
+ result= &unused;
+
+ tmp.length(0);
+
+ for (uint i= 0; set; i++, set >>= 1)
+ if (set & 1) {
+ tmp.append(lib[i]);
+ tmp.append(',');
+ }
+
+ if (tmp.length())
+ {
+ result->str= thd->strmake(tmp.ptr(), tmp.length()-1);
+ result->length= tmp.length()-1;
+ }
+ else
+ {
+ result->str= const_cast<char*>("");
+ result->length= 0;
+ }
+ return result->str;
+}
+
+char *flagset_to_string(THD *thd, LEX_STRING *result, ulonglong set,
+ const char *lib[])
+{
+ char buff[STRING_BUFFER_USUAL_SIZE*8];
+ String tmp(buff, sizeof(buff), &my_charset_latin1);
+ LEX_STRING unused;
+
+ if (!result) result= &unused;
+
+ tmp.length(0);
+
+ // note that the last element is always "default", and it's ignored below
+ for (uint i= 0; lib[i+1]; i++, set >>= 1)
+ {
+ tmp.append(lib[i]);
+ tmp.append(set & 1 ? "=on," : "=off,");
+ }
+
+ result->str= thd->strmake(tmp.ptr(), tmp.length()-1);
+ result->length= tmp.length()-1;
+
+ return result->str;
+}
+
diff --git a/sql/structs.h b/sql/structs.h
index 33b7148c4b3..041a6809804 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -142,8 +142,6 @@ typedef struct st_known_date_time_format {
const char *time_format;
} KNOWN_DATE_TIME_FORMAT;
-enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
-
extern const char *show_comp_option_name[];
typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
new file mode 100644
index 00000000000..3c4683d23f9
--- /dev/null
+++ b/sql/sys_vars.cc
@@ -0,0 +1,2738 @@
+/* Copyright (C) 2002-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ How to add new variables:
+
+ 1. copy one of the existing variables, and edit the declaration.
+ 2. if you need special behavior on assignment or additional checks
+ use ON_CHECK and ON_UPDATE callbacks.
+ 3. *Don't* add new Sys_var classes or uncle Occam will come
+ with his razor to haunt you at nights
+
+ Note - all storage engine variables (for example myisam_whatever)
+ should go into the corresponding storage engine sources
+ (for example in storage/myisam/ha_myisam.cc) !
+*/
+
+#include "sys_vars.h"
+
+#include "events.h"
+#include <thr_alarm.h>
+#include "slave.h"
+#include "rpl_mi.h"
+
+/*
+ The rule for this file: everything should be 'static'. When a sys_var
+ variable or a function from this file is - in very rare cases - needed
+ elsewhere it should be explicitly declared 'export' here to show that it's
+ not a mistakenly forgotten 'static' keyword.
+*/
+#define export /* not static */
+
+static Sys_var_ulong Sys_auto_increment_increment(
+ "auto_increment_increment",
+ "Auto-increment columns are incremented by this",
+ SESSION_VAR(auto_increment_increment),
+ CMD_LINE(OPT_ARG),
+ VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG);
+
+static Sys_var_ulong Sys_auto_increment_offset(
+ "auto_increment_offset",
+ "Offset added to Auto-increment columns. Used when "
+ "auto-increment-increment != 1",
+ SESSION_VAR(auto_increment_offset),
+ CMD_LINE(OPT_ARG),
+ VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG);
+
+static Sys_var_mybool Sys_automatic_sp_privileges(
+ "automatic_sp_privileges",
+ "Creating and dropping stored procedures alters ACLs",
+ GLOBAL_VAR(sp_automatic_privileges),
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+
+static Sys_var_ulong Sys_back_log(
+ "back_log", "The number of outstanding connection requests "
+ "MySQL can have. This comes into play when the main MySQL thread "
+ "gets very many connection requests in a very short time",
+ READ_ONLY GLOBAL_VAR(back_log), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 65535), DEFAULT(50), BLOCK_SIZE(1));
+
+static Sys_var_charptr Sys_basedir(
+ "basedir", "Path to installation directory. All paths are "
+ "usually resolved relative to this",
+ READ_ONLY GLOBAL_VAR(mysql_home_ptr), CMD_LINE(REQUIRED_ARG, 'b'),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_ulong Sys_binlog_cache_size(
+ "binlog_cache_size", "The size of the cache to "
+ "hold the SQL statements for the binary log during a "
+ "transaction. If you often use big, multi-statement "
+ "transactions you can increase this to get more performance",
+ GLOBAL_VAR(binlog_cache_size),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(32768), BLOCK_SIZE(IO_SIZE));
+
+static bool check_has_super(sys_var *self, THD *thd, set_var *var)
+{
+ DBUG_ASSERT(self->scope() != sys_var::GLOBAL);// don't abuse check_has_super()
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
+ {
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ return true;
+ }
+#endif
+ return false;
+}
+static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_has_super(self, thd, var))
+ return true;
+ if (var->type == OPT_GLOBAL ||
+ (thd->variables.binlog_format == var->save_result.ulonglong_value))
+ return false;
+
+ /*
+ If RBR and open temporary tables, their CREATE TABLE may not be in the
+ binlog, so we can't toggle to SBR in this connection.
+ */
+ if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
+ thd->temporary_tables)
+ {
+ my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
+ return true;
+ }
+ /*
+ if in a stored function/trigger, it's too late to change mode
+ */
+ if (thd->in_sub_stmt)
+ {
+ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
+ return true;
+ }
+ return false;
+}
+
+static bool fix_binlog_format_after_update(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->reset_current_stmt_binlog_row_based();
+ return false;
+}
+
+static Sys_var_enum Sys_binlog_format(
+ "binlog_format", "What form of binary logging the master will "
+ "use: either ROW for row-based binary logging, STATEMENT "
+ "for statement-based binary logging, or MIXED. MIXED is statement-"
+ "based binary logging except for those statements where only row-"
+ "based is correct: those which involve user-defined functions (i.e. "
+ "UDFs) or the UUID() function; for those, row-based binary logging is "
+ "automatically used. If NDBCLUSTER is enabled and binlog-format is "
+ "MIXED, the format switches to row-based and back implicitly per each "
+ "query accessing an NDBCLUSTER table",
+ SESSION_VAR(binlog_format), CMD_LINE(REQUIRED_ARG, OPT_BINLOG_FORMAT),
+ binlog_format_names, DEFAULT(BINLOG_FORMAT_STMT),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_format_check),
+ ON_UPDATE(fix_binlog_format_after_update));
+
+static Sys_var_ulong Sys_bulk_insert_buff_size(
+ "bulk_insert_buffer_size", "Size of tree cache used in bulk "
+ "insert optimisation. Note that this is a limit per thread!",
+ SESSION_VAR(bulk_insert_buff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(8192*1024), BLOCK_SIZE(1));
+
+static Sys_var_charptr Sys_character_sets_dir(
+ "character_sets_dir", "Directory where character sets are",
+ READ_ONLY GLOBAL_VAR(charsets_dir), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static bool check_not_null(sys_var *self, THD *thd, set_var *var)
+{
+ return var->value && var->value->is_null();
+}
+static bool check_charset(sys_var *self, THD *thd, set_var *var)
+{
+ if (!var->value)
+ return false;
+
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ String str(buff, sizeof(buff), system_charset_info), *res;
+ if (!(res=var->value->val_str(&str)))
+ var->save_result.ptr= NULL;
+ else if (!(var->save_result.ptr= get_charset_by_csname(res->c_ptr(),
+ MY_CS_PRIMARY,
+ MYF(0))) &&
+ !(var->save_result.ptr= get_old_charset_by_name(res->c_ptr())))
+ {
+ ErrConvString err(res);
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr());
+ return true;
+ }
+ }
+ else // INT_RESULT
+ {
+ int csno= (int)var->value->val_int();
+ if (!(var->save_result.ptr= get_charset(csno, MYF(0))))
+ {
+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
+ return true;
+ }
+ }
+ return false;
+}
+static bool check_charset_not_null(sys_var *self, THD *thd, set_var *var)
+{
+ return check_charset(self, thd, var) || check_not_null(self, thd, var);
+}
+static Sys_var_struct Sys_character_set_system(
+ "character_set_system", "The character set used by the server "
+ "for storing identifiers",
+ READ_ONLY GLOBAL_VAR(system_charset_info), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(0));
+
+static Sys_var_struct Sys_character_set_server(
+ "character_set_server", "The default character set",
+ SESSION_VAR(collation_server), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null));
+
+static bool check_charset_db(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_charset_not_null(self, thd, var))
+ return true;
+ if (!var->value) // = DEFAULT
+ var->save_result.ptr= thd->db_charset;
+ return false;
+}
+static Sys_var_struct Sys_character_set_database(
+ "character_set_database",
+ " The character set used by the default database",
+ SESSION_VAR(collation_database), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_db));
+
+static bool check_cs_client(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_charset_not_null(self, thd, var))
+ return true;
+
+ // Currently, UCS-2 cannot be used as a client character set
+ if (((CHARSET_INFO *)(var->save_result.ptr))->mbminlen > 1)
+ return true;
+
+ return false;
+}
+static bool fix_thd_charset(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->update_charset();
+ return false;
+}
+static Sys_var_struct Sys_character_set_client(
+ "character_set_client", "The character set for statements "
+ "that arrive from the client",
+ SESSION_VAR(character_set_client), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_cs_client),
+ ON_UPDATE(fix_thd_charset));
+
+static Sys_var_struct Sys_character_set_connection(
+ "character_set_connection", "The character set used for "
+ "literals that do not have a character set introducer and for "
+ "number-to-string conversion",
+ SESSION_VAR(collation_connection), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_not_null),
+ ON_UPDATE(fix_thd_charset));
+
+static Sys_var_struct Sys_character_set_results(
+ "character_set_results", "The character set used for returning "
+ "query results to the client",
+ SESSION_VAR(character_set_results), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_charset));
+
+static Sys_var_struct Sys_character_set_filesystem(
+ "character_set_filesystem", "The filesystem character set",
+ SESSION_VAR(character_set_filesystem), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, csname), DEFAULT(&character_set_filesystem),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_charset_not_null),
+ ON_UPDATE(fix_thd_charset));
+
+static const char *completion_type_names[]= {"NO_CHAIN", "CHAIN", "RELEASE", 0};
+static Sys_var_enum Sys_completion_type(
+ "completion_type", "The transaction completion type, one of "
+ "NO_CHAIN, CHAIN, RELEASE",
+ SESSION_VAR(completion_type), CMD_LINE(REQUIRED_ARG),
+ completion_type_names, DEFAULT(0));
+
+static bool check_collation_not_null(sys_var *self, THD *thd, set_var *var)
+{
+ if (!var->value)
+ return false;
+
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ String str(buff, sizeof(buff), system_charset_info), *res;
+ if (!(res= var->value->val_str(&str)))
+ var->save_result.ptr= NULL;
+ else if (!(var->save_result.ptr= get_charset_by_name(res->c_ptr(), MYF(0))))
+ {
+ ErrConvString err(res);
+ my_error(ER_UNKNOWN_COLLATION, MYF(0), err.ptr());
+ return true;
+ }
+ }
+ else // INT_RESULT
+ {
+ int csno= (int)var->value->val_int();
+ if (!(var->save_result.ptr= get_charset(csno, MYF(0))))
+ {
+ my_error(ER_UNKNOWN_COLLATION, MYF(0), llstr(csno, buff));
+ return true;
+ }
+ }
+ return check_not_null(self, thd, var);
+}
+static Sys_var_struct Sys_collation_connection(
+ "collation_connection", "The collation of the connection "
+ "character set",
+ SESSION_VAR(collation_connection), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_not_null),
+ ON_UPDATE(fix_thd_charset));
+
+static bool check_collation_db(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_collation_not_null(self, thd, var))
+ return true;
+ if (!var->value) // = DEFAULT
+ var->save_result.ptr= thd->db_charset;
+ return false;
+}
+static Sys_var_struct Sys_collation_database(
+ "collation_database", "The collation of the database "
+ "character set",
+ SESSION_VAR(collation_database), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_db));
+
+static Sys_var_struct Sys_collation_server(
+ "collation_server", "The server default collation",
+ SESSION_VAR(collation_server), NO_CMD_LINE,
+ offsetof(CHARSET_INFO, name), DEFAULT(&default_charset_info),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_collation_not_null));
+
+static const char *concurrent_insert_names[]= {"NEVER", "AUTO", "ALWAYS", 0};
+static Sys_var_enum Sys_concurrent_insert(
+ "concurrent_insert", "Use concurrent insert with MyISAM. Possible "
+ "values are NEVER, AUTO, ALWAYS",
+ GLOBAL_VAR(myisam_concurrent_insert), CMD_LINE(OPT_ARG),
+ concurrent_insert_names, DEFAULT(1));
+
+static Sys_var_ulong Sys_connect_timeout(
+ "connect_timeout",
+ "The number of seconds the mysqld server is waiting for a connect "
+ "packet before responding with 'Bad handshake'",
+ GLOBAL_VAR(connect_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(2, LONG_TIMEOUT), DEFAULT(CONNECT_TIMEOUT), BLOCK_SIZE(1));
+
+static Sys_var_charptr Sys_datadir(
+ "datadir", "Path to the database root directory",
+ READ_ONLY GLOBAL_VAR(mysql_real_data_home_ptr),
+ CMD_LINE(REQUIRED_ARG, 'h'), IN_FS_CHARSET, DEFAULT(0));
+
+#ifndef DBUG_OFF
+static Sys_var_dbug Sys_dbug(
+ "debug", "Debug log", sys_var::SESSION,
+ CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_has_super));
+#endif
+
+/**
+ @todo
+ When updating myisam_delay_key_write, we should do a 'flush tables'
+ of all MyISAM tables to ensure that they are reopen with the
+ new attribute.
+*/
+export bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type)
+{
+ switch (delay_key_write_options) {
+ case DELAY_KEY_WRITE_NONE:
+ myisam_delay_key_write=0;
+ break;
+ case DELAY_KEY_WRITE_ON:
+ myisam_delay_key_write=1;
+ break;
+ case DELAY_KEY_WRITE_ALL:
+ myisam_delay_key_write=1;
+ ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
+ break;
+ }
+ return false;
+}
+static const char *delay_key_write_names[]= { "OFF", "ON", "ALL", NullS };
+static Sys_var_enum Sys_delay_key_write(
+ "delay_key_write", "Type of DELAY_KEY_WRITE",
+ GLOBAL_VAR(delay_key_write_options), CMD_LINE(OPT_ARG),
+ delay_key_write_names, DEFAULT(DELAY_KEY_WRITE_ON),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_delay_key_write));
+
+static Sys_var_ulong Sys_delayed_insert_limit(
+ "delayed_insert_limit",
+ "After inserting delayed_insert_limit rows, the INSERT DELAYED "
+ "handler will check if there are any SELECT statements pending. "
+ "If so, it allows these to execute before continuing",
+ GLOBAL_VAR(delayed_insert_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(DELAYED_LIMIT), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_delayed_insert_timeout(
+ "delayed_insert_timeout",
+ "How long a INSERT DELAYED thread should wait for INSERT statements "
+ "before terminating",
+ GLOBAL_VAR(delayed_insert_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(DELAYED_WAIT_TIMEOUT),
+ BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_delayed_queue_size(
+ "delayed_queue_size",
+ "What size queue (in rows) should be allocated for handling INSERT "
+ "DELAYED. If the queue becomes full, any client that does INSERT "
+ "DELAYED will wait until there is room in the queue again",
+ GLOBAL_VAR(delayed_queue_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1));
+
+#ifdef HAVE_EVENT_SCHEDULER
+static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED", NullS };
+static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var)
+{
+ /* DISABLED is only accepted on the command line */
+ if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED)
+ return true;
+ /*
+ If the scheduler was disabled because there are no/bad
+ system tables, produce a more meaningful error message
+ than ER_OPTION_PREVENTS_STATEMENT
+ */
+ if (Events::check_if_system_tables_error())
+ return true;
+ if (Events::opt_event_scheduler == Events::EVENTS_DISABLED)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
+ "--event-scheduler=DISABLED or --skip-grant-tables");
+ return true;
+ }
+ return false;
+}
+static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type)
+{
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ /*
+ Events::start() is heavyweight. In particular it creates a new THD,
+ which takes LOCK_global_system_variables internally.
+ Thus we have to release it here.
+ We need to re-take it before returning, though.
+ And we need to take it *without* holding Events::LOCK_event_metadata.
+ */
+ bool ret= Events::opt_event_scheduler == Events::EVENTS_ON
+ ? Events::start()
+ : Events::stop();
+ pthread_mutex_unlock(&Events::LOCK_event_metadata);
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ pthread_mutex_lock(&Events::LOCK_event_metadata);
+ if (ret)
+ my_error(ER_EVENT_SET_VAR_ERROR, MYF(0));
+ return ret;
+}
+static PolyLock_mutex PLock_event_metadata(&Events::LOCK_event_metadata);
+static Sys_var_enum Sys_event_scheduler(
+ "event_scheduler", "Enable the event scheduler. Possible values are "
+ "ON, OFF, and DISABLED (keep the event scheduler completely "
+ "deactivated, it cannot be activated run-time)",
+ GLOBAL_VAR(Events::opt_event_scheduler), CMD_LINE(OPT_ARG),
+ event_scheduler_names, DEFAULT(Events::EVENTS_OFF),
+ &PLock_event_metadata, NOT_IN_BINLOG,
+ ON_CHECK(event_scheduler_check), ON_UPDATE(event_scheduler_update));
+#endif
+
+static Sys_var_ulong Sys_expire_logs_days(
+ "expire_logs_days",
+ "If non-zero, binary logs will be purged after expire_logs_days "
+ "days; possible purges happen at startup and at binary log rotation",
+ GLOBAL_VAR(expire_logs_days),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 99), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_mybool Sys_flush(
+ "flush", "Flush MyISAM tables to disk between SQL commands",
+ GLOBAL_VAR(myisam_flush),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static Sys_var_ulong Sys_flush_time(
+ "flush_time",
+ "A dedicated thread is created to flush all tables at the "
+ "given interval",
+ GLOBAL_VAR(flush_time),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT),
+ DEFAULT(FLUSH_TIME), BLOCK_SIZE(1));
+
+static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var)
+{
+ return ft_boolean_check_syntax_string((uchar*)
+ (var->save_result.string_value.str));
+}
+static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type)
+{
+#ifdef HAVE_QUERY_CACHE
+ query_cache.flush();
+#endif /* HAVE_QUERY_CACHE */
+ return false;
+}
+/// @todo make SESSION_VAR (usability enhancement and a fix for a race condition)
+static Sys_var_charptr Sys_ft_boolean_syntax(
+ "ft_boolean_syntax", "List of operators for "
+ "MATCH ... AGAINST ( ... IN BOOLEAN MODE)",
+ GLOBAL_VAR(ft_boolean_syntax),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(DEFAULT_FTB_SYNTAX), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(check_ftb_syntax), ON_UPDATE(query_cache_flush));
+
+static Sys_var_ulong Sys_ft_max_word_len(
+ "ft_max_word_len",
+ "The maximum length of the word to be included in a FULLTEXT index. "
+ "Note: FULLTEXT indexes must be rebuilt after changing this variable",
+ READ_ONLY GLOBAL_VAR(ft_max_word_len), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(10, HA_FT_MAXCHARLEN), DEFAULT(HA_FT_MAXCHARLEN),
+ BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_ft_min_word_len(
+ "ft_min_word_len",
+ "The minimum length of the word to be included in a FULLTEXT index. "
+ "Note: FULLTEXT indexes must be rebuilt after changing this variable",
+ READ_ONLY GLOBAL_VAR(ft_min_word_len), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, HA_FT_MAXCHARLEN), DEFAULT(4), BLOCK_SIZE(1));
+
+/// @todo make it an updatable SESSION_VAR
+static Sys_var_ulong Sys_ft_query_expansion_limit(
+ "ft_query_expansion_limit",
+ "Number of best matches to use for query expansion",
+ READ_ONLY GLOBAL_VAR(ft_query_expansion_limit),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 1000), DEFAULT(20), BLOCK_SIZE(1));
+
+static Sys_var_charptr Sys_ft_stopword_file(
+ "ft_stopword_file",
+ "Use stopwords from this file instead of built-in list",
+ READ_ONLY GLOBAL_VAR(ft_stopword_file), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_mybool Sys_ignore_builtin_innodb(
+ "ignore_builtin_innodb",
+ "Disable initialization of builtin InnoDB plugin",
+ READ_ONLY GLOBAL_VAR(opt_ignore_builtin_innodb),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static bool check_init_string(sys_var *self, THD *thd, set_var *var)
+{
+ if (var->save_result.string_value.str == 0)
+ {
+ var->save_result.string_value.str= const_cast<char*>("");
+ var->save_result.string_value.length= 0;
+ }
+ return false;
+}
+static PolyLock_rwlock PLock_sys_init_connect(&LOCK_sys_init_connect);
+static Sys_var_lexstring Sys_init_connect(
+ "init_connect", "Command(s) that are executed for each "
+ "new connection", GLOBAL_VAR(opt_init_connect),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(""), &PLock_sys_init_connect, NOT_IN_BINLOG,
+ ON_CHECK(check_init_string));
+
+static Sys_var_charptr Sys_init_file(
+ "init_file", "Read SQL commands from this file at startup",
+ READ_ONLY GLOBAL_VAR(opt_init_file),
+ IF_DISABLE_GRANT_OPTIONS(NO_CMD_LINE, CMD_LINE(REQUIRED_ARG)),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static PolyLock_rwlock PLock_sys_init_slave(&LOCK_sys_init_slave);
+static Sys_var_lexstring Sys_init_slave(
+ "init_slave", "Command(s) that are executed by a slave server "
+ "each time the SQL thread starts", GLOBAL_VAR(opt_init_slave),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(""), &PLock_sys_init_slave,
+ NOT_IN_BINLOG, ON_CHECK(check_init_string));
+
+static Sys_var_ulong Sys_interactive_timeout(
+ "interactive_timeout",
+ "The number of seconds the server waits for activity on an interactive "
+ "connection before closing it",
+ SESSION_VAR(net_interactive_timeout),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_join_buffer_size(
+ "join_buffer_size",
+ "The size of the buffer that is used for full joins",
+ SESSION_VAR(join_buff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(128, ULONG_MAX), DEFAULT(128*1024), BLOCK_SIZE(128));
+
+static Sys_var_keycache Sys_key_buffer_size(
+ "key_buffer_size", "The size of the buffer used for "
+ "index blocks for MyISAM tables. Increase this to get better index "
+ "handling (for all reads and multiple writes) to as much as you can "
+ "afford",
+ KEYCACHE_VAR(param_buff_size),
+ CMD_LINE(REQUIRED_ARG, OPT_KEY_BUFFER_SIZE),
+ VALID_RANGE(0, SIZE_T_MAX), DEFAULT(KEY_CACHE_SIZE),
+ BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_buffer_size));
+
+static Sys_var_keycache Sys_key_cache_block_size(
+ "key_cache_block_size", "The default size of key cache blocks",
+ KEYCACHE_VAR(param_block_size),
+ CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_BLOCK_SIZE),
+ VALID_RANGE(512, 1024*16), DEFAULT(KEY_CACHE_BLOCK_SIZE),
+ BLOCK_SIZE(512), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_keycache_param));
+
+static Sys_var_keycache Sys_key_cache_division_limit(
+ "key_cache_division_limit",
+ "The minimum percentage of warm blocks in key cache",
+ KEYCACHE_VAR(param_division_limit),
+ CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_DIVISION_LIMIT),
+ VALID_RANGE(1, 100), DEFAULT(100),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_keycache_param));
+
+static Sys_var_keycache Sys_key_cache_age_threshold(
+ "key_cache_age_threshold", "This characterizes the number of "
+ "hits a hot block has to be untouched until it is considered aged "
+ "enough to be downgraded to a warm block. This specifies the "
+ "percentage ratio of that number of hits to the total number of "
+ "blocks in key cache",
+ KEYCACHE_VAR(param_age_threshold),
+ CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_AGE_THRESHOLD),
+ VALID_RANGE(100, ULONG_MAX), DEFAULT(300),
+ BLOCK_SIZE(100), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_keycache_param));
+
+static Sys_var_mybool Sys_large_files_support(
+ "large_files_support",
+ "Whether mysqld was compiled with options for large file support",
+ READ_ONLY GLOBAL_VAR(opt_large_files),
+ NO_CMD_LINE, DEFAULT(sizeof(my_off_t) > 4));
+
+static Sys_var_uint Sys_large_page_size(
+ "large_page_size",
+ "If large page support is enabled, this shows the size of memory pages",
+ READ_ONLY GLOBAL_VAR(opt_large_page_size), NO_CMD_LINE,
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_mybool Sys_large_pages(
+ "large_pages", "Enable support for large pages",
+ READ_ONLY GLOBAL_VAR(opt_large_files),
+ IF_WIN(NO_CMD_LINE, CMD_LINE(OPT_ARG)), DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_language(
+ "lc_messages_dir", "Directory where error messages are",
+ READ_ONLY GLOBAL_VAR(lc_messages_dir_ptr), CMD_LINE(REQUIRED_ARG, 'L'),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_mybool Sys_local_infile(
+ "local_infile", "Enable LOAD DATA LOCAL INFILE",
+ GLOBAL_VAR(opt_local_infile), CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+
+#ifdef HAVE_MLOCKALL
+static Sys_var_mybool Sys_locked_in_memory(
+ "locked_in_memory",
+ "Whether mysqld was locked in memory with --memlock",
+ READ_ONLY GLOBAL_VAR(locked_in_memory), NO_CMD_LINE, DEFAULT(FALSE));
+#endif
+
+/* this says NO_CMD_LINE, as command-line option takes a string, not a bool */
+static Sys_var_mybool Sys_log_bin(
+ "log_bin", "Whether the binary log is enabled",
+ READ_ONLY GLOBAL_VAR(opt_bin_log), NO_CMD_LINE, DEFAULT(FALSE));
+
+static Sys_var_mybool Sys_trust_function_creators(
+ "log_bin_trust_function_creators",
+ "If set to FALSE (the default), then when --log-bin is used, creation "
+ "of a stored function (or trigger) is allowed only to users having the "
+ "SUPER privilege and only if this stored function (trigger) may not "
+ "break binary logging. Note that if ALL connections to this server "
+ "ALWAYS use row-based binary logging, the security issues do not "
+ "exist and the binary logging cannot break, so you can safely set "
+ "this to TRUE",
+ GLOBAL_VAR(trust_function_creators),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_log_error(
+ "log_error", "Error log file",
+ READ_ONLY GLOBAL_VAR(log_error_file_ptr), CMD_LINE(OPT_ARG),
+ IN_FS_CHARSET, DEFAULT(disabled_my_option));
+
+static Sys_var_mybool Sys_log_queries_not_using_indexes(
+ "log_queries_not_using_indexes",
+ "Log queries that are executed without benefit of any index to the "
+ "slow log if it is open",
+ GLOBAL_VAR(opt_log_queries_not_using_indexes),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static Sys_var_ulong Sys_log_warnings(
+ "log_warnings",
+ "Log some not critical warnings to the log file",
+ SESSION_VAR(log_warnings),
+ CMD_LINE(OPT_ARG, 'W'),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(1), BLOCK_SIZE(1));
+
+static bool update_cached_long_query_time(sys_var *self, THD *thd,
+ enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->variables.long_query_time=
+ thd->variables.long_query_time_double * 1e6;
+ else
+ global_system_variables.long_query_time=
+ global_system_variables.long_query_time_double * 1e6;
+ return false;
+}
+
+static Sys_var_double Sys_long_query_time(
+ "long_query_time",
+ "Log all queries that have taken more than long_query_time seconds "
+ "to execute to file. The argument will be treated as a decimal value "
+ "with microsecond precision",
+ SESSION_VAR(long_query_time_double),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(10),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_cached_long_query_time));
+
+static bool fix_low_prio_updates(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->update_lock_default= (thd->variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+ else
+ thr_upgraded_concurrent_insert_lock=
+ (global_system_variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
+ return false;
+}
+static Sys_var_mybool Sys_low_priority_updates(
+ "low_priority_updates",
+ "INSERT/DELETE/UPDATE has lower priority than selects",
+ SESSION_VAR(low_priority_updates),
+ CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_low_prio_updates));
+
+#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
+static Sys_var_mybool Sys_sql_low_priority_updates(
+ "sql_low_priority_updates",
+ "INSERT/DELETE/UPDATE has lower priority than selects",
+ SESSION_VAR(low_priority_updates), NO_CMD_LINE,
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_low_prio_updates));
+#endif
+
+static Sys_var_mybool Sys_lower_case_file_system(
+ "lower_case_file_system",
+ "Case sensitivity of file names on the file system where the "
+ "data directory is located",
+ READ_ONLY GLOBAL_VAR(lower_case_file_system), NO_CMD_LINE,
+ DEFAULT(FALSE));
+
+static Sys_var_uint Sys_lower_case_table_names(
+ "lower_case_table_names",
+ "If set to 1 table names are stored in lowercase on disk and table "
+ "names will be case-insensitive. Should be set to 2 if you are using "
+ "a case insensitive file system",
+ READ_ONLY GLOBAL_VAR(lower_case_table_names),
+ CMD_LINE(OPT_ARG, OPT_LOWER_CASE_TABLE_NAMES),
+ VALID_RANGE(0, 2),
+#ifdef FN_NO_CASE_SENSE
+ DEFAULT(1),
+#else
+ DEFAULT(0),
+#endif
+ BLOCK_SIZE(1));
+
+static bool session_readonly(sys_var *self, THD *thd, set_var *var)
+{
+ if (var->type == OPT_GLOBAL)
+ return false;
+ my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION",
+ self->name.str, "GLOBAL");
+ return true;
+}
+static Sys_var_ulong Sys_max_allowed_packet(
+ "max_allowed_packet",
+ "Max packet length to send to or receive from the server",
+ SESSION_VAR(max_allowed_packet), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, 1024*1024*1024), DEFAULT(1024*1024),
+ BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(session_readonly));
+
+static Sys_var_ulonglong Sys_max_binlog_cache_size(
+ "max_binlog_cache_size",
+ "Can be used to restrict the total size used to cache a "
+ "multi-transaction query",
+ GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(IO_SIZE, ULONGLONG_MAX),
+ DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE),
+ BLOCK_SIZE(IO_SIZE));
+
+static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type)
+{
+ mysql_bin_log.set_max_size(max_binlog_size);
+#ifdef HAVE_REPLICATION
+ if (!max_relay_log_size)
+ active_mi->rli.relay_log.set_max_size(max_binlog_size);
+#endif
+ return false;
+}
+static Sys_var_ulong Sys_max_binlog_size(
+ "max_binlog_size",
+ "Binary log will be rotated automatically when the size exceeds this "
+ "value. Will also apply to relay logs if max_relay_log_size is 0",
+ GLOBAL_VAR(max_binlog_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(IO_SIZE, 1024*1024L*1024L), DEFAULT(1024*1024L*1024L),
+ BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_max_binlog_size));
+
+static bool fix_max_connections(sys_var *self, THD *thd, enum_var_type type)
+{
+#ifndef EMBEDDED_LIBRARY
+ resize_thr_alarm(max_connections +
+ global_system_variables.max_insert_delayed_threads + 10);
+#endif
+ return false;
+}
+
+// Default max_connections of 151 is larger than Apache's default max
+// children, to avoid "too many connections" error in a common setup
+static Sys_var_ulong Sys_max_connections(
+ "max_connections", "The number of simultaneous clients allowed",
+ GLOBAL_VAR(max_connections), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 100000), DEFAULT(151), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_max_connections));
+
+static Sys_var_ulong Sys_max_connect_errors(
+ "max_connect_errors",
+ "If there is more than this number of interrupted connections from "
+ "a host this host will be blocked from further connections",
+ GLOBAL_VAR(max_connect_errors), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(MAX_CONNECT_ERRORS),
+ BLOCK_SIZE(1));
+
+static bool check_max_delayed_threads(sys_var *self, THD *thd, set_var *var)
+{
+ return var->type != OPT_GLOBAL &&
+ var->save_result.ulonglong_value != 0 &&
+ var->save_result.ulonglong_value !=
+ global_system_variables.max_insert_delayed_threads;
+}
+
+// Alias for max_delayed_threads
+static Sys_var_ulong Sys_max_insert_delayed_threads(
+ "max_insert_delayed_threads",
+ "Don't start more than this number of threads to handle INSERT "
+ "DELAYED statements. If set to zero INSERT DELAYED will be not used",
+ SESSION_VAR(max_insert_delayed_threads),
+ NO_CMD_LINE, VALID_RANGE(0, 16384), DEFAULT(20),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_max_delayed_threads), ON_UPDATE(fix_max_connections));
+
+static Sys_var_ulong Sys_max_delayed_threads(
+ "max_delayed_threads",
+ "Don't start more than this number of threads to handle INSERT "
+ "DELAYED statements. If set to zero INSERT DELAYED will be not used",
+ SESSION_VAR(max_insert_delayed_threads),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 16384), DEFAULT(20),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_max_delayed_threads), ON_UPDATE(fix_max_connections));
+
+static Sys_var_ulong Sys_max_error_count(
+ "max_error_count",
+ "Max number of errors/warnings to store for a statement",
+ SESSION_VAR(max_error_count), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 65535), DEFAULT(DEFAULT_ERROR_COUNT), BLOCK_SIZE(1));
+
+static Sys_var_ulonglong Sys_max_heap_table_size(
+ "max_heap_table_size",
+ "Don't allow creation of heap tables bigger than this",
+ SESSION_VAR(max_heap_table_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(16384, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
+ BLOCK_SIZE(1024));
+
+static Sys_var_ulong Sys_pseudo_thread_id(
+ "pseudo_thread_id",
+ "This variable is for internal server use",
+ SESSION_ONLY(pseudo_thread_id),
+ NO_CMD_LINE, VALID_RANGE(0, ULONG_MAX), DEFAULT(0),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
+ ON_CHECK(check_has_super));
+
+static bool fix_max_join_size(sys_var *self, THD *thd, enum_var_type type)
+{
+ SV *sv= type == OPT_GLOBAL ? &global_system_variables : &thd->variables;
+ if (sv->max_join_size == HA_POS_ERROR)
+ sv->option_bits|= OPTION_BIG_SELECTS;
+ else
+ sv->option_bits&= ~OPTION_BIG_SELECTS;
+ return false;
+}
+static Sys_var_harows Sys_max_join_size(
+ "max_join_size",
+ "Joins that are probably going to read more than max_join_size "
+ "records return an error",
+ SESSION_VAR(max_join_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_max_join_size));
+
+static Sys_var_ulong Sys_max_seeks_for_key(
+ "max_seeks_for_key",
+ "Limit assumed max number of seeks when looking up rows based on a key",
+ SESSION_VAR(max_seeks_for_key), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(ULONG_MAX), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_max_length_for_sort_data(
+ "max_length_for_sort_data",
+ "Max number of bytes in sorted records",
+ SESSION_VAR(max_length_for_sort_data), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(4, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
+
+static Sys_var_harows Sys_sql_max_join_size(
+ "sql_max_join_size", "Alias for max_join_size",
+ SESSION_VAR(max_join_size), NO_CMD_LINE,
+ VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_max_join_size), DEPRECATED(70000, 0));
+
+static PolyLock_mutex PLock_prepared_stmt_count(&LOCK_prepared_stmt_count);
+static Sys_var_ulong Sys_max_prepared_stmt_count(
+ "max_prepared_stmt_count",
+ "Maximum number of prepared statements in the server",
+ GLOBAL_VAR(max_prepared_stmt_count), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 1024*1024), DEFAULT(16382), BLOCK_SIZE(1),
+ &PLock_prepared_stmt_count);
+
+static bool fix_max_relay_log_size(sys_var *self, THD *thd, enum_var_type type)
+{
+#ifdef HAVE_REPLICATION
+ active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
+ max_relay_log_size: max_binlog_size);
+#endif
+ return false;
+}
+static Sys_var_ulong Sys_max_relay_log_size(
+ "max_relay_log_size",
+ "If non-zero: relay log will be rotated automatically when the "
+ "size exceeds this value; if zero: when the size "
+ "exceeds max_binlog_size",
+ GLOBAL_VAR(max_relay_log_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 1024L*1024*1024), DEFAULT(0), BLOCK_SIZE(IO_SIZE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_max_relay_log_size));
+
+static Sys_var_ulong Sys_max_sort_length(
+ "max_sort_length",
+ "The number of bytes to use when sorting BLOB or TEXT values (only "
+ "the first max_sort_length bytes of each value are used; the rest "
+ "are ignored)",
+ SESSION_VAR(max_sort_length), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(4, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_max_sp_recursion_depth(
+ "max_sp_recursion_depth",
+ "Maximum stored procedure recursion depth",
+ SESSION_VAR(max_sp_recursion_depth), CMD_LINE(OPT_ARG),
+ VALID_RANGE(0, 255), DEFAULT(0), BLOCK_SIZE(1));
+
+// non-standard session_value_ptr() here
+static Sys_var_max_user_conn Sys_max_user_connections(
+ "max_user_connections",
+ "The maximum number of active connections for a single user "
+ "(0 = no limit)",
+ SESSION_VAR(max_user_connections), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(session_readonly));
+
+static Sys_var_ulong Sys_max_tmp_tables(
+ "max_tmp_tables",
+ "Maximum number of temporary tables a client can keep open at a time",
+ SESSION_VAR(max_tmp_tables), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(32), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_max_write_lock_count(
+ "max_write_lock_count",
+ "After this many write locks, allow some read locks to run in between",
+ GLOBAL_VAR(max_write_lock_count), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(ULONG_MAX), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_min_examined_row_limit(
+ "min_examined_row_limit",
+ "Don't write queries to slow log that examine fewer rows "
+ "than that",
+ SESSION_VAR(min_examined_row_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+#ifdef _WIN32
+static Sys_var_mybool Sys_named_pipe(
+ "named_pipe", "Enable the named pipe (NT)",
+ READ_ONLY GLOBAL_VAR(opt_enable_named_pipe), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+#endif
+
+static Sys_var_ulong Sys_net_buffer_length(
+ "net_buffer_length",
+ "Buffer length for TCP/IP and socket communication",
+ SESSION_VAR(net_buffer_length), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, 1024*1024), DEFAULT(16384), BLOCK_SIZE(1024),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(session_readonly));
+
+static bool fix_net_read_timeout(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
+ return false;
+}
+static Sys_var_ulong Sys_net_read_timeout(
+ "net_read_timeout",
+ "Number of seconds to wait for more data from a connection before "
+ "aborting the read",
+ SESSION_VAR(net_read_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_READ_TIMEOUT), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_net_read_timeout));
+
+static bool fix_net_write_timeout(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
+ return false;
+}
+static Sys_var_ulong Sys_net_write_timeout(
+ "net_write_timeout",
+ "Number of seconds to wait for a block to be written to a connection "
+ "before aborting the write",
+ SESSION_VAR(net_write_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WRITE_TIMEOUT), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_net_write_timeout));
+
+static bool fix_net_retry_count(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ thd->net.retry_count=thd->variables.net_retry_count;
+ return false;
+}
+static Sys_var_ulong Sys_net_retry_count(
+ "net_retry_count",
+ "If a read on a communication port is interrupted, retry this "
+ "many times before giving up",
+ SESSION_VAR(net_retry_count), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(MYSQLD_NET_RETRY_COUNT),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_net_retry_count));
+
+static Sys_var_mybool Sys_new_mode(
+ "new", "Use very new possible \"unsafe\" functions",
+ SESSION_VAR(new_mode), CMD_LINE(OPT_ARG, 'n'), DEFAULT(FALSE));
+
+static Sys_var_mybool Sys_old_mode(
+ "old", "Use compatible behavior",
+ READ_ONLY GLOBAL_VAR(old_mode), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static Sys_var_mybool Sys_old_alter_table(
+ "old_alter_table", "Use old, non-optimized alter table",
+ SESSION_VAR(old_alter_table), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static bool check_old_passwords(sys_var *self, THD *thd, set_var *var)
+{
+ return mysql_user_table_is_in_short_password_format;
+}
+static Sys_var_mybool Sys_old_passwords(
+ "old_passwords",
+ "Use old password encryption method (needed for 4.0 and older clients)",
+ SESSION_VAR(old_passwords), CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_old_passwords));
+
+static Sys_var_ulong Sys_open_files_limit(
+ "open_files_limit",
+ "If this is not 0, then mysqld will use this value to reserve file "
+ "descriptors to use with setrlimit(). If this value is 0 then mysqld "
+ "will reserve max_connections*5 or max_connections + table_cache*2 "
+ "(whichever is larger) number of file descriptors",
+ READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, OS_FILE_LIMIT), DEFAULT(0), BLOCK_SIZE(1));
+
+/// @todo change to enum
+static Sys_var_ulong Sys_optimizer_prune_level(
+ "optimizer_prune_level",
+ "Controls the heuristic(s) applied during query optimization to prune "
+ "less-promising partial plans from the optimizer search space. "
+ "Meaning: 0 - do not apply any heuristic, thus perform exhaustive "
+ "search; 1 - prune plans based on number of retrieved rows",
+ SESSION_VAR(optimizer_prune_level), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 1), DEFAULT(1), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_optimizer_search_depth(
+ "optimizer_search_depth",
+ "Maximum depth of search performed by the query optimizer. Values "
+ "larger than the number of relations in a query result in better "
+ "query plans, but take longer to compile a query. Values smaller "
+ "than the number of tables in a relation result in faster "
+ "optimization, but may produce very bad query plans. If set to 0, "
+ "the system will automatically pick a reasonable value; if set to "
+ "63, the optimizer will switch to the original find_best search"
+ "(used for testing/comparison)",
+ SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, MAX_TABLES+2), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1));
+
+static const char *optimizer_switch_names[]=
+{
+ "index_merge", "index_merge_union", "index_merge_sort_union",
+ "index_merge_intersection",
+ "default", NullS
+};
+static Sys_var_flagset Sys_optimizer_switch(
+ "optimizer_switch",
+ "optimizer_switch=option=val[,option=val...], where option is one of "
+ "{index_merge, index_merge_union, index_merge_sort_union, "
+ "index_merge_intersection} and val is one of {on, off, default}",
+ SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG),
+ optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT));
+
+static Sys_var_charptr Sys_pid_file(
+ "pid_file", "Pid file used by safe_mysqld",
+ READ_ONLY GLOBAL_VAR(pidfile_name_ptr), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_plugin_dir(
+ "plugin_dir", "Directory for plugins",
+ READ_ONLY GLOBAL_VAR(opt_plugin_dir_ptr), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_uint Sys_port(
+ "port",
+ "Port number to use for connection or 0 to default to, "
+ "my.cnf, $MYSQL_TCP_PORT, "
+#if MYSQL_PORT_DEFAULT == 0
+ "/etc/services, "
+#endif
+ "built-in default (" STRINGIFY_ARG(MYSQL_PORT) "), whatever comes first",
+ READ_ONLY GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'),
+ VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_preload_buff_size(
+ "preload_buffer_size",
+ "The size of the buffer that is allocated when preloading indexes",
+ SESSION_VAR(preload_buff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, 1024*1024*1024), DEFAULT(32768), BLOCK_SIZE(1));
+
+static Sys_var_uint Sys_protocol_version(
+ "protocol_version",
+ "The version of the client/server protocol used by the MySQL server",
+ READ_ONLY GLOBAL_VAR(protocol_version), NO_CMD_LINE,
+ VALID_RANGE(0, ~0), DEFAULT(PROTOCOL_VERSION), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_read_buff_size(
+ "read_buffer_size",
+ "Each thread that does a sequential scan allocates a buffer of "
+ "this size for each table it scans. If you do many sequential scans, "
+ "you may want to increase this value",
+ SESSION_VAR(read_buff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(IO_SIZE*2, INT_MAX32), DEFAULT(128*1024),
+ BLOCK_SIZE(IO_SIZE));
+
+static my_bool read_only;
+static bool check_read_only(sys_var *self, THD *thd, set_var *var)
+{
+ /* Prevent self dead-lock */
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ return true;
+ }
+ return false;
+}
+static bool fix_read_only(sys_var *self, THD *thd, enum_var_type type)
+{
+ bool result= true;
+ my_bool new_read_only= read_only; // make a copy before releasing a mutex
+ DBUG_ENTER("sys_var_opt_readonly::update");
+
+ if (read_only == FALSE || read_only == opt_readonly)
+ {
+ opt_readonly= read_only;
+ DBUG_RETURN(false);
+ }
+
+ if (check_read_only(self, thd, 0)) // just in case
+ goto end;
+
+ if (thd->global_read_lock)
+ {
+ /*
+ This connection already holds the global read lock.
+ This can be the case with:
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = 1
+ */
+ opt_readonly= read_only;
+ DBUG_RETURN(false);
+ }
+
+ /*
+ Perform a 'FLUSH TABLES WITH READ LOCK'.
+ This is a 3 step process:
+ - [1] lock_global_read_lock()
+ - [2] close_cached_tables()
+ - [3] make_global_read_lock_block_commit()
+ [1] prevents new connections from obtaining tables locked for write.
+ [2] waits until all existing connections close their tables.
+ [3] prevents transactions from being committed.
+ */
+
+ read_only= opt_readonly;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+
+ if (lock_global_read_lock(thd))
+ goto end_with_mutex_unlock;
+
+ /*
+ This call will be blocked by any connection holding a READ or WRITE lock.
+ Ideally, we want to wait only for pending WRITE locks, but since:
+ con 1> LOCK TABLE T FOR READ;
+ con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
+ con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
+ can cause to wait on a read lock, it's required for the client application
+ to unlock everything, and acceptable for the server to wait on all locks.
+ */
+ if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)))
+ goto end_with_read_lock;
+
+ if ((result= make_global_read_lock_block_commit(thd)))
+ goto end_with_read_lock;
+
+ /* Change the opt_readonly system variable, safe because the lock is held */
+ opt_readonly= new_read_only;
+ result= false;
+
+ end_with_read_lock:
+ /* Release the lock */
+ unlock_global_read_lock(thd);
+ end_with_mutex_unlock:
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ end:
+ read_only= opt_readonly;
+ DBUG_RETURN(result);
+}
+static Sys_var_mybool Sys_readonly(
+ "read_only",
+ "Make all non-temporary tables read-only, with the exception for "
+ "replication (slave) threads and users with the SUPER privilege",
+ GLOBAL_VAR(read_only), CMD_LINE(OPT_ARG), DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
+
+// Small lower limit to be able to test MRR
+static Sys_var_ulong Sys_read_rnd_buff_size(
+ "read_rnd_buffer_size",
+ "When reading rows in sorted order after a sort, the rows are read "
+ "through this buffer to avoid a disk seeks. If not set, then it's "
+ "set to the value of record_buffer",
+ SESSION_VAR(read_rnd_buff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, INT_MAX32), DEFAULT(256*1024), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_div_precincrement(
+ "div_precision_increment", "Precision of the result of '/' "
+ "operator will be increased on that value",
+ SESSION_VAR(div_precincrement), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, DECIMAL_MAX_SCALE), DEFAULT(4), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_rpl_recovery_rank(
+ "rpl_recovery_rank", "Unused, will be removed",
+ GLOBAL_VAR(rpl_recovery_rank), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
+ DEPRECATED(70000, 0));
+
+static Sys_var_ulong Sys_range_alloc_block_size(
+ "range_alloc_block_size",
+ "Allocation block size for storing ranges during optimization",
+ SESSION_VAR(range_alloc_block_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX),
+ DEFAULT(RANGE_ALLOC_BLOCK_SIZE), BLOCK_SIZE(1024));
+
+static Sys_var_ulong Sys_multi_range_count(
+ "multi_range_count", "Number of key ranges to request at once",
+ SESSION_VAR(multi_range_count), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, ULONG_MAX), DEFAULT(256), BLOCK_SIZE(1));
+
+static bool fix_thd_mem_root(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ reset_root_defaults(thd->mem_root,
+ thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+ return false;
+}
+static Sys_var_ulong Sys_query_alloc_block_size(
+ "query_alloc_block_size",
+ "Allocation block size for query parsing and execution",
+ SESSION_VAR(query_alloc_block_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, ULONG_MAX), DEFAULT(QUERY_ALLOC_BLOCK_SIZE),
+ BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_thd_mem_root));
+
+static Sys_var_ulong Sys_query_prealloc_size(
+ "query_prealloc_size",
+ "Persistent buffer for query parsing and execution",
+ SESSION_VAR(query_prealloc_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(QUERY_ALLOC_PREALLOC_SIZE, ULONG_MAX),
+ DEFAULT(QUERY_ALLOC_PREALLOC_SIZE),
+ BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_thd_mem_root));
+
+#ifdef HAVE_SMEM
+static Sys_var_mybool Sys_shared_memory(
+ "shared_memory", "Enable the shared memory",
+ READ_ONLY GLOBAL_VAR(opt_enable_shared_memory), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_shared_memory_base_name(
+ "shared_memory_base_name", "Base name of shared memory",
+ READ_ONLY GLOBAL_VAR(shared_memory_base_name), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+#endif
+
+// this has to be NO_CMD_LINE as the command-line option has a different name
+static Sys_var_mybool Sys_skip_external_locking(
+ "skip_external_locking", "Don't use system (external) locking",
+ READ_ONLY GLOBAL_VAR(my_disable_locking), NO_CMD_LINE, DEFAULT(TRUE));
+
+static Sys_var_mybool Sys_skip_networking(
+ "skip_networking", "Don't allow connection with TCP/IP",
+ READ_ONLY GLOBAL_VAR(opt_disable_networking), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+static Sys_var_mybool Sys_skip_show_database(
+ "skip_show_database", "Don't allow 'SHOW DATABASE' commands",
+ READ_ONLY GLOBAL_VAR(opt_skip_show_db), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_socket(
+ "socket", "Socket file to use for connection",
+ READ_ONLY GLOBAL_VAR(mysqld_unix_port), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+#ifdef HAVE_THR_SETCONCURRENCY
+static Sys_var_ulong Sys_thread_concurrency(
+ "thread_concurrency",
+ "Permits the application to give the threads system a hint for "
+ "the desired number of threads that should be run at the same time",
+ READ_ONLY GLOBAL_VAR(concurrency), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 512), DEFAULT(DEFAULT_CONCURRENCY), BLOCK_SIZE(1));
+#endif
+
+static Sys_var_ulong Sys_thread_stack(
+ "thread_stack", "The stack size for each thread",
+ READ_ONLY GLOBAL_VAR(my_thread_stack_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(128*1024, ULONG_MAX), DEFAULT(DEFAULT_THREAD_STACK),
+ BLOCK_SIZE(1024));
+
+static Sys_var_charptr Sys_tmpdir(
+ "tmpdir", "Path for temporary files. Several paths may "
+ "be specified, separated by a "
+#if defined(__WIN__) || defined(__NETWARE__)
+ "semicolon (;)"
+#else
+ "colon (:)"
+#endif
+ ", in this case they are used in a round-robin fashion",
+ READ_ONLY GLOBAL_VAR(opt_mysql_tmpdir), CMD_LINE(REQUIRED_ARG, 't'),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static bool fix_trans_mem_root(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ reset_root_defaults(&thd->transaction.mem_root,
+ thd->variables.trans_alloc_block_size,
+ thd->variables.trans_prealloc_size);
+ return false;
+}
+static Sys_var_ulong Sys_trans_alloc_block_size(
+ "transaction_alloc_block_size",
+ "Allocation block size for transactions to be stored in binary log",
+ SESSION_VAR(trans_alloc_block_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, ULONG_MAX), DEFAULT(QUERY_ALLOC_BLOCK_SIZE),
+ BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_trans_mem_root));
+
+static Sys_var_ulong Sys_trans_prealloc_size(
+ "transaction_prealloc_size",
+ "Persistent buffer for transactions to be stored in binary log",
+ SESSION_VAR(trans_prealloc_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, ULONG_MAX), DEFAULT(TRANS_ALLOC_PREALLOC_SIZE),
+ BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_trans_mem_root));
+
+static const char *thread_handling_names[]=
+{
+ "one-thread-per-connection", "no-threads",
+#if HAVE_POOL_OF_THREADS == 1
+ "pool-of-threads",
+#endif
+ 0
+};
+static Sys_var_enum Sys_thread_handling(
+ "thread_handling",
+ "Define threads usage for handling queries, one of "
+ "one-thread-per-connection, no-threads"
+#if HAVE_POOL_OF_THREADS == 1
+ ", pool-of-threads"
+#endif
+ , READ_ONLY GLOBAL_VAR(thread_handling), CMD_LINE(REQUIRED_ARG),
+ thread_handling_names, DEFAULT(0));
+
+#ifdef HAVE_QUERY_CACHE
+static bool fix_query_cache_size(sys_var *self, THD *thd, enum_var_type type)
+{
+ ulong new_cache_size= query_cache.resize(query_cache_size);
+ /*
+ Note: query_cache_size is a global variable reflecting the
+ requested cache size. See also query_cache_size_arg
+ */
+ if (query_cache_size != new_cache_size)
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
+ query_cache_size, new_cache_size);
+
+ query_cache_size= new_cache_size;
+ return false;
+}
+static Sys_var_ulong Sys_query_cache_size(
+ "query_cache_size",
+ "The memory allocated to store results from old queries",
+ GLOBAL_VAR(query_cache_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1024),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_query_cache_size));
+
+static Sys_var_ulong Sys_query_cache_limit(
+ "query_cache_limit",
+ "Don't cache results that are bigger than this",
+ GLOBAL_VAR(query_cache.query_cache_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(1024*1024), BLOCK_SIZE(1));
+
+static bool fix_qcache_min_res_unit(sys_var *self, THD *thd, enum_var_type type)
+{
+ query_cache_min_res_unit=
+ query_cache.set_min_res_unit(query_cache_min_res_unit);
+ return false;
+}
+static Sys_var_ulong Sys_query_cache_min_res_unit(
+ "query_cache_min_res_unit",
+ "The minimum size for blocks allocated by the query cache",
+ GLOBAL_VAR(query_cache_min_res_unit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(QUERY_CACHE_MIN_RESULT_DATA_SIZE),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_qcache_min_res_unit));
+
+static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", 0 };
+static bool check_query_cache_type(sys_var *self, THD *thd, set_var *var)
+{
+ if (query_cache.is_disabled())
+ {
+ my_error(ER_QUERY_CACHE_DISABLED, MYF(0));
+ return true;
+ }
+ return false;
+}
+static Sys_var_enum Sys_query_cache_type(
+ "query_cache_type",
+ "OFF = Don't cache or retrieve results. ON = Cache all results "
+ "except SELECT SQL_NO_CACHE ... queries. DEMAND = Cache only "
+ "SELECT SQL_CACHE ... queries",
+ SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG),
+ query_cache_type_names, DEFAULT(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_query_cache_type));
+
+static Sys_var_mybool Sys_query_cache_wlock_invalidate(
+ "query_cache_wlock_invalidate",
+ "Invalidate queries in query cache on LOCK for write",
+ SESSION_VAR(query_cache_wlock_invalidate), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+#endif /* HAVE_QUERY_CACHE */
+
+static Sys_var_mybool Sys_secure_auth(
+ "secure_auth",
+ "Disallow authentication for accounts that have old (pre-4.1) "
+ "passwords",
+ GLOBAL_VAR(opt_secure_auth), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_secure_file_priv(
+ "secure_file_priv",
+ "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files "
+ "within specified directory",
+ PREALLOCATED READ_ONLY GLOBAL_VAR(opt_secure_file_priv),
+ CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0));
+
+static bool fix_server_id(sys_var *self, THD *thd, enum_var_type type)
+{
+ server_id_supplied = 1;
+ thd->server_id= server_id;
+ return false;
+}
+static Sys_var_ulong Sys_server_id(
+ "server_id",
+ "Uniquely identifies the server instance in the community of "
+ "replication partners",
+ GLOBAL_VAR(server_id), CMD_LINE(REQUIRED_ARG, OPT_SERVER_ID),
+ VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_server_id));
+
+static Sys_var_mybool Sys_slave_compressed_protocol(
+ "slave_compressed_protocol",
+ "Use compression on master/slave protocol",
+ GLOBAL_VAR(opt_slave_compressed_protocol), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+#ifdef HAVE_REPLICATION
+static const char *slave_exec_mode_names[]= {"STRICT", "IDEMPOTENT", 0};
+static Sys_var_enum Slave_exec_mode(
+ "slave_exec_mode",
+ "Modes for how replication events should be executed. Legal values "
+ "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, "
+ "replication will not stop for operations that are idempotent. "
+ "In STRICT mode, replication will stop on any unexpected difference "
+ "between the master and the slave",
+ GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG),
+ slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_STRICT));
+#endif
+
+static Sys_var_ulong Sys_slow_launch_time(
+ "slow_launch_time",
+ "If creating the thread takes longer than this value (in seconds), "
+ "the Slow_launch_threads counter will be incremented",
+ GLOBAL_VAR(slow_launch_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(2), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_sort_buffer(
+ "sort_buffer_size",
+ "Each thread that needs to do a sort allocates a buffer of this size",
+ SESSION_VAR(sortbuff_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(MIN_SORT_MEMORY, ULONG_MAX), DEFAULT(MAX_SORT_MEMORY),
+ BLOCK_SIZE(1));
+
+export ulong expand_sql_mode(ulonglong sql_mode)
+{
+ if (sql_mode & MODE_ANSI)
+ {
+ /*
+ Note that we dont set
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
+ to allow one to get full use of MySQL in this mode.
+
+ MODE_ONLY_FULL_GROUP_BY was removed from ANSI mode because it is
+ currently overly restrictive (see BUG#8510).
+ */
+ sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE);
+ }
+ if (sql_mode & MODE_ORACLE)
+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE |
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
+ if (sql_mode & MODE_MSSQL)
+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE |
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
+ MODE_NO_FIELD_OPTIONS);
+ if (sql_mode & MODE_POSTGRESQL)
+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE |
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
+ MODE_NO_FIELD_OPTIONS);
+ if (sql_mode & MODE_DB2)
+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE |
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
+ MODE_NO_FIELD_OPTIONS);
+ if (sql_mode & MODE_MAXDB)
+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
+ MODE_IGNORE_SPACE |
+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
+ if (sql_mode & MODE_MYSQL40)
+ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
+ if (sql_mode & MODE_MYSQL323)
+ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
+ if (sql_mode & MODE_TRADITIONAL)
+ sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
+ MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER |
+ MODE_NO_ENGINE_SUBSTITUTION);
+ return sql_mode;
+}
+static bool check_sql_mode(sys_var *self, THD *thd, set_var *var)
+{
+ var->save_result.ulonglong_value=
+ expand_sql_mode(var->save_result.ulonglong_value);
+ return false;
+}
+static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL)
+ {
+ /* Update thd->server_status */
+ if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
+ thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ else
+ thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ }
+ return false;
+}
+/*
+ WARNING: When adding new SQL modes don't forget to update the
+ tables definitions that stores it's value (ie: mysql.event, mysql.proc)
+*/
+static const char *sql_mode_names[]=
+{
+ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", ",",
+ "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", "NO_DIR_IN_CREATE",
+ "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
+ "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
+ "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
+ "STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE",
+ "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL",
+ "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION",
+ "PAD_CHAR_TO_FULL_LENGTH",
+ 0
+};
+export bool sql_mode_string_representation(THD *thd, ulong sql_mode,
+ LEX_STRING *ls)
+{
+ set_to_string(thd, ls, sql_mode, sql_mode_names);
+ return ls->str == 0;
+}
+/*
+ sql_mode should *not* be IN_BINLOG: even though it is written to the binlog,
+ the slave ignores the MODE_NO_DIR_IN_CREATE variable, so slave's value
+ differs from master's (see log_event.cc: Query_log_event::do_apply_event()).
+*/
+static Sys_var_set Sys_sql_mode(
+ "sql_mode",
+ "Syntax: sql-mode=mode[,mode[,mode...]]. See the manual for the "
+ "complete list of valid sql modes",
+ SESSION_VAR(sql_mode), CMD_LINE(REQUIRED_ARG),
+ sql_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_sql_mode), ON_UPDATE(fix_sql_mode));
+
+static Sys_var_charptr Sys_ssl_ca(
+ "ssl_ca",
+ "CA file in PEM format (check OpenSSL docs, implies --ssl)",
+ READ_ONLY GLOBAL_VAR(opt_ssl_ca), CMD_LINE(REQUIRED_ARG, OPT_SSL_CA),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_ssl_capath(
+ "ssl_capath",
+ "CA directory (check OpenSSL docs, implies --ssl)",
+ READ_ONLY GLOBAL_VAR(opt_ssl_capath),
+ CMD_LINE(REQUIRED_ARG, OPT_SSL_CAPATH), IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_ssl_cert(
+ "ssl_cert", "X509 cert in PEM format (implies --ssl)",
+ READ_ONLY GLOBAL_VAR(opt_ssl_cert), CMD_LINE(REQUIRED_ARG, OPT_SSL_CERT),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_ssl_cipher(
+ "ssl_cipher", "SSL cipher to use (implies --ssl)",
+ READ_ONLY GLOBAL_VAR(opt_ssl_cipher),
+ CMD_LINE(REQUIRED_ARG, OPT_SSL_CIPHER), IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_ssl_key(
+ "ssl_key", "X509 key in PEM format (implies --ssl)",
+ READ_ONLY GLOBAL_VAR(opt_ssl_key), CMD_LINE(REQUIRED_ARG, OPT_SSL_KEY),
+ IN_FS_CHARSET, DEFAULT(0));
+
+// why ENUM and not BOOL ?
+static const char *updatable_views_with_limit_names[]= {"NO", "YES", 0};
+static Sys_var_enum Sys_updatable_views_with_limit(
+ "updatable_views_with_limit",
+ "YES = Don't issue an error message (warning only) if a VIEW without "
+ "presence of a key of the underlying table is used in queries with a "
+ "LIMIT clause for updating. NO = Prohibit update of a VIEW, which "
+ "does not contain a key of the underlying table and the query uses "
+ "a LIMIT clause (usually get from GUI tools)",
+ SESSION_VAR(updatable_views_with_limit), CMD_LINE(REQUIRED_ARG),
+ updatable_views_with_limit_names, DEFAULT(TRUE));
+
+static Sys_var_mybool Sys_sync_frm(
+ "sync_frm", "Sync .frm files to disk on creation",
+ GLOBAL_VAR(opt_sync_frm), CMD_LINE(OPT_ARG),
+ DEFAULT(TRUE));
+
+static char *system_time_zone_ptr;
+static Sys_var_charptr Sys_system_time_zone(
+ "system_time_zone", "The server system time zone",
+ READ_ONLY GLOBAL_VAR(system_time_zone_ptr), NO_CMD_LINE,
+ IN_FS_CHARSET, DEFAULT(system_time_zone));
+
+static Sys_var_ulong Sys_table_def_size(
+ "table_definition_cache",
+ "The number of cached table definitions",
+ GLOBAL_VAR(table_def_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(TABLE_DEF_CACHE_MIN, 512*1024),
+ DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_table_cache_size(
+ "table_open_cache", "The number of cached open tables",
+ GLOBAL_VAR(table_cache_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 512*1024), DEFAULT(TABLE_OPEN_CACHE_DEFAULT),
+ BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_table_lock_wait_timeout(
+ "table_lock_wait_timeout",
+ "Timeout in seconds to wait for a table level lock before returning an "
+ "error. Used only if the connection has active cursors",
+ GLOBAL_VAR(table_lock_wait_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 1024*1024*1024), DEFAULT(50), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_thread_cache_size(
+ "thread_cache_size",
+ "How many threads we should keep in a cache for reuse",
+ GLOBAL_VAR(thread_cache_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 16384), DEFAULT(0), BLOCK_SIZE(1));
+
+#if HAVE_POOL_OF_THREADS == 1
+static Sys_var_ulong Sys_thread_pool_size(
+ "thread_pool_size",
+ "How many threads we should create to handle query requests in "
+ "case of 'thread_handling=pool-of-threads'",
+ GLOBAL_VAR(thread_pool_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, 16384), DEFAULT(20), BLOCK_SIZE(0));
+#endif
+
+// Can't change the 'next' tx_isolation if we are already in a transaction
+static bool check_tx_isolation(sys_var *self, THD *thd, set_var *var)
+{
+ if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
+ {
+ my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
+ return true;
+ }
+ return false;
+}
+
+/*
+ If one doesn't use the SESSION modifier, the isolation level
+ is only active for the next command.
+*/
+static bool fix_tx_isolation(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_SESSION)
+ thd->session_tx_isolation= (enum_tx_isolation)thd->variables.tx_isolation;
+ return false;
+}
+// NO_CMD_LINE - different name of the option
+static Sys_var_enum Sys_tx_isolation(
+ "tx_isolation", "Default transaction isolation level",
+ SESSION_VAR(tx_isolation), NO_CMD_LINE,
+ tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_tx_isolation),
+ ON_UPDATE(fix_tx_isolation));
+
+static Sys_var_ulonglong Sys_tmp_table_size(
+ "tmp_table_size",
+ "If an internal in-memory temporary table exceeds this size, MySQL "
+ "will automatically convert it to an on-disk MyISAM table",
+ SESSION_VAR(tmp_table_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(16*1024*1024),
+ BLOCK_SIZE(1));
+
+static Sys_var_mybool Sys_timed_mutexes(
+ "timed_mutexes",
+ "Specify whether to time mutexes (only InnoDB mutexes are currently "
+ "supported)",
+ GLOBAL_VAR(timed_mutexes), CMD_LINE(OPT_ARG), DEFAULT(0));
+
+static char *server_version_ptr;
+static Sys_var_charptr Sys_version(
+ "version", "Server version",
+ READ_ONLY GLOBAL_VAR(server_version_ptr), NO_CMD_LINE,
+ IN_SYSTEM_CHARSET, DEFAULT(server_version));
+
+static char *server_version_comment_ptr;
+static Sys_var_charptr Sys_version_comment(
+ "version_comment", "version_comment",
+ READ_ONLY GLOBAL_VAR(server_version_comment_ptr), NO_CMD_LINE,
+ IN_SYSTEM_CHARSET, DEFAULT(MYSQL_COMPILATION_COMMENT));
+
+static char *server_version_compile_machine_ptr;
+static Sys_var_charptr Sys_version_compile_machine(
+ "version_compile_machine", "version_compile_machine",
+ READ_ONLY GLOBAL_VAR(server_version_compile_machine_ptr), NO_CMD_LINE,
+ IN_SYSTEM_CHARSET, DEFAULT(MACHINE_TYPE));
+
+static char *server_version_compile_os_ptr;
+static Sys_var_charptr Sys_version_compile_os(
+ "version_compile_os", "version_compile_os",
+ READ_ONLY GLOBAL_VAR(server_version_compile_os_ptr), NO_CMD_LINE,
+ IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE));
+
+static Sys_var_ulong Sys_net_wait_timeout(
+ "wait_timeout",
+ "The number of seconds the server waits for activity on a "
+ "connection before closing it",
+ SESSION_VAR(net_wait_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
+ DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
+
+static Sys_var_mybool Sys_engine_condition_pushdown(
+ "engine_condition_pushdown",
+ "Push supported query conditions to the storage engine",
+ SESSION_VAR(engine_condition_pushdown), CMD_LINE(OPT_ARG),
+ DEFAULT(TRUE));
+
+static Sys_var_plugin Sys_default_storage_engine(
+ "default_storage_engine", "The default storage engine for new tables",
+ SESSION_VAR(table_plugin), NO_CMD_LINE,
+ MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_storage_engine),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_not_null));
+
+// Alias for @@default_storage_engine
+static Sys_var_plugin Sys_storage_engine(
+ "storage_engine", "Alias for @@default_storage_engine. Deprecated",
+ SESSION_VAR(table_plugin), NO_CMD_LINE,
+ MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_storage_engine),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_not_null));
+
+#if defined(ENABLED_DEBUG_SYNC)
+/*
+ Variable can be set for the session only.
+
+ This could be changed later. Then we need to have a global array of
+ actions in addition to the thread local ones. SET GLOBAL would
+ manage the global array, SET [SESSION] the local array. A sync point
+ would need to look for a local and a global action. Setting and
+ executing of global actions need to be protected by a mutex.
+
+ The purpose of global actions could be to allow synchronizing with
+ connectionless threads that cannot execute SET statements.
+*/
+static Sys_var_debug_sync Sys_debug_sync(
+ "debug_sync", "Debug Sync Facility",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
+/**
+ "time_format" "date_format" "datetime_format"
+
+ the following three variables are unused, and the source of confusion
+ (bug reports like "I've changed date_format, but date format hasn't changed.
+ I've made them read-only, to alleviate the situation somewhat.
+
+ @todo make them NO_CMD_LINE ?
+*/
+static Sys_var_charptr Sys_date_format(
+ "date_format", "The DATE format (ignored)",
+ READ_ONLY GLOBAL_VAR(global_date_format.format.str),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(known_date_time_formats[ISO_FORMAT].date_format));
+
+static Sys_var_charptr Sys_datetime_format(
+ "datetime_format", "The DATETIME format (ignored)",
+ READ_ONLY GLOBAL_VAR(global_datetime_format.format.str),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(known_date_time_formats[ISO_FORMAT].datetime_format));
+
+static Sys_var_charptr Sys_time_format(
+ "time_format", "The TIME format (ignored)",
+ READ_ONLY GLOBAL_VAR(global_time_format.format.str),
+ CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
+ DEFAULT(known_date_time_formats[ISO_FORMAT].time_format));
+
+static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ {
+ if (global_system_variables.option_bits & OPTION_AUTOCOMMIT)
+ global_system_variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
+ else
+ global_system_variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
+ return false;
+ }
+
+ if (thd->variables.option_bits & OPTION_AUTOCOMMIT &&
+ thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT)
+ { // activating autocommit
+
+ if (ha_commit(thd))
+ {
+ thd->variables.option_bits&= ~OPTION_AUTOCOMMIT;
+ return true;
+ }
+
+ thd->variables.option_bits&=
+ ~(OPTION_BEGIN | OPTION_KEEP_LOG | OPTION_NOT_AUTOCOMMIT);
+ thd->transaction.all.modified_non_trans_table= false;
+ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
+ return false;
+ }
+
+ if (!(thd->variables.option_bits & OPTION_AUTOCOMMIT) &&
+ !(thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT))
+ { // disabling autocommit
+
+ thd->transaction.all.modified_non_trans_table= false;
+ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
+ thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
+ return false;
+ }
+
+ return false; // autocommit value wasn't changed
+}
+static Sys_var_bit Sys_autocommit(
+ "autocommit", "autocommit",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTOCOMMIT, DEFAULT(TRUE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_autocommit));
+export sys_var *Sys_autocommit_ptr= &Sys_autocommit; // for sql_yacc.yy
+
+static Sys_var_mybool Sys_big_tables(
+ "big_tables", "Allow big result sets by saving all "
+ "temporary sets on file (Solves most 'table full' errors)",
+ SESSION_VAR(big_tables), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+#ifndef TO_BE_DELETED /* Alias for big_tables */
+static Sys_var_mybool Sys_sql_big_tables(
+ "sql_big_tables", "alias for big_tables",
+ SESSION_VAR(big_tables), NO_CMD_LINE, DEFAULT(FALSE));
+#endif
+
+static Sys_var_bit Sys_big_selects(
+ "sql_big_selects", "sql_big_selects",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIG_SELECTS,
+ DEFAULT(FALSE));
+
+static Sys_var_bit Sys_log_off(
+ "sql_log_off", "sql_log_off",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_LOG_OFF,
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
+
+static bool fix_sql_log_bin(sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type != OPT_GLOBAL && !thd->in_sub_stmt)
+ thd->sql_log_bin_toplevel= thd->variables.option_bits & OPTION_BIN_LOG;
+ return false;
+}
+static Sys_var_bit Sys_log_binlog(
+ "sql_log_bin", "sql_log_bin",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIN_LOG,
+ DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super),
+ ON_UPDATE(fix_sql_log_bin));
+
+static bool deprecated_log_update(sys_var *self, THD *thd, set_var *var)
+{
+ /*
+ The update log is not supported anymore since 5.0.
+ See sql/mysqld.cc/, comments in function init_server_components() for an
+ explaination of the different warnings we send below
+ */
+
+ if (opt_sql_bin_update)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
+ ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
+ else
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_UPDATE_LOG_DEPRECATED_IGNORED,
+ ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
+ return check_has_super(self, thd, var);
+}
+static Sys_var_bit Sys_log_update(
+ "sql_log_update", "alias for sql_log_bin",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIN_LOG,
+ DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(deprecated_log_update), ON_UPDATE(fix_sql_log_bin));
+
+static Sys_var_bit Sys_sql_warnings(
+ "sql_warnings", "sql_warnings",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_WARNINGS,
+ DEFAULT(FALSE));
+
+static Sys_var_bit Sys_sql_notes(
+ "sql_notes", "sql_notes",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_SQL_NOTES,
+ DEFAULT(TRUE));
+
+static Sys_var_bit Sys_auto_is_null(
+ "sql_auto_is_null", "sql_auto_is_null",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTO_IS_NULL,
+ DEFAULT(FALSE), NO_MUTEX_GUARD, IN_BINLOG);
+
+static Sys_var_bit Sys_safe_updates(
+ "sql_safe_updates", "sql_safe_updates",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_SAFE_UPDATES,
+ DEFAULT(FALSE));
+
+static Sys_var_bit Sys_buffer_results(
+ "sql_buffer_result", "sql_buffer_result",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BUFFER_RESULT,
+ DEFAULT(FALSE));
+
+static Sys_var_bit Sys_quote_show_create(
+ "sql_quote_show_create", "sql_quote_show_create",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_QUOTE_SHOW_CREATE,
+ DEFAULT(TRUE));
+
+static Sys_var_bit Sys_foreign_key_checks(
+ "foreign_key_checks", "foreign_key_checks",
+ SESSION_VAR(option_bits), NO_CMD_LINE,
+ REVERSE(OPTION_NO_FOREIGN_KEY_CHECKS),
+ DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
+
+static Sys_var_bit Sys_unique_checks(
+ "unique_checks", "unique_checks",
+ SESSION_VAR(option_bits), NO_CMD_LINE,
+ REVERSE(OPTION_RELAXED_UNIQUE_CHECKS),
+ DEFAULT(TRUE), NO_MUTEX_GUARD, IN_BINLOG);
+
+#ifdef ENABLED_PROFILING
+static Sys_var_bit Sys_profiling(
+ "profiling", "profiling",
+ SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_PROFILING,
+ DEFAULT(FALSE));
+
+static Sys_var_ulong Sys_profiling_history_size(
+ "profiling_history_size", "Limit of query profiling memory",
+ SESSION_VAR(profiling_history_size), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 100), DEFAULT(15), BLOCK_SIZE(1));
+#endif
+
+static Sys_var_harows Sys_select_limit(
+ "sql_select_limit",
+ "The maximum number of rows to return from SELECT statements",
+ SESSION_VAR(select_limit), NO_CMD_LINE,
+ VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1));
+
+static bool update_timestamp(THD *thd, set_var *var)
+{
+ if (var->value)
+ thd->set_time((time_t) var->save_result.ulonglong_value);
+ else // SET timestamp=DEFAULT
+ thd->user_time= 0;
+ return false;
+}
+static ulonglong read_timestamp(THD *thd)
+{
+ return (ulonglong) thd->start_time;
+}
+static Sys_var_session_special Sys_timestamp(
+ "timestamp", "Set the time for this client",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ~(time_t)0), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0), ON_UPDATE(update_timestamp),
+ ON_READ(read_timestamp));
+
+static bool update_last_insert_id(THD *thd, set_var *var)
+{
+ if (!var->value)
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->var->name);
+ return true;
+ }
+ thd->first_successful_insert_id_in_prev_stmt=
+ var->save_result.ulonglong_value;
+ return false;
+}
+static ulonglong read_last_insert_id(THD *thd)
+{
+ return (ulonglong) thd->read_first_successful_insert_id_in_prev_stmt();
+}
+static Sys_var_session_special Sys_last_insert_id(
+ "last_insert_id", "The value to be returned from LAST_INSERT_ID()",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
+
+// alias for last_insert_id(), Sybase-style
+static Sys_var_session_special Sys_identity(
+ "identity", "Synonym for the last_insert_id variable",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_last_insert_id), ON_READ(read_last_insert_id));
+
+/*
+ insert_id should *not* be marked as written to the binlog (i.e., it
+ should *not* be IN_BINLOG), because we want any statement that
+ refers to insert_id explicitly to be unsafe. (By "explicitly", we
+ mean using @@session.insert_id, whereas insert_id is used
+ "implicitly" when NULL value is inserted into an auto_increment
+ column).
+
+ We want statements referring explicitly to @@session.insert_id to be
+ unsafe, because insert_id is modified internally by the slave sql
+ thread when NULL values are inserted in an AUTO_INCREMENT column.
+ This modification interfers with the value of the
+ @@session.insert_id variable if @@session.insert_id is referred
+ explicitly by an insert statement (as is seen by executing "SET
+ @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
+ AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
+ statement-based logging mode: t will be different on master and
+ slave).
+*/
+static bool update_insert_id(THD *thd, set_var *var)
+{
+ if (!var->value)
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->var->name);
+ return true;
+ }
+ thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
+ return false;
+}
+
+static ulonglong read_insert_id(THD *thd)
+{
+ return thd->auto_inc_intervals_forced.minimum();
+}
+static Sys_var_session_special Sys_insert_id(
+ "insert_id", "The value to be used by the following INSERT "
+ "or ALTER TABLE statement when inserting an AUTO_INCREMENT value",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_insert_id), ON_READ(read_insert_id));
+
+static bool update_rand_seed1(THD *thd, set_var *var)
+{
+ if (!var->value)
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->var->name);
+ return true;
+ }
+ thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
+ return false;
+}
+static ulonglong read_rand_seed(THD *thd)
+{
+ return 0;
+}
+static Sys_var_session_special Sys_rand_seed1(
+ "rand_seed1", "Sets the internal state of the RAND() "
+ "generator for replication purposes",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONG_MAX), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_rand_seed1), ON_READ(read_rand_seed));
+
+static bool update_rand_seed2(THD *thd, set_var *var)
+{
+ if (!var->value)
+ {
+ my_error(ER_NO_DEFAULT, MYF(0), var->var->name);
+ return true;
+ }
+ thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
+ return false;
+}
+static Sys_var_session_special Sys_rand_seed2(
+ "rand_seed2", "Sets the internal state of the RAND() "
+ "generator for replication purposes",
+ sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONG_MAX), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_rand_seed2), ON_READ(read_rand_seed));
+
+static ulonglong read_error_count(THD *thd)
+{
+ return thd->warning_info->error_count();
+}
+// this really belongs to the SHOW STATUS
+static Sys_var_session_special Sys_error_count(
+ "error_count", "The number of errors that resulted from the "
+ "last statement that generated messages",
+ READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(read_error_count));
+
+static ulonglong read_warning_count(THD *thd)
+{
+ return thd->warning_info->warn_count();
+}
+// this really belongs to the SHOW STATUS
+static Sys_var_session_special Sys_warning_count(
+ "warning_count", "The number of errors, warnings, and notes "
+ "that resulted from the last statement that generated messages",
+ READ_ONLY sys_var::ONLY_SESSION, NO_CMD_LINE,
+ VALID_RANGE(0, ULONGLONG_MAX), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(read_warning_count));
+
+static Sys_var_ulong Sys_default_week_format(
+ "default_week_format",
+ "The default week format used by WEEK() functions",
+ SESSION_VAR(default_week_format), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, 7), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_ulong Sys_group_concat_max_len(
+ "group_concat_max_len",
+ "The maximum length of the result of function GROUP_CONCAT()",
+ SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(4, ULONG_MAX), DEFAULT(1024), BLOCK_SIZE(1));
+
+static char *glob_hostname_ptr;
+static Sys_var_charptr Sys_hostname(
+ "hostname", "Server host name",
+ READ_ONLY GLOBAL_VAR(glob_hostname_ptr), NO_CMD_LINE,
+ IN_FS_CHARSET, DEFAULT(glob_hostname));
+
+#ifndef EMBEDDED_LIBRARY
+static Sys_var_charptr Sys_repl_report_host(
+ "report_host",
+ "Hostname or IP of the slave to be reported to the master during "
+ "slave registration. Will appear in the output of SHOW SLAVE HOSTS. "
+ "Leave unset if you do not want the slave to register itself with the "
+ "master. Note that it is not sufficient for the master to simply read "
+ "the IP of the slave off the socket once the slave connects. Due to "
+ "NAT and other routing issues, that IP may not be valid for connecting "
+ "to the slave from the master or other hosts",
+ READ_ONLY GLOBAL_VAR(report_host), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_repl_report_user(
+ "report_user",
+ "The account user name of the slave to be reported to the master "
+ "during slave registration",
+ READ_ONLY GLOBAL_VAR(report_user), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_repl_report_password(
+ "report_password",
+ "The account password of the slave to be reported to the master "
+ "during slave registration",
+ READ_ONLY GLOBAL_VAR(report_password), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_uint Sys_repl_report_port(
+ "report_port",
+ "Port for connecting to slave reported to the master during slave "
+ "registration. Set it only if the slave is listening on a non-default "
+ "port or if you have a special tunnel from the master or other clients "
+ "to the slave. If not sure, leave this option unset",
+ READ_ONLY GLOBAL_VAR(report_port), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(MYSQL_PORT), BLOCK_SIZE(1));
+#endif
+
+static Sys_var_mybool Sys_keep_files_on_create(
+ "keep_files_on_create",
+ "Don't overwrite stale .MYD and .MYI even if no directory is specified",
+ SESSION_VAR(keep_files_on_create), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE));
+
+static char *license;
+static Sys_var_charptr Sys_license(
+ "license", "The type of license the server has",
+ READ_ONLY GLOBAL_VAR(license), NO_CMD_LINE, IN_SYSTEM_CHARSET,
+ DEFAULT(STRINGIFY_ARG(LICENSE)));
+
+static bool check_log_path(sys_var *self, THD *thd, set_var *var)
+{
+ if (!var->value)
+ return false; // DEFAULT is ok
+
+ if (!var->save_result.string_value.str)
+ return true;
+
+ if (var->save_result.string_value.length > FN_REFLEN)
+ { // path is too long
+ my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
+ return true;
+ }
+
+ char path[FN_REFLEN];
+ size_t path_length= unpack_filename(path, var->save_result.string_value.str);
+
+ if (!path_length)
+ return true;
+
+ MY_STAT f_stat;
+
+ if (my_stat(path, &f_stat, MYF(0)))
+ {
+ if (!MY_S_ISREG(f_stat.st_mode) || !(f_stat.st_mode & MY_S_IWRITE))
+ return true; // not a regular writable file
+ return false;
+ }
+
+ (void) dirname_part(path, var->save_result.string_value.str, &path_length);
+
+ if (var->save_result.string_value.length - path_length >= FN_LEN)
+ { // filename is too long
+ my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
+ return true;
+ }
+
+ if (!path_length) // no path is good path (remember, relative to datadir)
+ return false;
+
+ if (my_access(path, (F_OK|W_OK)))
+ return true; // directory is not writable
+
+ return false;
+}
+static bool fix_log(char** logname, const char* default_logname,
+ const char*ext, bool enabled, void (*reopen)(char*))
+{
+ if (!*logname) // SET ... = DEFAULT
+ {
+ char buff[FN_REFLEN];
+ *logname= my_strdup(make_log_name(buff, default_logname, ext),
+ MYF(MY_FAE+MY_WME));
+ if (!*logname)
+ return true;
+ }
+ logger.lock_exclusive();
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ if (enabled)
+ reopen(*logname);
+ logger.unlock();
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ return false;
+}
+static void reopen_general_log(char* name)
+{
+ logger.get_log_file_handler()->close(0);
+ logger.get_log_file_handler()->open_query_log(name);
+}
+static bool fix_general_log_file(sys_var *self, THD *thd, enum_var_type type)
+{
+ return fix_log(&opt_logname, default_logfile_name, ".log", opt_log,
+ reopen_general_log);
+}
+static Sys_var_charptr Sys_general_log_path(
+ "general_log_file", "Log connections and queries to given file",
+ PREALLOCATED GLOBAL_VAR(opt_logname), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file));
+
+static void reopen_slow_log(char* name)
+{
+ logger.get_slow_log_file_handler()->close(0);
+ logger.get_slow_log_file_handler()->open_slow_log(name);
+}
+static bool fix_slow_log_file(sys_var *self, THD *thd, enum_var_type type)
+{
+ return fix_log(&opt_slow_logname, default_logfile_name, "-slow.log",
+ opt_slow_log, reopen_slow_log);
+}
+static Sys_var_charptr Sys_slow_log_path(
+ "slow_query_log_file", "Log slow queries to given log file. "
+ "Defaults logging to hostname-slow.log. Must be enabled to activate "
+ "other slow log options",
+ PREALLOCATED GLOBAL_VAR(opt_slow_logname), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_log_path), ON_UPDATE(fix_slow_log_file));
+
+/// @todo deprecate these four legacy have_PLUGIN variables and use I_S instead
+export SHOW_COMP_OPTION have_csv, have_innodb;
+export SHOW_COMP_OPTION have_ndbcluster, have_partitioning;
+static Sys_var_have Sys_have_csv(
+ "have_csv", "have_csv",
+ READ_ONLY GLOBAL_VAR(have_csv), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_innodb(
+ "have_innodb", "have_innodb",
+ READ_ONLY GLOBAL_VAR(have_innodb), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_ndbcluster(
+ "have_ndbcluster", "have_ndbcluster",
+ READ_ONLY GLOBAL_VAR(have_ndbcluster), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_partition_db(
+ "have_partitioning", "have_partitioning",
+ READ_ONLY GLOBAL_VAR(have_partitioning), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_compress(
+ "have_compress", "have_compress",
+ READ_ONLY GLOBAL_VAR(have_compress), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_crypt(
+ "have_crypt", "have_crypt",
+ READ_ONLY GLOBAL_VAR(have_crypt), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_dlopen(
+ "have_dynamic_loading", "have_dynamic_loading",
+ READ_ONLY GLOBAL_VAR(have_dlopen), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_geometry(
+ "have_geometry", "have_geometry",
+ READ_ONLY GLOBAL_VAR(have_geometry), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_openssl(
+ "have_openssl", "have_openssl",
+ READ_ONLY GLOBAL_VAR(have_ssl), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_profiling(
+ "have_profiling", "have_profiling",
+ READ_ONLY GLOBAL_VAR(have_profiling), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_query_cache(
+ "have_query_cache", "have_query_cache",
+ READ_ONLY GLOBAL_VAR(have_query_cache), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_rtree_keys(
+ "have_rtree_keys", "have_rtree_keys",
+ READ_ONLY GLOBAL_VAR(have_rtree_keys), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_ssl(
+ "have_ssl", "have_ssl",
+ READ_ONLY GLOBAL_VAR(have_ssl), NO_CMD_LINE);
+
+static Sys_var_have Sys_have_symlink(
+ "have_symlink", "have_symlink",
+ READ_ONLY GLOBAL_VAR(have_symlink), NO_CMD_LINE);
+
+static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type);
+static Sys_var_mybool Sys_general_log(
+ "general_log", "Log connections and queries to a table or log file. "
+ "Defaults logging to a file hostname.log or a table mysql.general_log"
+ "if --log-output=TABLE is used",
+ GLOBAL_VAR(opt_log), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_log_state));
+
+// Synonym of "general_log" for consistency with SHOW VARIABLES output
+static Sys_var_mybool Sys_log(
+ "log", "Alias for --general-log. Deprecated",
+ GLOBAL_VAR(opt_log), NO_CMD_LINE,
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_log_state), DEPRECATED(70000, "'@@general_log'"));
+
+static Sys_var_mybool Sys_slow_query_log(
+ "slow_query_log",
+ "Log slow queries to a table or log file. Defaults logging to a file "
+ "hostname-slow.log or a table mysql.slow_log if --log-output=TABLE is "
+ "used. Must be enabled to activate other slow log options",
+ GLOBAL_VAR(opt_slow_log), CMD_LINE(OPT_ARG),
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_log_state));
+
+/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
+static Sys_var_mybool Sys_log_slow(
+ "log_slow_queries",
+ "Alias for --slow-query-log. Deprecated",
+ GLOBAL_VAR(opt_slow_log), NO_CMD_LINE,
+ DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_log_state), DEPRECATED(70000, "'@@slow_query_log'"));
+
+static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type)
+{
+ bool res;
+ my_bool *newvalptr, newval, oldval;
+ uint log_type;
+
+ if (self == &Sys_general_log || self == &Sys_log)
+ {
+ newvalptr= &opt_log;
+ oldval= logger.get_log_file_handler()->is_open();
+ log_type= QUERY_LOG_GENERAL;
+ }
+ else if (self == &Sys_slow_query_log || self == &Sys_log_slow)
+ {
+ newvalptr= &opt_slow_log;
+ oldval= logger.get_slow_log_file_handler()->is_open();
+ log_type= QUERY_LOG_SLOW;
+ }
+ else
+ DBUG_ASSERT(FALSE);
+
+ newval= *newvalptr;
+ if (oldval == newval)
+ return false;
+
+ *newvalptr= oldval; // [de]activate_log_handler works that way (sigh)
+
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ if (!newval)
+ {
+ logger.deactivate_log_handler(thd, log_type);
+ res= false;
+ }
+ else
+ res= logger.activate_log_handler(thd, log_type);
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ return res;
+}
+
+static bool check_not_empty_set(sys_var *self, THD *thd, set_var *var)
+{
+ return var->save_result.ulonglong_value == 0;
+}
+static bool fix_log_output(sys_var *self, THD *thd, enum_var_type type)
+{
+ logger.lock_exclusive();
+ logger.init_slow_log(log_output_options);
+ logger.init_general_log(log_output_options);
+ logger.unlock();
+ return false;
+}
+
+static Sys_var_set Sys_log_output(
+ "log_output", "Syntax: log-output=value[,value...], "
+ "where \"value\" could be TABLE, FILE or NONE",
+ GLOBAL_VAR(log_output_options), CMD_LINE(REQUIRED_ARG),
+ log_output_names, DEFAULT(LOG_FILE), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(check_not_empty_set), ON_UPDATE(fix_log_output));
+
+#ifdef HAVE_REPLICATION
+static Sys_var_mybool Sys_log_slave_updates(
+ "log_slave_updates", "Tells the slave to log the updates from "
+ "the slave thread to the binary log. You will need to turn it on if "
+ "you plan to daisy-chain the slaves",
+ READ_ONLY GLOBAL_VAR(opt_log_slave_updates), CMD_LINE(OPT_ARG),
+ DEFAULT(0));
+
+static Sys_var_charptr Sys_relay_log(
+ "relay_log", "The location and name to use for relay logs",
+ READ_ONLY GLOBAL_VAR(opt_relay_logname), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_relay_log_index(
+ "relay_log_index", "The location and name to use for the file "
+ "that keeps a list of the last relay logs",
+ READ_ONLY GLOBAL_VAR(opt_relaylog_index_name), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_charptr Sys_relay_log_info_file(
+ "relay_log_info_file", "The location and name of the file that "
+ "remembers where the SQL replication thread is in the relay logs",
+ READ_ONLY GLOBAL_VAR(relay_log_info_file), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static Sys_var_mybool Sys_relay_log_purge(
+ "relay_log_purge", "if disabled - do not purge relay logs. "
+ "if enabled - purge them as soon as they are no more needed",
+ GLOBAL_VAR(relay_log_purge), CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+
+static Sys_var_mybool Sys_relay_log_recovery(
+ "relay_log_recovery", "Enables automatic relay log recovery "
+ "right after the database startup, which means that the IO Thread "
+ "starts re-fetching from the master right after the last transaction "
+ "processed",
+ GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static Sys_var_charptr Sys_slave_load_tmpdir(
+ "slave_load_tmpdir", "The location where the slave should put "
+ "its temporary files when replicating a LOAD DATA INFILE command",
+ READ_ONLY GLOBAL_VAR(slave_load_tmpdir), CMD_LINE(REQUIRED_ARG),
+ IN_FS_CHARSET, DEFAULT(0));
+
+static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type)
+{
+ pthread_mutex_lock(&LOCK_active_mi);
+ DBUG_PRINT("info", ("slave_net_timeout=%lu mi->heartbeat_period=%.3f",
+ slave_net_timeout,
+ (active_mi? active_mi->heartbeat_period : 0.0)));
+ if (active_mi && slave_net_timeout < active_mi->heartbeat_period)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE,
+ "The current value for master_heartbeat_period"
+ " exceeds the new value of `slave_net_timeout' sec."
+ " A sensible value for the period should be"
+ " less than the timeout.");
+ pthread_mutex_unlock(&LOCK_active_mi);
+ return false;
+}
+static Sys_var_ulong Sys_slave_net_timeout(
+ "slave_net_timeout", "Number of seconds to wait for more data "
+ "from a master/slave connection before aborting the read",
+ GLOBAL_VAR(slave_net_timeout), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(SLAVE_NET_TIMEOUT), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(fix_slave_net_timeout));
+
+static bool check_slave_skip_counter(sys_var *self, THD *thd, set_var *var)
+{
+ bool result= false;
+ 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= true;
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ pthread_mutex_unlock(&LOCK_active_mi);
+ return result;
+}
+static bool fix_slave_skip_counter(sys_var *self, THD *thd, enum_var_type type)
+{
+ 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= sql_slave_skip_counter;
+ pthread_mutex_unlock(&active_mi->rli.data_lock);
+ }
+ pthread_mutex_unlock(&active_mi->rli.run_lock);
+ pthread_mutex_unlock(&LOCK_active_mi);
+ return 0;
+}
+static Sys_var_uint Sys_slave_skip_counter(
+ "sql_slave_skip_counter", "sql_slave_skip_counter",
+ GLOBAL_VAR(sql_slave_skip_counter), NO_CMD_LINE,
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_skip_counter),
+ ON_UPDATE(fix_slave_skip_counter));
+
+static Sys_var_charptr Sys_slave_skip_errors(
+ "slave_skip_errors", "Tells the slave thread to continue "
+ "replication when a query event returns an error from the "
+ "provided list",
+ READ_ONLY GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG),
+ IN_SYSTEM_CHARSET, DEFAULT(0));
+
+static Sys_var_ulonglong Sys_relay_log_space_limit(
+ "relay_log_space_limit", "Maximum space to use for all relay logs",
+ READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_uint Sys_sync_relaylog_period(
+ "sync_relay_log", "Synchronously flush relay log to disk after "
+ "every #th event. Use 0 (default) to disable synchronous flushing",
+ GLOBAL_VAR(sync_relaylog_period), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_uint Sys_sync_relayloginfo_period(
+ "sync_relay_log_info", "Synchronously flush relay log info "
+ "to disk after every #th transaction. Use 0 (default) to disable "
+ "synchronous flushing",
+ GLOBAL_VAR(sync_relayloginfo_period), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
+#endif
+
+static Sys_var_uint Sys_sync_binlog_period(
+ "sync_binlog", "Synchronously flush binary log to disk after "
+ "every #th event. Use 0 (default) to disable synchronous flushing",
+ GLOBAL_VAR(sync_binlog_period), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+static Sys_var_uint Sys_sync_masterinfo_period(
+ "sync_master_info", "Synchronously flush master info to disk "
+ "after every #th event. Use 0 (default) to disable synchronous flushing",
+ GLOBAL_VAR(sync_masterinfo_period), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+#ifdef HAVE_REPLICATION
+static Sys_var_ulong Sys_slave_trans_retries(
+ "slave_transaction_retries", "Number of times the slave SQL "
+ "thread will retry a transaction in case it failed with a deadlock "
+ "or elapsed lock wait timeout, before giving up and stopping",
+ GLOBAL_VAR(slave_trans_retries), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(10), BLOCK_SIZE(1));
+#endif
+
+static bool check_locale(sys_var *self, THD *thd, set_var *var)
+{
+ if (!var->value)
+ return false;
+
+ MY_LOCALE *locale;
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ if (var->value->result_type() == INT_RESULT)
+ {
+ int lcno= (int)var->value->val_int();
+ if (!(locale= my_locale_by_number(lcno)))
+ {
+ my_error(ER_UNKNOWN_LOCALE, MYF(0), llstr(lcno, buff));
+ return true;
+ }
+ if (check_not_null(self, thd, var))
+ return true;
+ }
+ else // STRING_RESULT
+ {
+ String str(buff, sizeof(buff), system_charset_info), *res;
+ if (!(res=var->value->val_str(&str)))
+ return true;
+ else if (!(locale= my_locale_by_name(res->c_ptr())))
+ {
+ ErrConvString err(res);
+ my_error(ER_UNKNOWN_LOCALE, MYF(0), err.ptr());
+ return true;
+ }
+ }
+
+ var->save_result.ptr= locale;
+
+ if (!locale->errmsgs->errmsgs)
+ {
+ pthread_mutex_lock(&LOCK_error_messages);
+ if (!locale->errmsgs->errmsgs &&
+ read_texts(ERRMSG_FILE, locale->errmsgs->language,
+ &locale->errmsgs->errmsgs,
+ ER_ERROR_LAST - ER_ERROR_FIRST + 1))
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Can't process error message file for locale '%s'",
+ locale->name);
+ pthread_mutex_unlock(&LOCK_error_messages);
+ return true;
+ }
+ pthread_mutex_unlock(&LOCK_error_messages);
+ }
+ return false;
+}
+static Sys_var_struct Sys_lc_messages(
+ "lc_messages", "Set the language used for the error messages",
+ SESSION_VAR(lc_messages), NO_CMD_LINE,
+ offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_messages),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_locale));
+
+static Sys_var_struct Sys_lc_time_names(
+ "lc_time_names", "Set the language used for the month "
+ "names and the days of the week",
+ SESSION_VAR(lc_time_names), NO_CMD_LINE,
+ offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_time_names),
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_locale));
+
+static Sys_var_tz Sys_time_zone(
+ "time_zone", "time_zone",
+ SESSION_VAR(time_zone), NO_CMD_LINE,
+ DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG);
+
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
new file mode 100644
index 00000000000..bdbbcbbbd59
--- /dev/null
+++ b/sql/sys_vars.h
@@ -0,0 +1,1600 @@
+/* Copyright (C) 2002-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+ "private" interface to sys_var - server configuration variables.
+
+ This header is included only by the file that contains declarations
+ of sys_var variables (sys_vars.cc).
+*/
+
+#include "sys_vars_shared.h"
+#include <my_getopt.h>
+#include <my_bit.h>
+#include <my_dir.h>
+#include "keycaches.h"
+
+/*
+ a set of mostly trivial (as in f(X)=X) defines below to make system variable
+ declarations more readable
+*/
+#define VALID_RANGE(X,Y) X,Y
+#define DEFAULT(X) X
+#define BLOCK_SIZE(X) X
+#define GLOBAL_VAR(X) sys_var::GLOBAL, (((char*)&(X))-(char*)&global_system_variables), sizeof(X)
+#define SESSION_VAR(X) sys_var::SESSION, offsetof(SV, X), sizeof(((SV *)0)->X)
+#define SESSION_ONLY(X) sys_var::ONLY_SESSION, offsetof(SV, X), sizeof(((SV *)0)->X)
+#define NO_CMD_LINE CMD_LINE(NO_ARG, -1)
+/*
+ the define below means that there's no *second* mutex guard,
+ LOCK_global_system_variables always guards all system variables
+*/
+#define NO_MUTEX_GUARD ((PolyLock*)0)
+#define IN_BINLOG sys_var::SESSION_VARIABLE_IN_BINLOG
+#define NOT_IN_BINLOG sys_var::VARIABLE_NOT_IN_BINLOG
+#define ON_READ(X) X
+#define ON_CHECK(X) X
+#define ON_UPDATE(X) X
+#define READ_ONLY sys_var::READONLY+
+// this means that Sys_var_charptr initial value was malloc()ed
+#define PREALLOCATED sys_var::ALLOCATED+
+/*
+ Sys_var_bit meaning is reversed, like in
+ @@foreign_key_checks <-> OPTION_NO_FOREIGN_KEY_CHECKS
+*/
+#define REVERSE(X) ~(X)
+#define DEPRECATED(X, Y) X, Y
+
+#define session_var(THD, TYPE) (*(TYPE*)session_var_ptr(THD))
+#define global_var(TYPE) (*(TYPE*)global_var_ptr())
+
+#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
+#define GET_HA_ROWS GET_ULL
+#else
+#define GET_HA_ROWS GET_ULONG
+#endif
+
+enum charset_enum {IN_SYSTEM_CHARSET, IN_FS_CHARSET};
+
+static const char *bool_values[3]= {"OFF", "ON", 0};
+TYPELIB bool_typelib={ array_elements(bool_values)-1, "", bool_values, 0 };
+
+/**
+ A small wrapper class to pass getopt arguments as a pair
+ to the Sys_var_* constructors. It improves type safety and helps
+ to catch errors in the argument order.
+*/
+struct CMD_LINE
+{
+ int id;
+ enum get_opt_arg_type arg_type;
+ CMD_LINE(enum get_opt_arg_type getopt_arg_type, int getopt_id=0)
+ : id(getopt_id), arg_type(getopt_arg_type) {}
+};
+
+/**
+ Sys_var_unsigned template is used to generate Sys_var_* classes
+ for variables that represent the value as an unsigned integer.
+ They are Sys_var_uint, Sys_var_ulong, Sys_var_harows, Sys_var_ulonglong.
+
+ An integer variable has a minimal and maximal values, and a "block_size"
+ (any valid value of the variable must be divisible by the block_size).
+
+ Class specific constructor arguments: min, max, block_size
+ Backing store: uint, ulong, ha_rows, ulonglong, depending on the Sys_var_*
+*/
+template <typename T, ulong ARGT, enum enum_mysql_show_type SHOWT>
+class Sys_var_unsigned: public sys_var
+{
+public:
+ Sys_var_unsigned(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ T min_val, T max_val, T def_val, uint block_size, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOWT, def_val, lock, binlog_status_arg,
+ on_check_func, on_update_func, deprecated_version,
+ substitute)
+ {
+ option.var_type= ARGT;
+ option.min_value= min_val;
+ option.max_value= max_val;
+ option.block_size= block_size;
+ option.u_max_value= (uchar**)max_var_ptr();
+ if (max_var_ptr())
+ *max_var_ptr()= max_val;
+ global_var(T)= def_val;
+ DBUG_ASSERT(size == sizeof(T));
+ DBUG_ASSERT(min_val < max_val);
+ DBUG_ASSERT(min_val <= def_val);
+ DBUG_ASSERT(max_val >= def_val);
+ DBUG_ASSERT(block_size > 0);
+ DBUG_ASSERT(def_val % block_size == 0);
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ my_bool fixed= FALSE;
+ ulonglong uv;
+ longlong v;
+
+ v= var->value->val_int();
+ if (var->value->unsigned_flag)
+ uv= (ulonglong) v;
+ else
+ uv= (ulonglong) (v < 0 ? 0 : v);
+
+ var->save_result.ulonglong_value=
+ getopt_ull_limit_value(uv, &option, &fixed);
+
+ if (max_var_ptr() && var->save_result.ulonglong_value > *max_var_ptr())
+ var->save_result.ulonglong_value= *max_var_ptr();
+
+ return throw_bounds_warning(thd, name.str,
+ var->save_result.ulonglong_value != uv,
+ var->value->unsigned_flag, v);
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, T)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(T)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool check_update_type(Item_result type)
+ { return type != INT_RESULT; }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= (ulonglong)*(T*)global_value_ptr(thd, 0); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+ private:
+ T *max_var_ptr()
+ {
+ return scope() == SESSION ? (T*)(((uchar*)&max_system_variables) + offset)
+ : 0;
+ }
+};
+
+typedef Sys_var_unsigned<uint, GET_UINT, SHOW_INT> Sys_var_uint;
+typedef Sys_var_unsigned<ulong, GET_ULONG, SHOW_LONG> Sys_var_ulong;
+typedef Sys_var_unsigned<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS> Sys_var_harows;
+typedef Sys_var_unsigned<ulonglong, GET_ULL, SHOW_LONGLONG> Sys_var_ulonglong;
+
+/**
+ Helper class for variables that take values from a TYPELIB
+*/
+class Sys_var_typelib: public sys_var
+{
+protected:
+ TYPELIB typelib;
+public:
+ Sys_var_typelib(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off,
+ CMD_LINE getopt,
+ SHOW_TYPE show_val_type_arg, const char *values[],
+ ulonglong def_val, PolyLock *lock,
+ enum binlog_status_enum binlog_status_arg,
+ on_check_function on_check_func, on_update_function on_update_func,
+ uint deprecated_version, const char *substitute)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, show_val_type_arg, def_val, lock,
+ binlog_status_arg, on_check_func,
+ on_update_func, deprecated_version, substitute)
+ {
+ for (typelib.count= 0; values[typelib.count]; typelib.count++) /*no-op */;
+ typelib.name="";
+ typelib.type_names= values;
+ typelib.type_lengths= 0; // only used by Fields_enum and Field_set
+ option.typelib= &typelib;
+ }
+ bool do_check(THD *thd, set_var *var) // works for enums and my_bool
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)))
+ return true;
+ else
+ if (!(var->save_result.ulonglong_value=
+ find_type(&typelib, res->ptr(), res->length(), false)))
+ return true;
+ else
+ var->save_result.ulonglong_value--;
+ }
+ else
+ {
+ longlong tmp=var->value->val_int();
+ if (tmp < 0 || tmp >= typelib.count)
+ return true;
+ else
+ var->save_result.ulonglong_value= tmp;
+ }
+
+ return false;
+ }
+ bool check_update_type(Item_result type)
+ { return type != INT_RESULT && type != STRING_RESULT; }
+};
+
+/**
+ The class for ENUM variables - variables that take one value from a fixed
+ list of values.
+
+ Class specific constructor arguments:
+ char* values[] - 0-terminated list of strings of valid values
+
+ Backing store: uint
+
+ @note
+ Do *not* use "enum FOO" variables as a backing store, there is no
+ guarantee that sizeof(enum FOO) == sizeof(uint), there is no guarantee
+ even that sizeof(enum FOO) == sizeof(enum BAR)
+*/
+class Sys_var_enum: public Sys_var_typelib
+{
+public:
+ Sys_var_enum(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ const char *values[], uint def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
+ SHOW_CHAR, values, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ option.var_type= GET_ENUM;
+ global_var(uint)= def_val;
+ DBUG_ASSERT(def_val < typelib.count);
+ DBUG_ASSERT(size == sizeof(uint));
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, uint)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(uint)= var->save_result.ulonglong_value;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= global_var(uint); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ { return (uchar*)typelib.type_names[session_var(thd, uint)]; }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ { return (uchar*)typelib.type_names[global_var(uint)]; }
+};
+
+/**
+ The class for boolean variables - a variant of ENUM variables
+ with the fixed list of values of { OFF , ON }
+
+ Backing store: my_bool
+*/
+class Sys_var_mybool: public Sys_var_typelib
+{
+public:
+ Sys_var_mybool(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ my_bool def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
+ SHOW_MY_BOOL, bool_values, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ option.var_type= GET_BOOL;
+ global_var(my_bool)= def_val;
+ DBUG_ASSERT(def_val < 2);
+ DBUG_ASSERT(getopt.arg_type == OPT_ARG || getopt.id == -1);
+ DBUG_ASSERT(size == sizeof(my_bool));
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, my_bool)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(my_bool)= var->save_result.ulonglong_value;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= (ulonglong)*(my_bool *)global_value_ptr(thd, 0); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+};
+
+/**
+ The class for string variables. The string can be in character_set_filesystem
+ or in character_set_system. The string can be allocated with my_malloc()
+ or not. The state of the initial value is specified in the constructor,
+ after that it's managed automatically. The value of NULL is supported.
+
+ Class specific constructor arguments:
+ enum charset_enum is_os_charset_arg
+
+ Backing store: char*
+
+ @note
+ This class supports only GLOBAL variables, because THD on destruction
+ does not destroy individual members of SV, there's no way to free
+ allocated string variables for every thread.
+*/
+class Sys_var_charptr: public sys_var
+{
+public:
+ Sys_var_charptr(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ enum charset_enum is_os_charset_arg,
+ const char *def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_CHAR_PTR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ is_os_charset= is_os_charset_arg == IN_FS_CHARSET;
+ /*
+ use GET_STR_ALLOC - if ALLOCATED it must be *always* allocated,
+ otherwise (GET_STR) you'll never know whether to free it or not.
+ (think of an exit because of an error right after my_getopt)
+ */
+ option.var_type= (flags & ALLOCATED) ? GET_STR_ALLOC : GET_STR;
+ global_var(const char*)= def_val;
+ DBUG_ASSERT(scope() == GLOBAL);
+ DBUG_ASSERT(size == sizeof(char *));
+ }
+ ~Sys_var_charptr()
+ {
+ if (flags & ALLOCATED)
+ my_free(global_var(char*), MYF(MY_ALLOW_ZERO_PTR));
+ flags&= ~ALLOCATED;
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE], buff2[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), charset(thd));
+ String str2(buff2, sizeof(buff2), charset(thd)), *res;
+
+ if (!(res=var->value->val_str(&str)))
+ var->save_result.string_value.str= 0;
+ else
+ {
+ uint32 unused;
+ if (String::needs_conversion(res->length(), res->charset(),
+ charset(thd), &unused))
+ {
+ uint errors;
+ str2.copy(res->ptr(), res->length(), res->charset(), charset(thd),
+ &errors);
+ res=&str2;
+
+ }
+ var->save_result.string_value.str= thd->strmake(res->ptr(), res->length());
+ var->save_result.string_value.length= res->length();
+ }
+
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ char *new_val, *ptr= var->save_result.string_value.str;
+ size_t len=var->save_result.string_value.length;
+ if (ptr)
+ {
+ new_val= (char*)my_memdup(ptr, len+1, MYF(MY_WME));
+ if (!new_val) return true;
+ new_val[len]=0;
+ }
+ else
+ new_val= 0;
+ if (flags & ALLOCATED)
+ my_free(global_var(char*), MYF(MY_ALLOW_ZERO_PTR));
+ flags|= ALLOCATED;
+ global_var(char*)= new_val;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { DBUG_ASSERT(FALSE); }
+ void global_save_default(THD *thd, set_var *var)
+ {
+ char *ptr= (char*)(intptr)option.def_value;
+ var->save_result.string_value.str= ptr;
+ var->save_result.string_value.length= ptr ? strlen(ptr) : 0;
+ }
+ bool check_update_type(Item_result type)
+ { return type != STRING_RESULT; }
+};
+
+/**
+ The class for string variables. Useful for strings that aren't necessarily
+ \0-terminated. Otherwise the same as Sys_var_charptr.
+
+ Class specific constructor arguments:
+ enum charset_enum is_os_charset_arg
+
+ Backing store: LEX_STRING
+
+ @note
+ Behaves exactly as Sys_var_charptr, only the backing store is different.
+*/
+class Sys_var_lexstring: public Sys_var_charptr
+{
+public:
+ Sys_var_lexstring(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ enum charset_enum is_os_charset_arg,
+ const char *def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_charptr(name_arg, comment, flag_args, off, sizeof(char*),
+ getopt, is_os_charset_arg, def_val, lock, binlog_status_arg,
+ on_check_func, on_update_func, deprecated_version, substitute)
+ {
+ global_var(LEX_STRING).length= strlen(def_val);
+ DBUG_ASSERT(size == sizeof(LEX_STRING));
+ *const_cast<SHOW_TYPE*>(&show_val_type)= SHOW_LEX_STRING;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ if (Sys_var_charptr::global_update(thd, var))
+ return true;
+ global_var(LEX_STRING).length= var->save_result.string_value.length;
+ return false;
+ }
+};
+
+#ifndef DBUG_OFF
+/**
+ @@session.dbug and @@global.dbug variables.
+
+ @@dbug variable differs from other variables in one aspect:
+ if its value is not assigned in the session, it "points" to the global
+ value, and so when the global value is changed, the change
+ immediately takes effect in the session.
+
+ This semantics is intentional, to be able to debug one session from
+ another.
+*/
+class Sys_var_dbug: public sys_var
+{
+public:
+ Sys_var_dbug(const char *name_arg,
+ const char *comment, int flag_args,
+ CMD_LINE getopt,
+ const char *def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, 0, getopt.id,
+ getopt.arg_type, SHOW_CHAR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ { option.var_type= GET_NO_ARG; }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
+
+ if (!(res=var->value->val_str(&str)))
+ var->save_result.string_value.str= const_cast<char*>("");
+ else
+ var->save_result.string_value.str= thd->strmake(res->ptr(), res->length());
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ const char *val= var->save_result.string_value.str;
+ if (!var->value)
+ DBUG_POP();
+ else
+ DBUG_SET(val);
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ const char *val= var->save_result.string_value.str;
+ DBUG_SET_INITIAL(val);
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { }
+ void global_save_default(THD *thd, set_var *var)
+ {
+ char *ptr= (char*)(intptr)option.def_value;
+ var->save_result.string_value.str= ptr;
+ }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ char buf[256];
+ DBUG_EXPLAIN(buf, sizeof(buf));
+ return (uchar*) thd->strdup(buf);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ char buf[256];
+ DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
+ return (uchar*) thd->strdup(buf);
+ }
+ bool check_update_type(Item_result type)
+ { return type != STRING_RESULT; }
+};
+#endif
+
+#define KEYCACHE_VAR(X) sys_var::GLOBAL,offsetof(KEY_CACHE, X), sizeof(((KEY_CACHE *)0)->X)
+#define keycache_var_ptr(KC, OFF) (((uchar*)(KC))+(OFF))
+#define keycache_var(KC, OFF) (*(ulonglong*)keycache_var_ptr(KC, OFF))
+typedef bool (*keycache_update_function)(THD *, KEY_CACHE *, ptrdiff_t, ulonglong);
+
+/**
+ The class for keycache_* variables. Supports structured names,
+ keycache_name.variable_name.
+
+ Class specific constructor arguments:
+ everything derived from Sys_var_ulonglong
+
+ Backing store: ulonglong
+
+ @note these variables can be only GLOBAL
+*/
+class Sys_var_keycache: public Sys_var_ulonglong
+{
+ keycache_update_function keycache_update;
+public:
+ Sys_var_keycache(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ ulonglong min_val, ulonglong max_val, ulonglong def_val,
+ ulonglong block_size, PolyLock *lock,
+ enum binlog_status_enum binlog_status_arg,
+ on_check_function on_check_func,
+ keycache_update_function on_update_func,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_ulonglong(name_arg, comment, flag_args, off, size,
+ getopt, min_val, max_val, def_val,
+ block_size, lock, binlog_status_arg, on_check_func, 0,
+ deprecated_version, substitute),
+ keycache_update(on_update_func)
+ {
+ option.var_type|= GET_ASK_ADDR;
+ option.value= (uchar**)1; // crash me, please
+ keycache_var(dflt_key_cache, off)= def_val;
+ DBUG_ASSERT(scope() == GLOBAL);
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ ulonglong new_value= var->save_result.ulonglong_value;
+ LEX_STRING *base_name= &var->base;
+ KEY_CACHE *key_cache;
+
+ /* If no basename, assume it's for the key cache named 'default' */
+ if (!base_name->length)
+ base_name= &default_key_cache_base;
+
+ key_cache= get_key_cache(base_name);
+
+ if (!key_cache)
+ { // Key cache didn't exists */
+ if (!new_value) // Tried to delete cache
+ return false; // Ok, nothing to do
+ if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
+ return true;
+ }
+
+ /**
+ Abort if some other thread is changing the key cache
+ @todo This should be changed so that we wait until the previous
+ assignment is done and then do the new assign
+ */
+ if (key_cache->in_init)
+ return true;
+
+ return keycache_update(thd, key_cache, offset, new_value);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ KEY_CACHE *key_cache= get_key_cache(base);
+ if (!key_cache)
+ key_cache= &zero_key_cache;
+ return keycache_var_ptr(key_cache, offset);
+ }
+};
+
+static bool update_buffer_size(THD *thd, KEY_CACHE *key_cache,
+ ptrdiff_t offset, ulonglong new_value)
+{
+ bool error= false;
+ DBUG_ASSERT(offset == offsetof(KEY_CACHE, param_buff_size));
+
+ if (new_value == 0)
+ {
+ if (key_cache == dflt_key_cache)
+ {
+ my_error(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, MYF(0));
+ return true;
+ }
+
+ if (key_cache->key_cache_inited) // If initied
+ {
+ /*
+ Move tables using this key cache to the default key cache
+ and clear the old key cache.
+ */
+ key_cache->in_init= 1;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ key_cache->param_buff_size= 0;
+ ha_resize_key_cache(key_cache);
+ ha_change_key_cache(key_cache, dflt_key_cache);
+ /*
+ We don't delete the key cache as some running threads my still be in
+ the key cache code with a pointer to the deleted (empty) key cache
+ */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ key_cache->in_init= 0;
+ }
+ return error;
+ }
+
+ key_cache->param_buff_size= new_value;
+
+ /* If key cache didn't exist initialize it, else resize it */
+ key_cache->in_init= 1;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+
+ if (!key_cache->key_cache_inited)
+ error= ha_init_key_cache(0, key_cache);
+ else
+ error= ha_resize_key_cache(key_cache);
+
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ key_cache->in_init= 0;
+
+ return error;
+}
+
+static bool update_keycache_param(THD *thd, KEY_CACHE *key_cache,
+ ptrdiff_t offset, ulonglong new_value)
+{
+ bool error= false;
+ DBUG_ASSERT(offset != offsetof(KEY_CACHE, param_buff_size));
+
+ keycache_var(key_cache, offset)= new_value;
+
+ key_cache->in_init= 1;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ error= ha_resize_key_cache(key_cache);
+
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ key_cache->in_init= 0;
+
+ return error;
+}
+
+/**
+ The class for floating point variables
+
+ Class specific constructor arguments: min, max
+
+ Backing store: double
+*/
+class Sys_var_double: public sys_var
+{
+public:
+ Sys_var_double(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ double min_val, double max_val, double def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_DOUBLE, def_val, lock, binlog_status_arg,
+ on_check_func, on_update_func, deprecated_version, substitute)
+ {
+ option.var_type= GET_DOUBLE;
+ option.min_value= min_val;
+ option.max_value= max_val;
+ global_var(double)= (double)option.def_value;
+ DBUG_ASSERT(min_val < max_val);
+ DBUG_ASSERT(min_val <= def_val);
+ DBUG_ASSERT(max_val >= def_val);
+ DBUG_ASSERT(size == sizeof(double));
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ my_bool fixed;
+ double v= var->value->val_real();
+ var->save_result.double_value= getopt_double_limit_value(v, &option, &fixed);
+
+ return throw_bounds_warning(thd, name.str, fixed, v);
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, double)= var->save_result.double_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(double)= var->save_result.double_value;
+ return false;
+ }
+ bool check_update_type(Item_result type)
+ {
+ return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.double_value= global_var(double); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.double_value= (double)option.def_value; }
+};
+
+/**
+ The class for the @max_user_connections.
+ It's derived from Sys_var_uint, but non-standard session value
+ requires a new class.
+
+ Class specific constructor arguments:
+ everything derived from Sys_var_uint
+
+ Backing store: uint
+*/
+class Sys_var_max_user_conn: public Sys_var_uint
+{
+public:
+ Sys_var_max_user_conn(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ uint min_val, uint max_val, uint def_val,
+ uint block_size, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_uint(name_arg, comment, SESSION, off, size, getopt,
+ min_val, max_val, def_val, block_size,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ { }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ if (thd->user_connect && thd->user_connect->user_resources.user_conn)
+ return (uchar*) &(thd->user_connect->user_resources.user_conn);
+ return global_value_ptr(thd, base);
+ }
+};
+
+// overflow-safe (1 << X)-1
+#define MAX_SET(X) ((((1UL << ((X)-1))-1) << 1) | 1)
+
+/**
+ The class for flagset variables - a variant of SET that allows in-place
+ editing (turning on/off individual bits). String representations looks like
+ a "flag=val,flag=val,...". Example: @@optimizer_switch
+
+ Class specific constructor arguments:
+ char* values[] - 0-terminated list of strings of valid values
+
+ Backing store: ulonglong
+
+ @note
+ the last value in the values[] array should
+ *always* be the string "default".
+*/
+class Sys_var_flagset: public Sys_var_typelib
+{
+public:
+ Sys_var_flagset(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ const char *values[], ulonglong def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
+ SHOW_CHAR, values, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ option.var_type= GET_FLAGSET;
+ global_var(ulonglong)= def_val;
+ DBUG_ASSERT(typelib.count > 1);
+ DBUG_ASSERT(typelib.count <= 65);
+ DBUG_ASSERT(def_val < MAX_SET(typelib.count));
+ DBUG_ASSERT(strcmp(values[typelib.count-1], "default") == 0);
+ DBUG_ASSERT(size == sizeof(ulonglong));
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
+ ulonglong default_value, current_value;
+ if (var->type == OPT_GLOBAL)
+ {
+ default_value= option.def_value;
+ current_value= global_var(ulonglong);
+ }
+ else
+ {
+ default_value= global_var(ulonglong);
+ current_value= session_var(thd, ulonglong);
+ }
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)))
+ return true;
+ else
+ {
+ char *error;
+ uint error_len;
+
+ var->save_result.ulonglong_value=
+ find_set_from_flags(&typelib,
+ typelib.count,
+ current_value,
+ default_value,
+ res->ptr(), res->length(),
+ &error, &error_len);
+ if (error)
+ {
+ ErrConvString err(error, error_len, res->charset());
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr());
+ return true;
+ }
+ }
+ }
+ else
+ {
+ longlong tmp=var->value->val_int();
+ if ((tmp < 0 && ! var->value->unsigned_flag)
+ || (ulonglong)tmp > MAX_SET(typelib.count))
+ return true;
+ else
+ var->save_result.ulonglong_value= tmp;
+ }
+
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, ulonglong)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(ulonglong)= var->save_result.ulonglong_value;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= global_var(ulonglong); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar*)flagset_to_string(thd, 0, session_var(thd, ulonglong),
+ typelib.type_names);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar*)flagset_to_string(thd, 0, global_var(ulonglong),
+ typelib.type_names);
+ }
+};
+
+/**
+ The class for SET variables - variables taking zero or more values
+ from the given list. Example: @@sql_mode
+
+ Class specific constructor arguments:
+ char* values[] - 0-terminated list of strings of valid values
+
+ Backing store: ulonglong
+*/
+class Sys_var_set: public Sys_var_typelib
+{
+public:
+ Sys_var_set(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ const char *values[], ulonglong def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
+ SHOW_CHAR, values, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ option.var_type= GET_SET;
+ global_var(ulonglong)= def_val;
+ DBUG_ASSERT(typelib.count > 0);
+ DBUG_ASSERT(typelib.count <= 64);
+ DBUG_ASSERT(def_val < MAX_SET(typelib.count));
+ DBUG_ASSERT(size == sizeof(ulonglong));
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
+
+ if (var->value->result_type() == STRING_RESULT)
+ {
+ if (!(res=var->value->val_str(&str)))
+ return true;
+ else
+ {
+ char *error;
+ uint error_len;
+ bool not_used;
+
+ var->save_result.ulonglong_value=
+ find_set(&typelib, res->ptr(), res->length(), NULL,
+ &error, &error_len, &not_used);
+ /*
+ note, we only issue an error if error_len > 0.
+ That is even while empty (zero-length) values are considered
+ errors by find_set(), these errors are ignored here
+ */
+ if (error_len)
+ {
+ ErrConvString err(error, error_len, res->charset());
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr());
+ return true;
+ }
+ }
+ }
+ else
+ {
+ longlong tmp=var->value->val_int();
+ if ((tmp < 0 && ! var->value->unsigned_flag)
+ || (ulonglong)tmp > MAX_SET(typelib.count))
+ return true;
+ else
+ var->save_result.ulonglong_value= tmp;
+ }
+
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, ulonglong)= var->save_result.ulonglong_value;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(ulonglong)= var->save_result.ulonglong_value;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= global_var(ulonglong); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar*)set_to_string(thd, 0, session_var(thd, ulonglong),
+ typelib.type_names);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar*)set_to_string(thd, 0, global_var(ulonglong),
+ typelib.type_names);
+ }
+};
+
+/**
+ The class for variables which value is a plugin.
+ Example: @@default_storage_engine
+
+ Class specific constructor arguments:
+ int plugin_type_arg (for example MYSQL_STORAGE_ENGINE_PLUGIN)
+
+ Backing store: plugin_ref
+
+ @note
+ these variables don't support command-line equivalents, any such
+ command-line options should be added manually to my_long_options in mysqld.cc
+*/
+class Sys_var_plugin: public sys_var
+{
+ int plugin_type;
+public:
+ Sys_var_plugin(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ int plugin_type_arg, char **def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_CHAR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute),
+ plugin_type(plugin_type_arg)
+ {
+ option.var_type= GET_STR;
+ DBUG_ASSERT(size == sizeof(plugin_ref));
+ DBUG_ASSERT(getopt.id == -1); // force NO_CMD_LINE
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff,sizeof(buff), system_charset_info), *res;
+ if (!(res=var->value->val_str(&str)))
+ var->save_result.plugin= NULL;
+ else
+ {
+ const LEX_STRING pname= { const_cast<char*>(res->ptr()), res->length() };
+ plugin_ref plugin;
+
+ // special code for storage engines (e.g. to handle historical aliases)
+ if (plugin_type == MYSQL_STORAGE_ENGINE_PLUGIN)
+ plugin= ha_resolve_by_name(thd, &pname);
+ else
+ plugin= my_plugin_lock_by_name(thd, &pname, plugin_type);
+ if (!plugin)
+ {
+ // historically different error code
+ if (plugin_type == MYSQL_STORAGE_ENGINE_PLUGIN)
+ {
+ ErrConvString err(res);
+ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), err.ptr());
+ }
+ return true;
+ }
+ var->save_result.plugin= plugin;
+ }
+ return false;
+ }
+ void do_update(plugin_ref *valptr, plugin_ref newval)
+ {
+ plugin_ref oldval= *valptr;
+ if (oldval != newval)
+ {
+ *valptr= my_plugin_lock(NULL, &newval);
+ plugin_unlock(NULL, oldval);
+ }
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ do_update((plugin_ref*)session_var_ptr(thd),
+ var->save_result.plugin);
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ do_update((plugin_ref*)global_var_ptr(),
+ var->save_result.plugin);
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ {
+ plugin_ref plugin= global_var(plugin_ref);
+ var->save_result.plugin= my_plugin_lock(thd, &plugin);
+ }
+ void global_save_default(THD *thd, set_var *var)
+ {
+ LEX_STRING pname;
+ pname.str= *(char**)option.def_value;
+ pname.length= strlen(pname.str);
+
+ plugin_ref plugin;
+ if (plugin_type == MYSQL_STORAGE_ENGINE_PLUGIN)
+ plugin= ha_resolve_by_name(thd, &pname);
+ else
+ plugin= my_plugin_lock_by_name(thd, &pname, plugin_type);
+ DBUG_ASSERT(plugin);
+
+ var->save_result.plugin= my_plugin_lock(thd, &plugin);
+ }
+ bool check_update_type(Item_result type)
+ { return type != STRING_RESULT; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ plugin_ref plugin= session_var(thd, plugin_ref);
+ return (uchar*)(plugin ? thd->strmake(plugin_name(plugin)->str,
+ plugin_name(plugin)->length) : 0);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ plugin_ref plugin= global_var(plugin_ref);
+ return (uchar*)(plugin ? thd->strmake(plugin_name(plugin)->str,
+ plugin_name(plugin)->length) : 0);
+ }
+};
+
+#if defined(ENABLED_DEBUG_SYNC)
+/**
+ The class for @@debug_sync session-only variable
+*/
+class Sys_var_debug_sync :public sys_var
+{
+public:
+ Sys_var_debug_sync(const char *name_arg,
+ const char *comment, int flag_args,
+ CMD_LINE getopt,
+ const char *def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, 0, getopt.id,
+ getopt.arg_type, SHOW_CHAR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ DBUG_ASSERT(scope() == ONLY_SESSION);
+ option.var_type= GET_NO_ARG;
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[STRING_BUFFER_USUAL_SIZE];
+ String str(buff, sizeof(buff), system_charset_info), *res;
+
+ if (!(res=var->value->val_str(&str)))
+ var->save_result.string_value.str= const_cast<char*>("");
+ else
+ var->save_result.string_value.str= thd->strmake(res->ptr(), res->length());
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ extern bool debug_sync_update(THD *thd, char *val_str);
+ return debug_sync_update(thd, var->save_result.string_value.str);
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ {
+ var->save_result.string_value.str= const_cast<char*>("");
+ var->save_result.string_value.length= 0;
+ }
+ void global_save_default(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ extern uchar *debug_sync_value_ptr(THD *thd);
+ return debug_sync_value_ptr(thd);
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ DBUG_ASSERT(FALSE);
+ return 0;
+ }
+ bool check_update_type(Item_result type)
+ { return type != STRING_RESULT; }
+};
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
+/**
+ The class for bit variables - a variant of boolean that stores the value
+ in a bit.
+
+ Class specific constructor arguments:
+ ulonglong bitmask_arg - the mask for the bit to set in the ulonglong
+ backing store
+
+ Backing store: ulonglong
+
+ @note
+ This class supports the "reverse" semantics, when the value of the bit
+ being 0 corresponds to the value of variable being set. To activate it
+ use REVERSE(bitmask) instead of simply bitmask in the constructor.
+
+ @note
+ variables of this class cannot be set from the command line as
+ my_getopt does not support bits.
+*/
+class Sys_var_bit: public Sys_var_typelib
+{
+ ulonglong bitmask;
+ bool reverse_semantics;
+ void set(uchar *ptr, ulonglong value)
+ {
+ if ((value != 0) ^ reverse_semantics)
+ (*(ulonglong *)ptr)|= bitmask;
+ else
+ (*(ulonglong *)ptr)&= ~bitmask;
+ }
+public:
+ Sys_var_bit(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ ulonglong bitmask_arg, my_bool def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_typelib(name_arg, comment, flag_args, off, getopt,
+ SHOW_MY_BOOL, bool_values, def_val, lock,
+ binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ option.var_type= GET_BOOL;
+ reverse_semantics= my_count_bits(bitmask_arg) > 1;
+ bitmask= reverse_semantics ? ~bitmask_arg : bitmask_arg;
+ set(global_var_ptr(), def_val);
+ DBUG_ASSERT(def_val < 2);
+ DBUG_ASSERT(getopt.id == -1); // force NO_CMD_LINE
+ DBUG_ASSERT(size == sizeof(ulonglong));
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ set(session_var_ptr(thd), var->save_result.ulonglong_value);
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ set(global_var_ptr(), var->save_result.ulonglong_value);
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= global_var(ulonglong) & bitmask; }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ulonglong_value= option.def_value; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ thd->sys_var_tmp.my_bool_value= reverse_semantics ^
+ ((session_var(thd, ulonglong) & bitmask) != 0);
+ return (uchar*) &thd->sys_var_tmp.my_bool_value;
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ thd->sys_var_tmp.my_bool_value= reverse_semantics ^
+ ((global_var(ulonglong) & bitmask) != 0);
+ return (uchar*) &thd->sys_var_tmp.my_bool_value;
+ }
+};
+
+/**
+ The class for variables that have a special meaning for a session,
+ such as @@timestamp or @@rnd_seed1, their values typically cannot be read
+ from SV structure, and a special "read" callback is provided.
+
+ Class specific constructor arguments:
+ everything derived from Sys_var_ulonglong
+ session_special_read_function read_func_arg
+
+ Backing store: ulonglong
+
+ @note
+ These variables are session-only, global or command-line equivalents
+ are not supported as they're generally meaningless.
+*/
+class Sys_var_session_special: public Sys_var_ulonglong
+{
+ typedef bool (*session_special_update_function)(THD *thd, set_var *var);
+ typedef ulonglong (*session_special_read_function)(THD *thd);
+
+ session_special_read_function read_func;
+ session_special_update_function update_func;
+public:
+ Sys_var_session_special(const char *name_arg,
+ const char *comment, int flag_args,
+ CMD_LINE getopt,
+ ulonglong min_val, ulonglong max_val, ulonglong block_size,
+ PolyLock *lock, enum binlog_status_enum binlog_status_arg,
+ on_check_function on_check_func,
+ session_special_update_function update_func_arg,
+ session_special_read_function read_func_arg,
+ uint deprecated_version=0, const char *substitute=0)
+ : Sys_var_ulonglong(name_arg, comment, flag_args, 0,
+ sizeof(ulonglong), getopt, min_val,
+ max_val, 0, block_size, lock, binlog_status_arg, on_check_func, 0,
+ deprecated_version, substitute),
+ read_func(read_func_arg), update_func(update_func_arg)
+ {
+ DBUG_ASSERT(scope() == ONLY_SESSION);
+ DBUG_ASSERT(getopt.id == -1); // NO_CMD_LINE, because the offset is fake
+ }
+ bool session_update(THD *thd, set_var *var)
+ { return update_func(thd, var); }
+ bool global_update(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->value= 0; }
+ void global_save_default(THD *thd, set_var *var)
+ { DBUG_ASSERT(FALSE); }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ thd->sys_var_tmp.ulonglong_value= read_func(thd);
+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ DBUG_ASSERT(FALSE);
+ return 0;
+ }
+};
+
+/**
+ The class for read-only variables that show whether a particular
+ feature is supported by the server. Example: have_compression
+
+ Backing store: enum SHOW_COMP_OPTION
+
+ @note
+ These variables are necessarily read-only, only global, and have no
+ command-line equivalent.
+*/
+class Sys_var_have: public sys_var
+{
+public:
+ Sys_var_have(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_CHAR, 0,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ DBUG_ASSERT(scope() == GLOBAL);
+ DBUG_ASSERT(getopt.id == -1);
+ DBUG_ASSERT(lock == 0);
+ DBUG_ASSERT(binlog_status_arg == VARIABLE_NOT_IN_BINLOG);
+ DBUG_ASSERT(is_readonly());
+ DBUG_ASSERT(on_update == 0);
+ DBUG_ASSERT(size == sizeof(enum SHOW_COMP_OPTION));
+ }
+ bool do_check(THD *thd, set_var *var) {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ DBUG_ASSERT(FALSE);
+ return true;
+ }
+ void session_save_default(THD *thd, set_var *var) { }
+ void global_save_default(THD *thd, set_var *var) { }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ DBUG_ASSERT(FALSE);
+ return 0;
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar*)show_comp_option_name[global_var(enum SHOW_COMP_OPTION)];
+ }
+ bool check_update_type(Item_result type) { return false; }
+};
+
+/**
+ Generic class for variables for storing entities that are internally
+ represented as structures, have names, and possibly can be referred to by
+ numbers. Examples: character sets, collations, locales,
+
+ Class specific constructor arguments:
+ ptrdiff_t name_offset - offset of the 'name' field in the structure
+
+ Backing store: void*
+
+ @note
+ As every such a structure requires special treatment from my_getopt,
+ these variables don't support command-line equivalents, any such
+ command-line options should be added manually to my_long_options in mysqld.cc
+*/
+class Sys_var_struct: public sys_var
+{
+ ptrdiff_t name_offset; // offset to the 'name' property in the structure
+public:
+ Sys_var_struct(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ ptrdiff_t name_off, void *def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_CHAR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute), name_offset(name_off)
+ {
+ option.var_type= GET_STR;
+ /*
+ struct variables are special on the command line - often (e.g. for
+ charsets) the name cannot be immediately resolved, but only after all
+ options (in particular, basedir) are parsed.
+
+ thus all struct command-line options should be added manually
+ to my_long_options in mysqld.cc
+ */
+ DBUG_ASSERT(getopt.id == -1);
+ DBUG_ASSERT(size == sizeof(void *));
+ }
+ bool do_check(THD *thd, set_var *var)
+ { return false; }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, void*)= var->save_result.ptr;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(void*)= var->save_result.ptr;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ { var->save_result.ptr= global_var(void*); }
+ void global_save_default(THD *thd, set_var *var)
+ { var->save_result.ptr= *(void**)option.def_value; }
+ bool check_update_type(Item_result type)
+ { return type != INT_RESULT && type != STRING_RESULT; }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ uchar *ptr= session_var(thd, uchar*);
+ return ptr ? *(uchar**)(ptr+name_offset) : 0;
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ uchar *ptr= global_var(uchar*);
+ return ptr ? *(uchar**)(ptr+name_offset) : 0;
+ }
+};
+
+/**
+ The class for variables that store time zones
+
+ Backing store: Time_zone*
+
+ @note
+ Time zones cannot be supported directly by my_getopt, thus
+ these variables don't support command-line equivalents, any such
+ command-line options should be added manually to my_long_options in mysqld.cc
+*/
+class Sys_var_tz: public sys_var
+{
+public:
+ Sys_var_tz(const char *name_arg,
+ const char *comment, int flag_args, ptrdiff_t off, size_t size,
+ CMD_LINE getopt,
+ Time_zone **def_val, PolyLock *lock=0,
+ enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
+ on_check_function on_check_func=0,
+ on_update_function on_update_func=0,
+ uint deprecated_version=0, const char *substitute=0)
+ : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
+ getopt.arg_type, SHOW_CHAR, (intptr)def_val,
+ lock, binlog_status_arg, on_check_func, on_update_func,
+ deprecated_version, substitute)
+ {
+ DBUG_ASSERT(getopt.id == -1);
+ DBUG_ASSERT(size == sizeof(Time_zone *));
+ }
+ bool do_check(THD *thd, set_var *var)
+ {
+ char buff[MAX_TIME_ZONE_NAME_LENGTH];
+ String str(buff, sizeof(buff), &my_charset_latin1);
+ String *res= var->value->val_str(&str);
+
+ if (!res)
+ return true;
+
+ if (!(var->save_result.time_zone= my_tz_find(thd, res)))
+ {
+ ErrConvString err(res);
+ my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), err.ptr());
+ return true;
+ }
+ return false;
+ }
+ bool session_update(THD *thd, set_var *var)
+ {
+ session_var(thd, Time_zone*)= var->save_result.time_zone;
+ return false;
+ }
+ bool global_update(THD *thd, set_var *var)
+ {
+ global_var(Time_zone*)= var->save_result.time_zone;
+ return false;
+ }
+ void session_save_default(THD *thd, set_var *var)
+ {
+ var->save_result.time_zone= global_var(Time_zone*);
+ }
+ void global_save_default(THD *thd, set_var *var)
+ {
+ var->save_result.time_zone=
+ *(Time_zone**)(intptr)option.def_value;
+ }
+ uchar *session_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ /*
+ This is an ugly fix for replication: we don't replicate properly queries
+ invoking system variables' values to update tables; but
+ CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
+ replicable (i.e. we tell the binlog code to store the session
+ timezone). If it's the global value which was used we can't replicate
+ (binlog code stores session value only).
+ */
+ thd->time_zone_used= 1;
+ return (uchar *)(session_var(thd, Time_zone*)->get_name()->ptr());
+ }
+ uchar *global_value_ptr(THD *thd, LEX_STRING *base)
+ {
+ return (uchar *)(global_var(Time_zone*)->get_name()->ptr());
+ }
+ bool check_update_type(Item_result type)
+ { return type != STRING_RESULT; }
+};
+
+/****************************************************************************
+ Used templates
+****************************************************************************/
+
+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
+template class List<set_var_base>;
+template class List_iterator_fast<set_var_base>;
+template class Sys_var_unsigned<uint, GET_UINT, SHOW_INT>;
+template class Sys_var_unsigned<ulong, GET_ULONG, SHOW_LONG>;
+template class Sys_var_unsigned<ha_rows, GET_HA_ROWS, SHOW_HA_ROWS>;
+template class Sys_var_unsigned<ulonglong, GET_ULL, SHOW_LONGLONG>;
+#endif
+
diff --git a/sql/sys_vars_shared.h b/sql/sys_vars_shared.h
new file mode 100644
index 00000000000..e996fdba52e
--- /dev/null
+++ b/sql/sys_vars_shared.h
@@ -0,0 +1,81 @@
+/* Copyright (C) 2002-2006 MySQL AB, 2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+ "protected" interface to sys_var - server configuration variables.
+
+ This header is included by files implementing support and utility
+ functions of sys_var's (set_var.cc) and files implementing
+ classes in the sys_var hierarchy (sql_plugin.cc)
+*/
+
+#include <mysql_priv.h>
+#include "set_var.h"
+
+extern bool throw_bounds_warning(THD *thd, const char *name,
+ bool fixed, bool is_unsigned, longlong v);
+extern bool throw_bounds_warning(THD *thd, const char *name, bool fixed,
+ double v);
+extern sys_var *intern_find_sys_var(const char *str, uint length);
+
+extern sys_var_chain all_sys_vars;
+
+/** wrapper to hide a mutex and an rwlock under a common interface */
+class PolyLock
+{
+public:
+ virtual void rdlock()= 0;
+ virtual void wrlock()= 0;
+ virtual void unlock()= 0;
+ virtual ~PolyLock() {}
+};
+
+class PolyLock_mutex: public PolyLock
+{
+ pthread_mutex_t *mutex;
+public:
+ PolyLock_mutex(pthread_mutex_t *arg): mutex(arg) {}
+ void rdlock() { pthread_mutex_lock(mutex); }
+ void wrlock() { pthread_mutex_lock(mutex); }
+ void unlock() { pthread_mutex_unlock(mutex); }
+};
+
+class PolyLock_rwlock: public PolyLock
+{
+ rw_lock_t *rwlock;
+public:
+ PolyLock_rwlock(rw_lock_t *arg): rwlock(arg) {}
+ void rdlock() { rw_rdlock(rwlock); }
+ void wrlock() { rw_wrlock(rwlock); }
+ void unlock() { rw_unlock(rwlock); }
+};
+
+class AutoWLock
+{
+ PolyLock *lock;
+public:
+ AutoWLock(PolyLock *l) : lock(l) { if (lock) lock->wrlock(); }
+ ~AutoWLock() { if (lock) lock->unlock(); }
+};
+
+class AutoRLock
+{
+ PolyLock *lock;
+public:
+ AutoRLock(PolyLock *l) : lock(l) { if (lock) lock->rdlock(); }
+ ~AutoRLock() { if (lock) lock->unlock(); }
+};
+
diff --git a/sql/table.cc b/sql/table.cc
index 0f68bb7c29e..eef03955183 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1406,12 +1406,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
key_part->store_length+=HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
- /*
- Mark that there may be many matching values for one key
- combination ('a', 'a ', 'a '...)
- */
- if (!(field->flags & BINARY_FLAG))
- keyinfo->flags|= HA_END_SPACE_KEY;
}
if (field->type() == MYSQL_TYPE_BIT)
key_part->key_part_flag|= HA_BIT_PART;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index dbed1a16982..0784b73f353 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1756,6 +1756,10 @@ end:
my_pthread_setspecific_ptr(THR_THD, 0);
my_pthread_setspecific_ptr(THR_MALLOC, 0);
}
+
+ default_tz= default_tz_name ? global_system_variables.time_zone
+ : my_tz_SYSTEM;
+
DBUG_RETURN(return_val);
}
diff --git a/sql/unireg.h b/sql/unireg.h
index 80c6ad23907..006ffff5d52 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -93,8 +93,8 @@
#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1)
-#define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD)
-#define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD)
+#define MAX_SORT_MEMORY 2048*1024
+#define MIN_SORT_MEMORY 32*1024
/* Memory allocated when parsing a statement / saving a statement */
#define MEM_ROOT_BLOCK_SIZE 8192