set_var.cc 112 KB
Newer Older
1
/* Copyright (C) 2000-2003 MySQL AB
unknown's avatar
unknown committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

   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; either version 2 of the License, or
   (at your option) any later version.

   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 */

/*
  Handling of MySQL SQL variables

  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.
25 26
  - If the variable should be changeable or one should be able to access it
    with @@variable_name, it should be added to the 'list of all variables'
27 28 29
    list (sys_variables) 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'
unknown's avatar
unknown committed
30
  - If the variable should be changed from the command line, add a definition
unknown's avatar
unknown committed
31
    of it in the my_option structure list in mysqld.cc
32 33
  - Don't forget to initialize new fields in global_system_variables and
    max_system_variables!
unknown's avatar
unknown committed
34 35 36
  - If the variable should show up in 'show variables' add it to the
    init_vars[] struct in this file

37 38 39 40 41 42
  NOTES:
    - 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).

unknown's avatar
unknown committed
43 44 45 46 47 48 49 50
  TODO:
    - Add full support for the variable character_set (for 4.1)

    - 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.
*/

51
#ifdef USE_PRAGMA_IMPLEMENTATION
unknown's avatar
unknown committed
52 53 54 55
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
56
#include <mysql.h>
unknown's avatar
unknown committed
57 58
#include "slave.h"
#include <my_getopt.h>
59
#include <thr_alarm.h>
unknown's avatar
unknown committed
60 61 62 63 64 65 66
#include <myisam.h>
#ifdef HAVE_BERKELEY_DB
#include "ha_berkeley.h"
#endif
#ifdef HAVE_INNOBASE_DB
#include "ha_innodb.h"
#endif
unknown's avatar
unknown committed
67 68 69
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
#endif
unknown's avatar
unknown committed
70 71 72 73 74

static HASH system_variable_hash;
const char *bool_type_names[]= { "OFF", "ON", NullS };
TYPELIB bool_typelib=
{
75
  array_elements(bool_type_names)-1, "", bool_type_names, NULL
unknown's avatar
unknown committed
76 77
};

78 79 80
const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
TYPELIB delay_key_write_typelib=
{
81 82
  array_elements(delay_key_write_type_names)-1, "",
  delay_key_write_type_names, NULL
83 84
};

85
static int sys_check_charset(THD *thd, set_var *var);
unknown's avatar
unknown committed
86 87
static bool sys_update_charset(THD *thd, set_var *var);
static void sys_set_default_charset(THD *thd, enum_var_type type);
88 89 90
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);
unknown's avatar
unknown committed
91 92 93 94
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);
unknown's avatar
unknown committed
95 96
static bool set_option_bit(THD *thd, set_var *var);
static bool set_option_autocommit(THD *thd, set_var *var);
97
static int  check_log_update(THD *thd, set_var *var);
unknown's avatar
unknown committed
98
static bool set_log_update(THD *thd, set_var *var);
99
static int  check_pseudo_thread_id(THD *thd, set_var *var);
100
static bool set_log_bin(THD *thd, set_var *var);
unknown's avatar
unknown committed
101 102
static void fix_low_priority_updates(THD *thd, enum_var_type type);
static void fix_tx_isolation(THD *thd, enum_var_type type);
unknown's avatar
unknown committed
103 104
static int check_completion_type(THD *thd, set_var *var);
static void fix_completion_type(THD *thd, enum_var_type type);
unknown's avatar
unknown committed
105 106
static void fix_net_read_timeout(THD *thd, enum_var_type type);
static void fix_net_write_timeout(THD *thd, enum_var_type type);
107
static void fix_net_retry_count(THD *thd, enum_var_type type);
unknown's avatar
unknown committed
108 109
static void fix_max_join_size(THD *thd, enum_var_type type);
static void fix_query_cache_size(THD *thd, enum_var_type type);
110
static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
111
static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
112 113
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);
114
static void fix_max_connections(THD *thd, enum_var_type type);
115
static int check_max_delayed_threads(THD *thd, set_var *var);
116 117
static void fix_thd_mem_root(THD *thd, enum_var_type type);
static void fix_trans_mem_root(THD *thd, enum_var_type type);
118
static void fix_server_id(THD *thd, enum_var_type type);
unknown's avatar
unknown committed
119
static KEY_CACHE *create_key_cache(const char *name, uint length);
120
void fix_sql_mode_var(THD *thd, enum_var_type type);
121 122
static byte *get_error_count(THD *thd);
static byte *get_warning_count(THD *thd);
123
static byte *get_prepared_stmt_count(THD *thd);
124
static byte *get_have_innodb(THD *thd);
unknown's avatar
unknown committed
125 126 127 128 129 130 131 132

/*
  Variable definition list

  These are variables that can be set from the command line, in
  alphabetic order
*/

133 134 135 136 137
sys_var_thd_ulong	sys_auto_increment_increment("auto_increment_increment",
                                                     &SV::auto_increment_increment);
sys_var_thd_ulong	sys_auto_increment_offset("auto_increment_offset",
                                                  &SV::auto_increment_offset);

138 139 140
sys_var_bool_ptr	sys_automatic_sp_privileges("automatic_sp_privileges",
					      &sp_automatic_privileges);

unknown's avatar
unknown committed
141 142 143 144
sys_var_long_ptr	sys_binlog_cache_size("binlog_cache_size",
					      &binlog_cache_size);
sys_var_thd_ulong	sys_bulk_insert_buff_size("bulk_insert_buffer_size",
						  &SV::bulk_insert_buff_size);
145
sys_var_character_set_server	sys_character_set_server("character_set_server");
146 147
sys_var_const_str       sys_charset_system("character_set_system",
                                           (char *)my_charset_utf8_general_ci.name);
148
sys_var_character_set_database	sys_character_set_database("character_set_database");
149
sys_var_character_set_client  sys_character_set_client("character_set_client");
unknown's avatar
unknown committed
150
sys_var_character_set_connection  sys_character_set_connection("character_set_connection");
151
sys_var_character_set_results sys_character_set_results("character_set_results");
unknown's avatar
unknown committed
152
sys_var_character_set_filesystem  sys_character_set_filesystem("character_set_filesystem");
unknown's avatar
unknown committed
153 154 155 156
sys_var_thd_ulong	sys_completion_type("completion_type",
					 &SV::completion_type,
					 check_completion_type,
					 fix_completion_type);
unknown's avatar
unknown committed
157
sys_var_collation_connection sys_collation_connection("collation_connection");
158 159
sys_var_collation_database sys_collation_database("collation_database");
sys_var_collation_server sys_collation_server("collation_server");
160 161
sys_var_long_ptr	sys_concurrent_insert("concurrent_insert",
                                              &myisam_concurrent_insert);
unknown's avatar
unknown committed
162 163
sys_var_long_ptr	sys_connect_timeout("connect_timeout",
					    &connect_timeout);
164 165 166 167
sys_var_enum		sys_delay_key_write("delay_key_write",
					    &delay_key_write_options,
					    &delay_key_write_typelib,
					    fix_delay_key_write);
unknown's avatar
unknown committed
168 169 170 171 172 173
sys_var_long_ptr	sys_delayed_insert_limit("delayed_insert_limit",
						 &delayed_insert_limit);
sys_var_long_ptr	sys_delayed_insert_timeout("delayed_insert_timeout",
						   &delayed_insert_timeout);
sys_var_long_ptr	sys_delayed_queue_size("delayed_queue_size",
					       &delayed_queue_size);
unknown's avatar
unknown committed
174 175
sys_var_long_ptr	sys_expire_logs_days("expire_logs_days",
					     &expire_logs_days);
unknown's avatar
unknown committed
176 177
sys_var_bool_ptr	sys_flush("flush", &myisam_flush);
sys_var_long_ptr	sys_flush_time("flush_time", &flush_time);
178 179 180 181 182 183 184 185 186 187 188
sys_var_str             sys_ft_boolean_syntax("ft_boolean_syntax",
                                         sys_check_ftb_syntax,
                                         sys_update_ftb_syntax,
                                         sys_default_ftb_syntax,
                                         ft_boolean_syntax);
sys_var_str             sys_init_connect("init_connect", 0,
                                         sys_update_init_connect,
                                         sys_default_init_connect,0);
sys_var_str             sys_init_slave("init_slave", 0,
                                       sys_update_init_slave,
                                       sys_default_init_slave,0);
unknown's avatar
unknown committed
189 190 191 192
sys_var_thd_ulong	sys_interactive_timeout("interactive_timeout",
						&SV::net_interactive_timeout);
sys_var_thd_ulong	sys_join_buffer_size("join_buffer_size",
					     &SV::join_buff_size);
193
sys_var_key_buffer_size	sys_key_buffer_size("key_buffer_size");
194
sys_var_key_cache_long  sys_key_cache_block_size("key_cache_block_size",
unknown's avatar
unknown committed
195 196
						 offsetof(KEY_CACHE,
							  param_block_size));
197
sys_var_key_cache_long	sys_key_cache_division_limit("key_cache_division_limit",
unknown's avatar
unknown committed
198 199
						     offsetof(KEY_CACHE,
							      param_division_limit));
200
sys_var_key_cache_long  sys_key_cache_age_threshold("key_cache_age_threshold",
unknown's avatar
unknown committed
201 202
						     offsetof(KEY_CACHE,
							      param_age_threshold));
unknown's avatar
unknown committed
203 204
sys_var_bool_ptr	sys_local_infile("local_infile",
					 &opt_local_infile);
205
sys_var_trust_routine_creators
206
sys_trust_routine_creators("log_bin_trust_routine_creators",
207
                           &trust_function_creators);
unknown's avatar
foo1  
unknown committed
208
sys_var_bool_ptr
209 210
sys_trust_function_creators("log_bin_trust_function_creators",
                            &trust_function_creators);
211
sys_var_thd_ulong	sys_log_warnings("log_warnings", &SV::log_warnings);
unknown's avatar
unknown committed
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
sys_var_thd_ulong	sys_long_query_time("long_query_time",
					     &SV::long_query_time);
sys_var_thd_bool	sys_low_priority_updates("low_priority_updates",
						 &SV::low_priority_updates,
						 fix_low_priority_updates);
#ifndef TO_BE_DELETED	/* Alias for the low_priority_updates */
sys_var_thd_bool	sys_sql_low_priority_updates("sql_low_priority_updates",
						     &SV::low_priority_updates,
						     fix_low_priority_updates);
#endif
sys_var_thd_ulong	sys_max_allowed_packet("max_allowed_packet",
					       &SV::max_allowed_packet);
sys_var_long_ptr	sys_max_binlog_cache_size("max_binlog_cache_size",
						  &max_binlog_cache_size);
sys_var_long_ptr	sys_max_binlog_size("max_binlog_size",
227 228
					    &max_binlog_size,
                                            fix_max_binlog_size);
unknown's avatar
unknown committed
229
sys_var_long_ptr	sys_max_connections("max_connections",
230 231
					    &max_connections,
                                            fix_max_connections);
unknown's avatar
unknown committed
232 233
sys_var_long_ptr	sys_max_connect_errors("max_connect_errors",
					       &max_connect_errors);
234
sys_var_thd_ulong       sys_max_insert_delayed_threads("max_insert_delayed_threads",
235 236 237
						       &SV::max_insert_delayed_threads,
                                                       check_max_delayed_threads,
                                                       fix_max_connections);
238 239
sys_var_thd_ulong	sys_max_delayed_threads("max_delayed_threads",
						&SV::max_insert_delayed_threads,
240 241
                                                check_max_delayed_threads,
                                                fix_max_connections);
242 243
sys_var_thd_ulong	sys_max_error_count("max_error_count",
					    &SV::max_error_count);
unknown's avatar
unknown committed
244 245
sys_var_thd_ulong	sys_max_heap_table_size("max_heap_table_size",
						&SV::max_heap_table_size);
246 247 248
sys_var_thd_ulong       sys_pseudo_thread_id("pseudo_thread_id",
					     &SV::pseudo_thread_id,
                                             check_pseudo_thread_id, 0);
249
sys_var_thd_ha_rows	sys_max_join_size("max_join_size",
unknown's avatar
unknown committed
250 251
					  &SV::max_join_size,
					  fix_max_join_size);
252 253
sys_var_thd_ulong	sys_max_seeks_for_key("max_seeks_for_key",
					      &SV::max_seeks_for_key);
unknown's avatar
unknown committed
254
sys_var_thd_ulong   sys_max_length_for_sort_data("max_length_for_sort_data",
255
                                                 &SV::max_length_for_sort_data);
unknown's avatar
unknown committed
256
#ifndef TO_BE_DELETED	/* Alias for max_join_size */
257
sys_var_thd_ha_rows	sys_sql_max_join_size("sql_max_join_size",
unknown's avatar
unknown committed
258 259 260
					      &SV::max_join_size,
					      fix_max_join_size);
#endif
261 262 263 264
static sys_var_long_ptr_global
sys_max_prepared_stmt_count("max_prepared_stmt_count",
                            &max_prepared_stmt_count,
                            &LOCK_prepared_stmt_count);
265 266 267
sys_var_long_ptr	sys_max_relay_log_size("max_relay_log_size",
                                               &max_relay_log_size,
                                               fix_max_relay_log_size);
unknown's avatar
unknown committed
268 269
sys_var_thd_ulong	sys_max_sort_length("max_sort_length",
					    &SV::max_sort_length);
270 271
sys_var_thd_ulong	sys_max_sp_recursion_depth("max_sp_recursion_depth",
                                                   &SV::max_sp_recursion_depth);
272
sys_var_max_user_conn   sys_max_user_connections("max_user_connections");
unknown's avatar
unknown committed
273 274 275 276
sys_var_thd_ulong	sys_max_tmp_tables("max_tmp_tables",
					   &SV::max_tmp_tables);
sys_var_long_ptr	sys_max_write_lock_count("max_write_lock_count",
						 &max_write_lock_count);
unknown's avatar
unknown committed
277 278
sys_var_thd_ulong       sys_multi_range_count("multi_range_count",
                                              &SV::multi_range_count);
unknown's avatar
unknown committed
279 280
sys_var_long_ptr	sys_myisam_data_pointer_size("myisam_data_pointer_size",
                                                    &myisam_data_pointer_size);
281
sys_var_thd_ulonglong	sys_myisam_max_sort_file_size("myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
282
sys_var_thd_ulong       sys_myisam_repair_threads("myisam_repair_threads", &SV::myisam_repair_threads);
unknown's avatar
unknown committed
283
sys_var_thd_ulong	sys_myisam_sort_buffer_size("myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
284 285 286 287 288 289

sys_var_thd_enum        sys_myisam_stats_method("myisam_stats_method",
                                                &SV::myisam_stats_method,
                                                &myisam_stats_method_typelib,
                                                NULL);

unknown's avatar
unknown committed
290 291 292 293
sys_var_thd_ulong	sys_net_buffer_length("net_buffer_length",
					      &SV::net_buffer_length);
sys_var_thd_ulong	sys_net_read_timeout("net_read_timeout",
					     &SV::net_read_timeout,
294
					     0, fix_net_read_timeout);
unknown's avatar
unknown committed
295 296
sys_var_thd_ulong	sys_net_write_timeout("net_write_timeout",
					      &SV::net_write_timeout,
297
					      0, fix_net_write_timeout);
298 299
sys_var_thd_ulong	sys_net_retry_count("net_retry_count",
					    &SV::net_retry_count,
300
					    0, fix_net_retry_count);
301
sys_var_thd_bool	sys_new_mode("new", &SV::new_mode);
302
sys_var_thd_bool	sys_old_passwords("old_passwords", &SV::old_passwords);
303 304 305 306
sys_var_thd_ulong       sys_optimizer_prune_level("optimizer_prune_level",
                                                  &SV::optimizer_prune_level);
sys_var_thd_ulong       sys_optimizer_search_depth("optimizer_search_depth",
                                                   &SV::optimizer_search_depth);
unknown's avatar
unknown committed
307 308
sys_var_thd_ulong       sys_preload_buff_size("preload_buffer_size",
                                              &SV::preload_buff_size);
unknown's avatar
unknown committed
309 310
sys_var_thd_ulong	sys_read_buff_size("read_buffer_size",
					   &SV::read_buff_size);
311
sys_var_bool_ptr	sys_readonly("read_only", &opt_readonly);
unknown's avatar
unknown committed
312 313
sys_var_thd_ulong	sys_read_rnd_buff_size("read_rnd_buffer_size",
					       &SV::read_rnd_buff_size);
unknown's avatar
unknown committed
314 315
sys_var_thd_ulong	sys_div_precincrement("div_precision_increment",
                                              &SV::div_precincrement);
316 317 318 319
#ifdef HAVE_REPLICATION
sys_var_bool_ptr	sys_relay_log_purge("relay_log_purge",
                                            &relay_log_purge);
#endif
unknown's avatar
unknown committed
320 321 322 323 324
sys_var_long_ptr	sys_rpl_recovery_rank("rpl_recovery_rank",
					      &rpl_recovery_rank);
sys_var_long_ptr	sys_query_cache_size("query_cache_size",
					     &query_cache_size,
					     fix_query_cache_size);
325 326 327 328

sys_var_thd_ulong	sys_range_alloc_block_size("range_alloc_block_size",
						   &SV::range_alloc_block_size);
sys_var_thd_ulong	sys_query_alloc_block_size("query_alloc_block_size",
329 330
						   &SV::query_alloc_block_size,
						   0, fix_thd_mem_root);
331
sys_var_thd_ulong	sys_query_prealloc_size("query_prealloc_size",
332 333
						&SV::query_prealloc_size,
						0, fix_thd_mem_root);
334
sys_var_thd_ulong	sys_trans_alloc_block_size("transaction_alloc_block_size",
335 336
						   &SV::trans_alloc_block_size,
						   0, fix_trans_mem_root);
337
sys_var_thd_ulong	sys_trans_prealloc_size("transaction_prealloc_size",
338 339
						&SV::trans_prealloc_size,
						0, fix_trans_mem_root);
340

unknown's avatar
unknown committed
341 342 343
#ifdef HAVE_QUERY_CACHE
sys_var_long_ptr	sys_query_cache_limit("query_cache_limit",
					      &query_cache.query_cache_limit);
344 345 346
sys_var_long_ptr        sys_query_cache_min_res_unit("query_cache_min_res_unit",
						     &query_cache_min_res_unit,
						     fix_query_cache_min_res_unit);
unknown's avatar
unknown committed
347 348 349
sys_var_thd_enum	sys_query_cache_type("query_cache_type",
					     &SV::query_cache_type,
					     &query_cache_type_typelib);
350 351 352
sys_var_thd_bool
sys_query_cache_wlock_invalidate("query_cache_wlock_invalidate",
				 &SV::query_cache_wlock_invalidate);
unknown's avatar
unknown committed
353
#endif /* HAVE_QUERY_CACHE */
354
sys_var_bool_ptr	sys_secure_auth("secure_auth", &opt_secure_auth);
355
sys_var_long_ptr	sys_server_id("server_id", &server_id, fix_server_id);
356 357
sys_var_bool_ptr	sys_slave_compressed_protocol("slave_compressed_protocol",
						      &opt_slave_compressed_protocol);
unknown's avatar
SCRUM  
unknown committed
358
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
359 360
sys_var_long_ptr	sys_slave_net_timeout("slave_net_timeout",
					      &slave_net_timeout);
361 362
sys_var_long_ptr	sys_slave_trans_retries("slave_transaction_retries",
                                                &slave_trans_retries);
363
#endif
unknown's avatar
unknown committed
364 365 366 367
sys_var_long_ptr	sys_slow_launch_time("slow_launch_time",
					     &slow_launch_time);
sys_var_thd_ulong	sys_sort_buffer("sort_buffer_size",
					&SV::sortbuff_size);
368 369
sys_var_thd_sql_mode    sys_sql_mode("sql_mode",
                                     &SV::sql_mode);
370 371 372 373
sys_var_thd_enum
sys_updatable_views_with_limit("updatable_views_with_limit",
                               &SV::updatable_views_with_limit,
                               &updatable_views_with_limit_typelib);
unknown's avatar
VIEW  
unknown committed
374

375 376
sys_var_thd_table_type  sys_table_type("table_type",
				       &SV::table_type);
unknown's avatar
unknown committed
377 378
sys_var_thd_storage_engine sys_storage_engine("storage_engine",
				       &SV::table_type);
379 380 381
#ifdef HAVE_REPLICATION
sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period);
#endif
382
sys_var_bool_ptr	sys_sync_frm("sync_frm", &opt_sync_frm);
unknown's avatar
unknown committed
383 384
sys_var_long_ptr	sys_table_cache_size("table_cache",
					     &table_cache_size);
385 386
sys_var_long_ptr	sys_table_lock_wait_timeout("table_lock_wait_timeout",
                                                    &table_lock_wait_timeout);
unknown's avatar
unknown committed
387 388 389 390 391 392 393 394
sys_var_long_ptr	sys_thread_cache_size("thread_cache_size",
					      &thread_cache_size);
sys_var_thd_enum	sys_tx_isolation("tx_isolation",
					 &SV::tx_isolation,
					 &tx_isolation_typelib,
					 fix_tx_isolation);
sys_var_thd_ulong	sys_tmp_table_size("tmp_table_size",
					   &SV::tmp_table_size);
unknown's avatar
unknown committed
395 396
sys_var_bool_ptr  sys_timed_mutexes("timed_mutexes",
                                    &timed_mutexes);
unknown's avatar
unknown committed
397 398
sys_var_thd_ulong	sys_net_wait_timeout("wait_timeout",
					     &SV::net_wait_timeout);
399

400
#ifdef HAVE_INNOBASE_DB
401 402
sys_var_long_ptr	sys_innodb_fast_shutdown("innodb_fast_shutdown",
						 &innobase_fast_shutdown);
403 404
sys_var_long_ptr        sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct",
                                                        &srv_max_buf_pool_modified_pct);
405 406
sys_var_long_ptr	sys_innodb_max_purge_lag("innodb_max_purge_lag",
							&srv_max_purge_lag);
407 408
sys_var_thd_bool	sys_innodb_table_locks("innodb_table_locks",
                                               &SV::innodb_table_locks);
409 410
sys_var_thd_bool	sys_innodb_support_xa("innodb_support_xa",
                                               &SV::innodb_support_xa);
411 412
sys_var_long_ptr	sys_innodb_autoextend_increment("innodb_autoextend_increment",
							&srv_auto_extend_increment);
413 414
sys_var_long_ptr	sys_innodb_sync_spin_loops("innodb_sync_spin_loops",
                                             &srv_n_spin_wait_rounds);
unknown's avatar
unknown committed
415
sys_var_long_ptr  sys_innodb_concurrency_tickets("innodb_concurrency_tickets",
unknown's avatar
unknown committed
416 417 418 419 420
                                             &srv_n_free_tickets_to_enter);
sys_var_long_ptr  sys_innodb_thread_sleep_delay("innodb_thread_sleep_delay",
                                                &srv_thread_sleep_delay);
sys_var_long_ptr  sys_innodb_thread_concurrency("innodb_thread_concurrency",
                                                &srv_thread_concurrency);
421 422
sys_var_long_ptr  sys_innodb_commit_concurrency("innodb_commit_concurrency",
                                                &srv_commit_concurrency);
unknown's avatar
unknown committed
423 424 425
sys_var_long_ptr  sys_innodb_flush_log_at_trx_commit(
                                        "innodb_flush_log_at_trx_commit",
                                        &srv_flush_log_at_trx_commit);
426
#endif
427

unknown's avatar
unknown committed
428 429 430 431 432
/* Condition pushdown to storage engine */
sys_var_thd_bool
sys_engine_condition_pushdown("engine_condition_pushdown",
			      &SV::engine_condition_pushdown);

433
#ifdef HAVE_NDBCLUSTER_DB
434
/* ndb thread specific variable settings */
435
sys_var_thd_ulong
436 437 438
sys_ndb_autoincrement_prefetch_sz("ndb_autoincrement_prefetch_sz",
				  &SV::ndb_autoincrement_prefetch_sz);
sys_var_thd_bool
439
sys_ndb_force_send("ndb_force_send", &SV::ndb_force_send);
440
sys_var_thd_bool
441
sys_ndb_use_exact_count("ndb_use_exact_count", &SV::ndb_use_exact_count);
442
sys_var_thd_bool
443
sys_ndb_use_transactions("ndb_use_transactions", &SV::ndb_use_transactions);
444 445
sys_var_long_ptr
sys_ndb_cache_check_time("ndb_cache_check_time", &ndb_cache_check_time);
446
#endif
447 448 449 450 451

/* Time/date/datetime formats */

sys_var_thd_date_time_format sys_time_format("time_format",
					     &SV::time_format,
452
					     MYSQL_TIMESTAMP_TIME);
453 454
sys_var_thd_date_time_format sys_date_format("date_format",
					     &SV::date_format,
455
					     MYSQL_TIMESTAMP_DATE);
456 457
sys_var_thd_date_time_format sys_datetime_format("datetime_format",
						 &SV::datetime_format,
458
						 MYSQL_TIMESTAMP_DATETIME);
459 460

/* Variables that are bits in THD */
unknown's avatar
unknown committed
461

462 463 464 465
sys_var_thd_bit sys_autocommit("autocommit", 0,
                               set_option_autocommit,
                               OPTION_NOT_AUTOCOMMIT,
                               1);
466
static sys_var_thd_bit	sys_big_tables("big_tables", 0,
unknown's avatar
unknown committed
467 468 469
				       set_option_bit,
				       OPTION_BIG_TABLES);
#ifndef TO_BE_DELETED	/* Alias for big_tables */
470
static sys_var_thd_bit	sys_sql_big_tables("sql_big_tables", 0,
unknown's avatar
unknown committed
471 472 473
					   set_option_bit,
					   OPTION_BIG_TABLES);
#endif
474
static sys_var_thd_bit	sys_big_selects("sql_big_selects", 0,
unknown's avatar
unknown committed
475
					set_option_bit,
476
					OPTION_BIG_SELECTS);
477
static sys_var_thd_bit	sys_log_off("sql_log_off", 0,
unknown's avatar
unknown committed
478 479 480
				    set_option_bit,
				    OPTION_LOG_OFF);
static sys_var_thd_bit	sys_log_update("sql_log_update",
481
                                       check_log_update,
unknown's avatar
unknown committed
482 483 484
				       set_log_update,
				       OPTION_UPDATE_LOG);
static sys_var_thd_bit	sys_log_binlog("sql_log_bin",
485 486 487 488
                                       check_log_update,
				       set_log_bin,
				       OPTION_BIN_LOG);
static sys_var_thd_bit	sys_sql_warnings("sql_warnings", 0,
unknown's avatar
unknown committed
489 490
					 set_option_bit,
					 OPTION_WARNINGS);
491 492
static sys_var_thd_bit	sys_sql_notes("sql_notes", 0,
					 set_option_bit,
493
					 OPTION_SQL_NOTES);
494
static sys_var_thd_bit	sys_auto_is_null("sql_auto_is_null", 0,
unknown's avatar
unknown committed
495 496
					 set_option_bit,
					 OPTION_AUTO_IS_NULL);
497
static sys_var_thd_bit	sys_safe_updates("sql_safe_updates", 0,
unknown's avatar
unknown committed
498 499
					 set_option_bit,
					 OPTION_SAFE_UPDATES);
500
static sys_var_thd_bit	sys_buffer_results("sql_buffer_result", 0,
unknown's avatar
unknown committed
501 502
					   set_option_bit,
					   OPTION_BUFFER_RESULT);
503
static sys_var_thd_bit	sys_quote_show_create("sql_quote_show_create", 0,
unknown's avatar
unknown committed
504 505
					      set_option_bit,
					      OPTION_QUOTE_SHOW_CREATE);
506
static sys_var_thd_bit	sys_foreign_key_checks("foreign_key_checks", 0,
507 508 509
					       set_option_bit,
					       OPTION_NO_FOREIGN_KEY_CHECKS,
					       1);
510
static sys_var_thd_bit	sys_unique_checks("unique_checks", 0,
511 512 513 514
					  set_option_bit,
					  OPTION_RELAXED_UNIQUE_CHECKS,
					  1);

unknown's avatar
unknown committed
515 516
/* Local state variables */

517
static sys_var_thd_ha_rows	sys_select_limit("sql_select_limit",
unknown's avatar
unknown committed
518 519 520 521 522
						 &SV::select_limit);
static sys_var_timestamp	sys_timestamp("timestamp");
static sys_var_last_insert_id	sys_last_insert_id("last_insert_id");
static sys_var_last_insert_id	sys_identity("identity");
static sys_var_insert_id	sys_insert_id("insert_id");
523 524 525 526 527 528 529 530
static sys_var_readonly		sys_error_count("error_count",
						OPT_SESSION,
						SHOW_LONG,
						get_error_count);
static sys_var_readonly		sys_warning_count("warning_count",
						  OPT_SESSION,
						  SHOW_LONG,
						  get_warning_count);
531 532 533
static sys_var_readonly	sys_prepared_stmt_count("prepared_stmt_count",
                                                OPT_GLOBAL, SHOW_LONG,
                                                get_prepared_stmt_count);
534

unknown's avatar
unknown committed
535
/* alias for last_insert_id() to be compatible with Sybase */
unknown's avatar
SCRUM  
unknown committed
536
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
537
static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter");
538
#endif
539 540
static sys_var_rand_seed1	sys_rand_seed1("rand_seed1");
static sys_var_rand_seed2	sys_rand_seed2("rand_seed2");
unknown's avatar
unknown committed
541

542 543
static sys_var_thd_ulong        sys_default_week_format("default_week_format",
					                &SV::default_week_format);
unknown's avatar
unknown committed
544

unknown's avatar
unknown committed
545 546 547
sys_var_thd_ulong               sys_group_concat_max_len("group_concat_max_len",
                                                         &SV::group_concat_max_len);

548
sys_var_thd_time_zone            sys_time_zone("time_zone");
549 550 551 552

/* Read only variables */

sys_var_const_str		sys_os("version_compile_os", SYSTEM_TYPE);
553 554
sys_var_readonly                sys_have_innodb("have_innodb", OPT_GLOBAL,
                                                SHOW_CHAR, get_have_innodb);
555
/* Global read-only variable describing server license */
556
sys_var_const_str		sys_license("license", STRINGIFY_ARG(LICENSE));
557 558


unknown's avatar
unknown committed
559 560 561 562 563 564 565 566 567 568 569
/*
  List of all variables for initialisation and storage in hash
  This is sorted in alphabetical order to make it easy to add new variables

  If the variable is not in this list, it can't be changed with
  SET variable_name=
*/

sys_var *sys_variables[]=
{
  &sys_auto_is_null,
570 571
  &sys_auto_increment_increment,
  &sys_auto_increment_offset,
unknown's avatar
unknown committed
572
  &sys_autocommit,
573
  &sys_automatic_sp_privileges,
unknown's avatar
unknown committed
574 575 576 577 578
  &sys_big_tables,
  &sys_big_selects,
  &sys_binlog_cache_size,
  &sys_buffer_results,
  &sys_bulk_insert_buff_size,
579 580
  &sys_character_set_server,
  &sys_character_set_database,
581
  &sys_character_set_client,
unknown's avatar
unknown committed
582
  &sys_character_set_connection,
583
  &sys_character_set_results,
unknown's avatar
unknown committed
584
  &sys_character_set_filesystem,
585
  &sys_charset_system,
unknown's avatar
unknown committed
586
  &sys_collation_connection,
587 588
  &sys_collation_database,
  &sys_collation_server,
unknown's avatar
unknown committed
589
  &sys_completion_type,
unknown's avatar
unknown committed
590 591
  &sys_concurrent_insert,
  &sys_connect_timeout,
592 593
  &sys_date_format,
  &sys_datetime_format,
unknown's avatar
unknown committed
594
  &sys_div_precincrement,
595
  &sys_default_week_format,
unknown's avatar
unknown committed
596 597 598 599
  &sys_delay_key_write,
  &sys_delayed_insert_limit,
  &sys_delayed_insert_timeout,
  &sys_delayed_queue_size,
600
  &sys_error_count,
unknown's avatar
unknown committed
601
  &sys_expire_logs_days,
unknown's avatar
unknown committed
602 603
  &sys_flush,
  &sys_flush_time,
604
  &sys_ft_boolean_syntax,
605
  &sys_foreign_key_checks,
unknown's avatar
unknown committed
606
  &sys_group_concat_max_len,
607
  &sys_have_innodb,
unknown's avatar
unknown committed
608
  &sys_identity,
unknown's avatar
unknown committed
609 610
  &sys_init_connect,
  &sys_init_slave,
unknown's avatar
unknown committed
611 612 613 614
  &sys_insert_id,
  &sys_interactive_timeout,
  &sys_join_buffer_size,
  &sys_key_buffer_size,
unknown's avatar
unknown committed
615
  &sys_key_cache_block_size,
616 617
  &sys_key_cache_division_limit,
  &sys_key_cache_age_threshold,
unknown's avatar
unknown committed
618
  &sys_last_insert_id,
619
  &sys_license,
unknown's avatar
unknown committed
620 621 622 623 624 625 626 627 628 629 630 631 632
  &sys_local_infile,
  &sys_log_binlog,
  &sys_log_off,
  &sys_log_update,
  &sys_log_warnings,
  &sys_long_query_time,
  &sys_low_priority_updates,
  &sys_max_allowed_packet,
  &sys_max_binlog_cache_size,
  &sys_max_binlog_size,
  &sys_max_connect_errors,
  &sys_max_connections,
  &sys_max_delayed_threads,
633
  &sys_max_error_count,
634
  &sys_max_insert_delayed_threads,
unknown's avatar
unknown committed
635 636
  &sys_max_heap_table_size,
  &sys_max_join_size,
unknown's avatar
unknown committed
637
  &sys_max_length_for_sort_data,
638
  &sys_max_prepared_stmt_count,
639
  &sys_max_relay_log_size,
640
  &sys_max_seeks_for_key,
unknown's avatar
unknown committed
641
  &sys_max_sort_length,
642
  &sys_max_sp_recursion_depth,
unknown's avatar
unknown committed
643 644 645
  &sys_max_tmp_tables,
  &sys_max_user_connections,
  &sys_max_write_lock_count,
unknown's avatar
unknown committed
646
  &sys_multi_range_count,
unknown's avatar
unknown committed
647
  &sys_myisam_data_pointer_size,
unknown's avatar
unknown committed
648
  &sys_myisam_max_sort_file_size,
649
  &sys_myisam_repair_threads,
unknown's avatar
unknown committed
650
  &sys_myisam_sort_buffer_size,
651
  &sys_myisam_stats_method,
unknown's avatar
unknown committed
652 653
  &sys_net_buffer_length,
  &sys_net_read_timeout,
654
  &sys_net_retry_count,
unknown's avatar
unknown committed
655 656
  &sys_net_wait_timeout,
  &sys_net_write_timeout,
657
  &sys_new_mode,
658
  &sys_old_passwords,
659 660
  &sys_optimizer_prune_level,
  &sys_optimizer_search_depth,
unknown's avatar
unknown committed
661
  &sys_preload_buff_size,
662
  &sys_prepared_stmt_count,
unknown's avatar
unknown committed
663
  &sys_pseudo_thread_id,
664
  &sys_query_alloc_block_size,
unknown's avatar
unknown committed
665
  &sys_query_cache_size,
666
  &sys_query_prealloc_size,
unknown's avatar
unknown committed
667 668
#ifdef HAVE_QUERY_CACHE
  &sys_query_cache_limit,
669
  &sys_query_cache_min_res_unit,
unknown's avatar
unknown committed
670
  &sys_query_cache_type,
671
  &sys_query_cache_wlock_invalidate,
672
#endif /* HAVE_QUERY_CACHE */
unknown's avatar
unknown committed
673
  &sys_quote_show_create,
674 675
  &sys_rand_seed1,
  &sys_rand_seed2,
676
  &sys_range_alloc_block_size,
677
  &sys_readonly,
unknown's avatar
unknown committed
678 679
  &sys_read_buff_size,
  &sys_read_rnd_buff_size,
680 681 682
#ifdef HAVE_REPLICATION
  &sys_relay_log_purge,
#endif
unknown's avatar
unknown committed
683 684
  &sys_rpl_recovery_rank,
  &sys_safe_updates,
685
  &sys_secure_auth,
unknown's avatar
unknown committed
686 687
  &sys_select_limit,
  &sys_server_id,
unknown's avatar
SCRUM  
unknown committed
688
#ifdef HAVE_REPLICATION
689
  &sys_slave_compressed_protocol,
unknown's avatar
unknown committed
690
  &sys_slave_net_timeout,
691
  &sys_slave_trans_retries,
unknown's avatar
unknown committed
692
  &sys_slave_skip_counter,
693
#endif
unknown's avatar
unknown committed
694 695 696 697 698
  &sys_slow_launch_time,
  &sys_sort_buffer,
  &sys_sql_big_tables,
  &sys_sql_low_priority_updates,
  &sys_sql_max_join_size,
699
  &sys_sql_mode,
unknown's avatar
unknown committed
700
  &sys_sql_warnings,
701
  &sys_sql_notes,
unknown's avatar
unknown committed
702
  &sys_storage_engine,
703 704 705
#ifdef HAVE_REPLICATION
  &sys_sync_binlog_period,
#endif
706
  &sys_sync_frm,
unknown's avatar
unknown committed
707
  &sys_table_cache_size,
708
  &sys_table_lock_wait_timeout,
unknown's avatar
unknown committed
709 710
  &sys_table_type,
  &sys_thread_cache_size,
711
  &sys_time_format,
unknown's avatar
unknown committed
712
  &sys_timed_mutexes,
unknown's avatar
unknown committed
713
  &sys_timestamp,
714
  &sys_time_zone,
unknown's avatar
unknown committed
715
  &sys_tmp_table_size,
716 717
  &sys_trans_alloc_block_size,
  &sys_trans_prealloc_size,
unknown's avatar
unknown committed
718
  &sys_tx_isolation,
719
  &sys_os,
720
#ifdef HAVE_INNOBASE_DB
721
  &sys_innodb_fast_shutdown,
722
  &sys_innodb_max_dirty_pages_pct,
723
  &sys_innodb_max_purge_lag,
724
  &sys_innodb_table_locks,
725
  &sys_innodb_support_xa,
726
  &sys_innodb_max_purge_lag,
727
  &sys_innodb_autoextend_increment,
728
  &sys_innodb_sync_spin_loops,
unknown's avatar
unknown committed
729
  &sys_innodb_concurrency_tickets,
unknown's avatar
unknown committed
730 731
  &sys_innodb_thread_sleep_delay,
  &sys_innodb_thread_concurrency,
732
  &sys_innodb_commit_concurrency,
unknown's avatar
unknown committed
733
  &sys_innodb_flush_log_at_trx_commit,
unknown's avatar
foo1  
unknown committed
734
#endif
735
  &sys_trust_routine_creators,
736
  &sys_trust_function_creators,
unknown's avatar
unknown committed
737
  &sys_engine_condition_pushdown,
738 739
#ifdef HAVE_NDBCLUSTER_DB
  &sys_ndb_autoincrement_prefetch_sz,
740
  &sys_ndb_cache_check_time,
741 742 743
  &sys_ndb_force_send,
  &sys_ndb_use_exact_count,
  &sys_ndb_use_transactions,
744
#endif
745
  &sys_unique_checks,
746
  &sys_updatable_views_with_limit,
747
  &sys_warning_count
unknown's avatar
unknown committed
748 749 750 751 752 753 754 755
};


/*
  Variables shown by SHOW variables in alphabetical order
*/

struct show_var_st init_vars[]= {
756
  {"auto_increment_increment", (char*) &sys_auto_increment_increment, SHOW_SYS},
757
  {"auto_increment_offset",   (char*) &sys_auto_increment_offset, SHOW_SYS},
758
  {sys_automatic_sp_privileges.name,(char*) &sys_automatic_sp_privileges,       SHOW_SYS},
unknown's avatar
unknown committed
759 760 761 762 763
  {"back_log",                (char*) &back_log,                    SHOW_LONG},
  {"basedir",                 mysql_home,                           SHOW_CHAR},
#ifdef HAVE_BERKELEY_DB
  {"bdb_cache_size",          (char*) &berkeley_cache_size,         SHOW_LONG},
  {"bdb_home",                (char*) &berkeley_home,               SHOW_CHAR_PTR},
764
  {"bdb_log_buffer_size",     (char*) &berkeley_log_buffer_size,    SHOW_LONG},
unknown's avatar
unknown committed
765
  {"bdb_logdir",              (char*) &berkeley_logdir,             SHOW_CHAR_PTR},
766
  {"bdb_max_lock",            (char*) &berkeley_max_lock,	    SHOW_LONG},
unknown's avatar
unknown committed
767 768 769 770 771
  {"bdb_shared_data",	      (char*) &berkeley_shared_data,	    SHOW_BOOL},
  {"bdb_tmpdir",              (char*) &berkeley_tmpdir,             SHOW_CHAR_PTR},
#endif
  {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size,	    SHOW_SYS},
  {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
772
  {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
unknown's avatar
unknown committed
773
  {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
774
  {sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS},
unknown's avatar
unknown committed
775
  {sys_character_set_filesystem.name,(char*) &sys_character_set_filesystem, SHOW_SYS},
776
  {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS},
777 778 779
  {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS},
  {sys_charset_system.name,   (char*) &sys_charset_system,          SHOW_SYS},
  {"character_sets_dir",      mysql_charsets_dir,                   SHOW_CHAR},
unknown's avatar
unknown committed
780
  {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS},
781 782
  {sys_collation_database.name,(char*) &sys_collation_database,     SHOW_SYS},
  {sys_collation_server.name,(char*) &sys_collation_server,         SHOW_SYS},
unknown's avatar
unknown committed
783
  {sys_completion_type.name,  (char*) &sys_completion_type,	    SHOW_SYS},
unknown's avatar
unknown committed
784 785 786
  {sys_concurrent_insert.name,(char*) &sys_concurrent_insert,       SHOW_SYS},
  {sys_connect_timeout.name,  (char*) &sys_connect_timeout,         SHOW_SYS},
  {"datadir",                 mysql_real_data_home,                 SHOW_CHAR},
787 788 789
  {sys_date_format.name,      (char*) &sys_date_format,		    SHOW_SYS},
  {sys_datetime_format.name,  (char*) &sys_datetime_format,	    SHOW_SYS},
  {sys_default_week_format.name, (char*) &sys_default_week_format,  SHOW_SYS},
unknown's avatar
unknown committed
790 791 792 793
  {sys_delay_key_write.name,  (char*) &sys_delay_key_write,         SHOW_SYS},
  {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
  {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS},
  {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size,     SHOW_SYS},
unknown's avatar
unknown committed
794
  {sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS},
unknown's avatar
foo1  
unknown committed
795
  {sys_engine_condition_pushdown.name,
unknown's avatar
unknown committed
796
   (char*) &sys_engine_condition_pushdown,                          SHOW_SYS},
unknown's avatar
unknown committed
797
  {sys_expire_logs_days.name, (char*) &sys_expire_logs_days,        SHOW_SYS},
unknown's avatar
unknown committed
798 799
  {sys_flush.name,             (char*) &sys_flush,                  SHOW_SYS},
  {sys_flush_time.name,        (char*) &sys_flush_time,             SHOW_SYS},
800
  {sys_ft_boolean_syntax.name,(char*) &ft_boolean_syntax,	    SHOW_CHAR},
unknown's avatar
unknown committed
801
  {"ft_max_word_len",         (char*) &ft_max_word_len,             SHOW_LONG},
802
  {"ft_min_word_len",         (char*) &ft_min_word_len,             SHOW_LONG},
803
  {"ft_query_expansion_limit",(char*) &ft_query_expansion_limit,    SHOW_LONG},
804
  {"ft_stopword_file",        (char*) &ft_stopword_file,            SHOW_CHAR_PTR},
805
  {sys_group_concat_max_len.name, (char*) &sys_group_concat_max_len,  SHOW_SYS},
806
  {"have_archive",	      (char*) &have_archive_db,	            SHOW_HAVE},
unknown's avatar
unknown committed
807
  {"have_bdb",		      (char*) &have_berkeley_db,	    SHOW_HAVE},
808
  {"have_blackhole_engine",   (char*) &have_blackhole_db,	    SHOW_HAVE},
unknown's avatar
unknown committed
809
  {"have_compress",	      (char*) &have_compress,		    SHOW_HAVE},
810
  {"have_crypt",	      (char*) &have_crypt,		    SHOW_HAVE},
811
  {"have_csv",	              (char*) &have_csv_db,	            SHOW_HAVE},
812
  {"have_example_engine",     (char*) &have_example_db,	            SHOW_HAVE},
813
  {"have_federated_engine",   (char*) &have_federated_db,           SHOW_HAVE},
unknown's avatar
unknown committed
814
  {"have_geometry",           (char*) &have_geometry,               SHOW_HAVE},
unknown's avatar
unknown committed
815
  {"have_innodb",	      (char*) &have_innodb,		    SHOW_HAVE},
816
  {"have_isam",		      (char*) &have_isam,		    SHOW_HAVE},
unknown's avatar
unknown committed
817
  {"have_ndbcluster",         (char*) &have_ndbcluster,             SHOW_HAVE},
unknown's avatar
unknown committed
818 819
  {"have_openssl",	      (char*) &have_openssl,		    SHOW_HAVE},
  {"have_query_cache",        (char*) &have_query_cache,            SHOW_HAVE},
820
  {"have_raid",		      (char*) &have_raid,		    SHOW_HAVE},
821
  {"have_rtree_keys",         (char*) &have_rtree_keys,             SHOW_HAVE},
822
  {"have_symlink",            (char*) &have_symlink,                SHOW_HAVE},
unknown's avatar
unknown committed
823
  {"init_connect",            (char*) &sys_init_connect,            SHOW_SYS},
824
  {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
unknown's avatar
unknown committed
825
  {"init_slave",              (char*) &sys_init_slave,              SHOW_SYS},
unknown's avatar
unknown committed
826 827
#ifdef HAVE_INNOBASE_DB
  {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
828
  {sys_innodb_autoextend_increment.name, (char*) &sys_innodb_autoextend_increment, SHOW_SYS},
unknown's avatar
unknown committed
829
  {"innodb_buffer_pool_awe_mem_mb", (char*) &innobase_buffer_pool_awe_mem_mb, SHOW_LONG },
830
  {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONGLONG },
unknown's avatar
unknown committed
831
  {"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL},
unknown's avatar
unknown committed
832
  {sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS},
unknown's avatar
unknown committed
833
  {sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS},
unknown's avatar
unknown committed
834 835
  {"innodb_data_file_path", (char*) &innobase_data_file_path,	    SHOW_CHAR_PTR},
  {"innodb_data_home_dir",  (char*) &innobase_data_home_dir,	    SHOW_CHAR_PTR},
836
  {"innodb_doublewrite", (char*) &innobase_use_doublewrite, SHOW_MY_BOOL},
837
  {sys_innodb_fast_shutdown.name,(char*) &sys_innodb_fast_shutdown, SHOW_SYS},
838
  {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG },
unknown's avatar
unknown committed
839
  {"innodb_file_per_table", (char*) &innobase_file_per_table, SHOW_MY_BOOL},
unknown's avatar
unknown committed
840
  {sys_innodb_flush_log_at_trx_commit.name, (char*) &sys_innodb_flush_log_at_trx_commit, SHOW_SYS},
unknown's avatar
unknown committed
841
  {"innodb_flush_method",    (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR},
842
  {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG },
unknown's avatar
unknown committed
843
  {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG },
unknown's avatar
unknown committed
844
  {"innodb_locks_unsafe_for_binlog", (char*) &innobase_locks_unsafe_for_binlog, SHOW_MY_BOOL},
unknown's avatar
unknown committed
845 846 847
  {"innodb_log_arch_dir",   (char*) &innobase_log_arch_dir, 	    SHOW_CHAR_PTR},
  {"innodb_log_archive",    (char*) &innobase_log_archive, 	    SHOW_MY_BOOL},
  {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG },
848
  {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONGLONG},
unknown's avatar
unknown committed
849 850
  {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group,	SHOW_LONG},
  {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR},
851
  {sys_innodb_max_dirty_pages_pct.name, (char*) &sys_innodb_max_dirty_pages_pct, SHOW_SYS},
852
  {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS},
853 854
  {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
  {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG },
unknown's avatar
unknown committed
855
  {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS},
856
  {sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS},
unknown's avatar
unknown committed
857
  {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
unknown's avatar
unknown committed
858 859
  {sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
  {sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
unknown's avatar
unknown committed
860 861 862 863
#endif
  {sys_interactive_timeout.name,(char*) &sys_interactive_timeout,   SHOW_SYS},
  {sys_join_buffer_size.name,   (char*) &sys_join_buffer_size,	    SHOW_SYS},
  {sys_key_buffer_size.name,	(char*) &sys_key_buffer_size,	    SHOW_SYS},
864 865
  {sys_key_cache_age_threshold.name,   (char*) &sys_key_cache_age_threshold,
                                                                    SHOW_SYS},
unknown's avatar
unknown committed
866
  {sys_key_cache_block_size.name,   (char*) &sys_key_cache_block_size,
867
                                                                    SHOW_SYS},
868
  {sys_key_cache_division_limit.name,   (char*) &sys_key_cache_division_limit,
869
                                                                    SHOW_SYS},
unknown's avatar
unknown committed
870
  {"language",                language,                             SHOW_CHAR},
871
  {"large_files_support",     (char*) &opt_large_files,             SHOW_BOOL},
872
  {"large_page_size",         (char*) &opt_large_page_size,         SHOW_INT},
unknown's avatar
unknown committed
873
  {"large_pages",             (char*) &opt_large_pages,             SHOW_MY_BOOL},
874
  {sys_license.name,	      (char*) &sys_license,                 SHOW_SYS},
unknown's avatar
unknown committed
875 876 877 878 879 880
  {sys_local_infile.name,     (char*) &sys_local_infile,	    SHOW_SYS},
#ifdef HAVE_MLOCKALL
  {"locked_in_memory",	      (char*) &locked_in_memory,	    SHOW_BOOL},
#endif
  {"log",                     (char*) &opt_log,                     SHOW_BOOL},
  {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
881
  {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
882
  {"log_error",               (char*) log_error_file,               SHOW_CHAR},
unknown's avatar
SCRUM  
unknown committed
883
#ifdef HAVE_REPLICATION
884
  {"log_slave_updates",       (char*) &opt_log_slave_updates,       SHOW_MY_BOOL},
885
#endif
unknown's avatar
unknown committed
886 887 888 889
  {"log_slow_queries",        (char*) &opt_slow_log,                SHOW_BOOL},
  {sys_log_warnings.name,     (char*) &sys_log_warnings,	    SHOW_SYS},
  {sys_long_query_time.name,  (char*) &sys_long_query_time, 	    SHOW_SYS},
  {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
890
  {"lower_case_file_system",  (char*) &lower_case_file_system,      SHOW_MY_BOOL},
891
  {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_INT},
unknown's avatar
unknown committed
892 893 894 895
  {sys_max_allowed_packet.name,(char*) &sys_max_allowed_packet,	    SHOW_SYS},
  {sys_max_binlog_cache_size.name,(char*) &sys_max_binlog_cache_size, SHOW_SYS},
  {sys_max_binlog_size.name,    (char*) &sys_max_binlog_size,	    SHOW_SYS},
  {sys_max_connect_errors.name, (char*) &sys_max_connect_errors,    SHOW_SYS},
896
  {sys_max_connections.name,    (char*) &sys_max_connections,	    SHOW_SYS},
unknown's avatar
unknown committed
897
  {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads,   SHOW_SYS},
898
  {sys_max_error_count.name,	(char*) &sys_max_error_count,	    SHOW_SYS},
unknown's avatar
unknown committed
899
  {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size,   SHOW_SYS},
900 901
  {sys_max_insert_delayed_threads.name,
   (char*) &sys_max_insert_delayed_threads,   SHOW_SYS},
unknown's avatar
unknown committed
902
  {sys_max_join_size.name,	(char*) &sys_max_join_size,	    SHOW_SYS},
unknown's avatar
unknown committed
903
  {sys_max_length_for_sort_data.name, (char*) &sys_max_length_for_sort_data,
unknown's avatar
unknown committed
904
   SHOW_SYS},
905 906
  {sys_max_prepared_stmt_count.name, (char*) &sys_max_prepared_stmt_count,
    SHOW_SYS},
907 908
  {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size,    SHOW_SYS},
  {sys_max_seeks_for_key.name,  (char*) &sys_max_seeks_for_key,	    SHOW_SYS},
unknown's avatar
unknown committed
909
  {sys_max_sort_length.name,	(char*) &sys_max_sort_length,	    SHOW_SYS},
910 911
  {sys_max_sp_recursion_depth.name,
    (char*) &sys_max_sp_recursion_depth, SHOW_SYS},
912
  {sys_max_tmp_tables.name,	(char*) &sys_max_tmp_tables,	    SHOW_SYS},
913
  {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
unknown's avatar
unknown committed
914
  {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
unknown's avatar
unknown committed
915
  {sys_multi_range_count.name,  (char*) &sys_multi_range_count,     SHOW_SYS},
unknown's avatar
unknown committed
916
  {sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS},
917 918
  {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size,
   SHOW_SYS},
919
  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
920
  {sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads,
unknown's avatar
unknown committed
921 922
   SHOW_SYS},
  {sys_myisam_sort_buffer_size.name, (char*) &sys_myisam_sort_buffer_size, SHOW_SYS},
unknown's avatar
foo1  
unknown committed
923

924
  {sys_myisam_stats_method.name, (char*) &sys_myisam_stats_method, SHOW_SYS},
unknown's avatar
foo1  
unknown committed
925

unknown's avatar
unknown committed
926
#ifdef __NT__
927
  {"named_pipe",	      (char*) &opt_enable_named_pipe,       SHOW_MY_BOOL},
928 929 930 931 932 933 934
#endif
#ifdef HAVE_NDBCLUSTER_DB
  {sys_ndb_autoincrement_prefetch_sz.name,
   (char*) &sys_ndb_autoincrement_prefetch_sz,                      SHOW_SYS},
  {sys_ndb_force_send.name,   (char*) &sys_ndb_force_send,          SHOW_SYS},
  {sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count,   SHOW_SYS},
  {sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS},
unknown's avatar
unknown committed
935
  {sys_ndb_cache_check_time.name,(char*) &sys_ndb_cache_check_time, SHOW_SYS},
unknown's avatar
unknown committed
936 937 938
#endif
  {sys_net_buffer_length.name,(char*) &sys_net_buffer_length,       SHOW_SYS},
  {sys_net_read_timeout.name, (char*) &sys_net_read_timeout,        SHOW_SYS},
939
  {sys_net_retry_count.name,  (char*) &sys_net_retry_count,	    SHOW_SYS},
unknown's avatar
unknown committed
940
  {sys_net_write_timeout.name,(char*) &sys_net_write_timeout,       SHOW_SYS},
941
  {sys_new_mode.name,         (char*) &sys_new_mode,                SHOW_SYS},
942
  {sys_old_passwords.name,    (char*) &sys_old_passwords,           SHOW_SYS},
unknown's avatar
unknown committed
943
  {"open_files_limit",	      (char*) &open_files_limit,	    SHOW_LONG},
944 945 946 947
  {sys_optimizer_prune_level.name, (char*) &sys_optimizer_prune_level,
   SHOW_SYS},
  {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
   SHOW_SYS},
unknown's avatar
unknown committed
948
  {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
949
  {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS},
950
  {"port",                    (char*) &mysqld_port,                  SHOW_INT},
unknown's avatar
unknown committed
951
  {sys_preload_buff_size.name, (char*) &sys_preload_buff_size,      SHOW_SYS},
952
  {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
953 954
  {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
   SHOW_SYS},
unknown's avatar
unknown committed
955
#ifdef HAVE_QUERY_CACHE
unknown's avatar
unknown committed
956
  {sys_query_cache_limit.name,(char*) &sys_query_cache_limit,	    SHOW_SYS},
957 958
  {sys_query_cache_min_res_unit.name, (char*) &sys_query_cache_min_res_unit,
   SHOW_SYS},
unknown's avatar
unknown committed
959 960
  {sys_query_cache_size.name, (char*) &sys_query_cache_size,	    SHOW_SYS},
  {sys_query_cache_type.name, (char*) &sys_query_cache_type,        SHOW_SYS},
unknown's avatar
unknown committed
961 962
  {sys_query_cache_wlock_invalidate.name,
   (char *) &sys_query_cache_wlock_invalidate, SHOW_SYS},
unknown's avatar
unknown committed
963
#endif /* HAVE_QUERY_CACHE */
964
  {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size,  SHOW_SYS},
965 966
  {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size,
   SHOW_SYS},
unknown's avatar
unknown committed
967 968 969
  {sys_read_buff_size.name,   (char*) &sys_read_buff_size,	    SHOW_SYS},
  {sys_readonly.name,         (char*) &sys_readonly,                SHOW_SYS},
  {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size,	    SHOW_SYS},
unknown's avatar
unknown committed
970 971
#ifdef HAVE_REPLICATION
  {sys_relay_log_purge.name,  (char*) &sys_relay_log_purge,         SHOW_SYS},
972
  {"relay_log_space_limit",  (char*) &relay_log_space_limit,        SHOW_LONGLONG},
unknown's avatar
unknown committed
973
#endif
unknown's avatar
unknown committed
974
  {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank,       SHOW_SYS},
975
  {"secure_auth",             (char*) &sys_secure_auth,             SHOW_SYS},
976 977 978 979
#ifdef HAVE_SMEM
  {"shared_memory",           (char*) &opt_enable_shared_memory,    SHOW_MY_BOOL},
  {"shared_memory_base_name", (char*) &shared_memory_base_name,     SHOW_CHAR_PTR},
#endif
unknown's avatar
unknown committed
980
  {sys_server_id.name,	      (char*) &sys_server_id,		    SHOW_SYS},
981
  {"skip_external_locking",   (char*) &my_disable_locking,          SHOW_MY_BOOL},
unknown's avatar
unknown committed
982 983
  {"skip_networking",         (char*) &opt_disable_networking,      SHOW_BOOL},
  {"skip_show_database",      (char*) &opt_skip_show_db,            SHOW_BOOL},
984
#ifdef HAVE_REPLICATION
985 986 987
  {sys_slave_compressed_protocol.name,
    (char*) &sys_slave_compressed_protocol,           SHOW_SYS},
  {"slave_load_tmpdir",       (char*) &slave_load_tmpdir,           SHOW_CHAR_PTR},
988
  {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout,	    SHOW_SYS},
989
  {"slave_skip_errors",       (char*) &slave_error_mask,            SHOW_SLAVE_SKIP_ERRORS},
990
  {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries,   SHOW_SYS},
991
#endif
unknown's avatar
unknown committed
992
  {sys_slow_launch_time.name, (char*) &sys_slow_launch_time,        SHOW_SYS},
993
#ifdef HAVE_SYS_UN_H
994
  {"socket",                  (char*) &mysqld_unix_port,             SHOW_CHAR_PTR},
995
#endif
unknown's avatar
unknown committed
996
  {sys_sort_buffer.name,      (char*) &sys_sort_buffer, 	    SHOW_SYS},
997
  {sys_sql_mode.name,         (char*) &sys_sql_mode,                SHOW_SYS},
998 999
  {"sql_notes",               (char*) &sys_sql_notes,               SHOW_BOOL},
  {"sql_warnings",            (char*) &sys_sql_warnings,            SHOW_BOOL},
unknown's avatar
unknown committed
1000
  {sys_storage_engine.name,   (char*) &sys_storage_engine,          SHOW_SYS},
1001 1002 1003
#ifdef HAVE_REPLICATION
  {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period,     SHOW_SYS},
#endif
unknown's avatar
unknown committed
1004
  {sys_sync_frm.name,         (char*) &sys_sync_frm,               SHOW_SYS},
1005 1006 1007
#ifdef HAVE_TZNAME
  {"system_time_zone",        system_time_zone,                     SHOW_CHAR},
#endif
unknown's avatar
unknown committed
1008
  {"table_cache",             (char*) &table_cache_size,            SHOW_LONG},
1009
  {"table_lock_wait_timeout", (char*) &table_lock_wait_timeout,     SHOW_LONG },
unknown's avatar
unknown committed
1010 1011 1012 1013 1014 1015
  {sys_table_type.name,	      (char*) &sys_table_type,	            SHOW_SYS},
  {sys_thread_cache_size.name,(char*) &sys_thread_cache_size,       SHOW_SYS},
#ifdef HAVE_THR_SETCONCURRENCY
  {"thread_concurrency",      (char*) &concurrency,                 SHOW_LONG},
#endif
  {"thread_stack",            (char*) &thread_stack,                SHOW_LONG},
1016
  {sys_time_format.name,      (char*) &sys_time_format,		    SHOW_SYS},
1017
  {"time_zone",               (char*) &sys_time_zone,               SHOW_SYS},
unknown's avatar
unknown committed
1018
  {sys_timed_mutexes.name,    (char*) &sys_timed_mutexes,       SHOW_SYS},
unknown's avatar
unknown committed
1019
  {sys_tmp_table_size.name,   (char*) &sys_tmp_table_size,	    SHOW_SYS},
unknown's avatar
unknown committed
1020
  {"tmpdir",                  (char*) &opt_mysql_tmpdir,            SHOW_CHAR_PTR},
1021 1022 1023
  {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size,
   SHOW_SYS},
  {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size,  SHOW_SYS},
1024
  {sys_tx_isolation.name,     (char*) &sys_tx_isolation,	    SHOW_SYS},
1025 1026
  {sys_updatable_views_with_limit.name,
                              (char*) &sys_updatable_views_with_limit,SHOW_SYS},
unknown's avatar
unknown committed
1027
  {"version",                 server_version,                       SHOW_CHAR},
1028 1029 1030
#ifdef HAVE_BERKELEY_DB
  {"version_bdb",             (char*) DB_VERSION_STRING,            SHOW_CHAR},
#endif
1031
  {"version_comment",         (char*) MYSQL_COMPILATION_COMMENT,    SHOW_CHAR},
1032
  {"version_compile_machine", (char*) MACHINE_TYPE,		    SHOW_CHAR},
1033
  {sys_os.name,		      (char*) &sys_os,			    SHOW_SYS},
unknown's avatar
unknown committed
1034 1035 1036 1037
  {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout,	    SHOW_SYS},
  {NullS, NullS, SHOW_LONG}
};

1038

1039 1040 1041 1042 1043 1044
bool sys_var::check(THD *thd, set_var *var)
{
  var->save_result.ulonglong_value= var->value->val_int();
  return 0;
}

1045 1046 1047 1048 1049 1050 1051
bool sys_var_str::check(THD *thd, set_var *var)
{
  int res;
  if (!check_func)
    return 0;

  if ((res=(*check_func)(thd, var)) < 0)
1052 1053
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
             name, var->value->str_value.ptr());
1054 1055 1056
  return res;
}

unknown's avatar
unknown committed
1057 1058 1059 1060
/*
  Functions to check and update variables
*/

unknown's avatar
unknown committed
1061

1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
/*
  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)
unknown's avatar
unknown committed
1072
{
1073 1074 1075 1076
  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*) "";
1077
  if (!(res= my_strdup_with_length((byte*)old_value, new_length, MYF(0))))
1078
    return 1;
unknown's avatar
unknown committed
1079 1080 1081 1082
  /*
    Replace the old value in such a way that the any thread using
    the value will work.
  */
1083 1084 1085 1086 1087
  rw_wrlock(var_mutex);
  old_value= var_str->value;
  var_str->value= res;
  var_str->value_length= new_length;
  rw_unlock(var_mutex);
unknown's avatar
unknown committed
1088 1089 1090 1091 1092
  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
  return 0;
}


1093 1094 1095 1096 1097 1098
static bool sys_update_init_connect(THD *thd, set_var *var)
{
  return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
}


unknown's avatar
unknown committed
1099 1100
static void sys_default_init_connect(THD* thd, enum_var_type type)
{
1101
  update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
unknown's avatar
unknown committed
1102 1103 1104 1105 1106
}


static bool sys_update_init_slave(THD *thd, set_var *var)
{
1107
  return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
unknown's avatar
unknown committed
1108 1109 1110 1111 1112
}


static void sys_default_init_slave(THD* thd, enum_var_type type)
{
1113
  update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
unknown's avatar
unknown committed
1114 1115
}

1116 1117
static int sys_check_ftb_syntax(THD *thd,  set_var *var)
{
1118 1119 1120 1121
  if (thd->security_ctx->master_access & SUPER_ACL)
    return (ft_boolean_check_syntax_string((byte*)
                                           var->value->str_value.c_ptr()) ?
            -1 : 0);
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
  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);
  return 0;
}

static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
{
1138
  strmake(ft_boolean_syntax, def_ft_boolean_syntax,
1139 1140
	  sizeof(ft_boolean_syntax)-1);
}
unknown's avatar
unknown committed
1141

unknown's avatar
unknown committed
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155

/*
  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)
    thd->update_lock_default= (thd->variables.low_priority_updates ?
			       TL_WRITE_LOW_PRIORITY : TL_WRITE);
}


1156 1157 1158 1159 1160 1161 1162
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;
}

unknown's avatar
unknown committed
1163 1164 1165 1166 1167 1168 1169 1170
/*
  Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR
*/

static void fix_max_join_size(THD *thd, enum_var_type type)
{
  if (type != OPT_GLOBAL)
  {
1171
    if (thd->variables.max_join_size == HA_POS_ERROR)
unknown's avatar
unknown committed
1172 1173 1174 1175 1176
      thd->options|= OPTION_BIG_SELECTS;
    else
      thd->options&= ~OPTION_BIG_SELECTS;
  }
}
1177

unknown's avatar
unknown committed
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190

/*
  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)
{
  if (type == OPT_SESSION)
    thd->session_tx_isolation= ((enum_tx_isolation)
				thd->variables.tx_isolation);
}

unknown's avatar
foo1  
unknown committed
1191
static void fix_completion_type(THD *thd __attribute__(unused),
unknown's avatar
unknown committed
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
				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;
}

unknown's avatar
unknown committed
1206 1207 1208 1209 1210

/*
  If we are changing the thread variable, we have to copy it to NET too
*/

unknown's avatar
SCRUM  
unknown committed
1211
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
static void fix_net_read_timeout(THD *thd, enum_var_type type)
{
  if (type != OPT_GLOBAL)
    thd->net.read_timeout=thd->variables.net_read_timeout;
}


static void fix_net_write_timeout(THD *thd, enum_var_type type)
{
  if (type != OPT_GLOBAL)
    thd->net.write_timeout=thd->variables.net_write_timeout;
}

1225 1226 1227 1228 1229
static void fix_net_retry_count(THD *thd, enum_var_type type)
{
  if (type != OPT_GLOBAL)
    thd->net.retry_count=thd->variables.net_retry_count;
}
unknown's avatar
SCRUM  
unknown committed
1230 1231 1232
#else /* HAVE_REPLICATION */
static void fix_net_read_timeout(THD *thd __attribute__(unused),
				 enum_var_type type __attribute__(unused))
1233
{}
unknown's avatar
SCRUM  
unknown committed
1234 1235
static void fix_net_write_timeout(THD *thd __attribute__(unused),
				  enum_var_type type __attribute__(unused))
1236
{}
unknown's avatar
SCRUM  
unknown committed
1237 1238
static void fix_net_retry_count(THD *thd __attribute__(unused),
				enum_var_type type __attribute__(unused))
1239
{}
unknown's avatar
SCRUM  
unknown committed
1240
#endif /* HAVE_REPLICATION */
1241

unknown's avatar
unknown committed
1242 1243 1244 1245

static void fix_query_cache_size(THD *thd, enum_var_type type)
{
#ifdef HAVE_QUERY_CACHE
1246
  ulong requested= query_cache_size;
unknown's avatar
unknown committed
1247
  query_cache.resize(query_cache_size);
1248 1249 1250 1251
  if (requested != query_cache_size)
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
			ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
			requested, query_cache_size);
unknown's avatar
unknown committed
1252 1253 1254 1255
#endif
}


1256 1257 1258
#ifdef HAVE_QUERY_CACHE
static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
{
unknown's avatar
foo1  
unknown committed
1259
  query_cache_min_res_unit=
1260 1261 1262 1263 1264
    query_cache.set_min_res_unit(query_cache_min_res_unit);
}
#endif


1265
extern void fix_delay_key_write(THD *thd, enum_var_type type)
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
{
  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;
  }
}

1281
static void fix_max_binlog_size(THD *thd, enum_var_type type)
1282 1283 1284 1285 1286
{
  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);
1287
#ifdef HAVE_REPLICATION
1288 1289
  if (!max_relay_log_size)
    active_mi->rli.relay_log.set_max_size(max_binlog_size);
unknown's avatar
unknown committed
1290
#endif
1291 1292 1293
  DBUG_VOID_RETURN;
}

1294
static void fix_max_relay_log_size(THD *thd, enum_var_type type)
1295 1296 1297 1298
{
  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));
1299
#ifdef HAVE_REPLICATION
1300 1301
  active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
                                        max_relay_log_size: max_binlog_size);
1302
#endif
1303 1304
  DBUG_VOID_RETURN;
}
1305

1306

1307 1308
static int check_max_delayed_threads(THD *thd, set_var *var)
{
unknown's avatar
unknown committed
1309
  longlong val= var->value->val_int();
1310
  if (var->type != OPT_GLOBAL && val != 0 &&
unknown's avatar
unknown committed
1311
      val != (longlong) global_system_variables.max_insert_delayed_threads)
1312 1313
  {
    char buf[64];
1314
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
1315 1316 1317 1318 1319
    return 1;
  }
  return 0;
}

1320
static void fix_max_connections(THD *thd, enum_var_type type)
1321
{
1322
#ifndef EMBEDDED_LIBRARY
unknown's avatar
foo1  
unknown committed
1323
  resize_thr_alarm(max_connections +
1324
		   global_system_variables.max_insert_delayed_threads + 10);
1325
#endif
1326 1327 1328 1329 1330 1331
}


static void fix_thd_mem_root(THD *thd, enum_var_type type)
{
  if (type != OPT_GLOBAL)
unknown's avatar
unknown committed
1332
    reset_root_defaults(thd->mem_root,
1333 1334 1335 1336 1337 1338 1339
                        thd->variables.query_alloc_block_size,
                        thd->variables.query_prealloc_size);
}


static void fix_trans_mem_root(THD *thd, enum_var_type type)
{
1340
#ifdef USING_TRANSACTIONS
1341 1342 1343 1344
  if (type != OPT_GLOBAL)
    reset_root_defaults(&thd->transaction.mem_root,
                        thd->variables.trans_alloc_block_size,
                        thd->variables.trans_prealloc_size);
1345
#endif
1346 1347
}

1348

1349 1350 1351 1352
static void fix_server_id(THD *thd, enum_var_type type)
{
  server_id_supplied = 1;
}
1353

1354 1355 1356 1357 1358 1359 1360 1361 1362 1363

sys_var_long_ptr::
sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
                 sys_after_update_func after_update_arg)
  :sys_var_long_ptr_global(name_arg, value_ptr,
                           &LOCK_global_system_variables, after_update_arg)
{}


bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
unknown's avatar
unknown committed
1364 1365 1366 1367 1368
{
  longlong v= var->value->val_int();
  var->save_result.ulonglong_value= v < 0 ? 0 : v;
  return 0;
}
1369

1370
bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
unknown's avatar
unknown committed
1371
{
1372
  ulonglong tmp= var->save_result.ulonglong_value;
1373
  pthread_mutex_lock(guard);
unknown's avatar
unknown committed
1374 1375 1376 1377
  if (option_limits)
    *value= (ulong) getopt_ull_limit_value(tmp, option_limits);
  else
    *value= (ulong) tmp;
1378
  pthread_mutex_unlock(guard);
unknown's avatar
unknown committed
1379 1380 1381 1382
  return 0;
}


1383
void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
unknown's avatar
unknown committed
1384
{
1385
  pthread_mutex_lock(guard);
unknown's avatar
unknown committed
1386
  *value= (ulong) option_limits->def_value;
1387
  pthread_mutex_unlock(guard);
unknown's avatar
unknown committed
1388 1389 1390
}


1391 1392
bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
{
1393
  ulonglong tmp= var->save_result.ulonglong_value;
1394
  pthread_mutex_lock(&LOCK_global_system_variables);
1395 1396 1397 1398
  if (option_limits)
    *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
  else
    *value= (ulonglong) tmp;
1399
  pthread_mutex_unlock(&LOCK_global_system_variables);
1400 1401 1402 1403 1404 1405
  return 0;
}


void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
{
1406
  pthread_mutex_lock(&LOCK_global_system_variables);
1407
  *value= (ulonglong) option_limits->def_value;
1408
  pthread_mutex_unlock(&LOCK_global_system_variables);
1409 1410 1411
}


unknown's avatar
unknown committed
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424
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;
}


1425 1426 1427 1428 1429 1430 1431
bool sys_var_enum::update(THD *thd, set_var *var)
{
  *value= (uint) var->save_result.ulong_value;
  return 0;
}


1432
byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
1433 1434 1435 1436
{
  return (byte*) enum_names->type_names[*value];
}

1437 1438 1439 1440 1441
bool sys_var_thd_ulong::check(THD *thd, set_var *var)
{
  return (sys_var_thd::check(thd, var) ||
          (check_func && (*check_func)(thd, var)));
}
1442

unknown's avatar
unknown committed
1443 1444
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
{
1445
  ulonglong tmp= var->save_result.ulonglong_value;
unknown's avatar
unknown committed
1446 1447 1448 1449 1450

  /* Don't use bigger value than given with --maximum-variable-name=.. */
  if ((ulong) tmp > max_system_variables.*offset)
    tmp= max_system_variables.*offset;

1451 1452 1453 1454 1455 1456
#if SIZEOF_LONG == 4
  /* Avoid overflows on 32 bit systems */
  if (tmp > (ulonglong) ~(ulong) 0)
    tmp= ((ulonglong) ~(ulong) 0);
#endif

unknown's avatar
unknown committed
1457 1458 1459
  if (option_limits)
    tmp= (ulong) getopt_ull_limit_value(tmp, option_limits);
  if (var->type == OPT_GLOBAL)
1460
    global_system_variables.*offset= (ulong) tmp;
unknown's avatar
unknown committed
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
  else
    thd->variables.*offset= (ulong) tmp;
  return 0;
}


void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
{
  if (type == OPT_GLOBAL)
  {
    /* We will not come here if option_limits is not set */
    global_system_variables.*offset= (ulong) option_limits->def_value;
  }
  else
    thd->variables.*offset= global_system_variables.*offset;
}


1479 1480
byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
				   LEX_STRING *base)
unknown's avatar
unknown committed
1481 1482 1483 1484 1485 1486 1487
{
  if (type == OPT_GLOBAL)
    return (byte*) &(global_system_variables.*offset);
  return (byte*) &(thd->variables.*offset);
}


1488 1489
bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
{
1490
  ulonglong tmp= var->save_result.ulonglong_value;
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500

  /* Don't use bigger value than given with --maximum-variable-name=.. */
  if ((ha_rows) tmp > max_system_variables.*offset)
    tmp= max_system_variables.*offset;

  if (option_limits)
    tmp= (ha_rows) getopt_ull_limit_value(tmp, option_limits);
  if (var->type == OPT_GLOBAL)
  {
    /* Lock is needed to make things safe on 32 bit systems */
unknown's avatar
foo1  
unknown committed
1501
    pthread_mutex_lock(&LOCK_global_system_variables);
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
    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)
  {
    /* We will not come here if option_limits is not set */
    pthread_mutex_lock(&LOCK_global_system_variables);
    global_system_variables.*offset= (ha_rows) option_limits->def_value;
    pthread_mutex_unlock(&LOCK_global_system_variables);
  }
  else
    thd->variables.*offset= global_system_variables.*offset;
}


1525 1526
byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
				     LEX_STRING *base)
1527 1528 1529 1530 1531 1532
{
  if (type == OPT_GLOBAL)
    return (byte*) &(global_system_variables.*offset);
  return (byte*) &(thd->variables.*offset);
}

unknown's avatar
unknown committed
1533 1534
bool sys_var_thd_ulonglong::update(THD *thd,  set_var *var)
{
1535
  ulonglong tmp= var->save_result.ulonglong_value;
1536

1537
  if (tmp > max_system_variables.*offset)
1538 1539 1540
    tmp= max_system_variables.*offset;

  if (option_limits)
1541
    tmp= getopt_ull_limit_value(tmp, option_limits);
unknown's avatar
unknown committed
1542
  if (var->type == OPT_GLOBAL)
1543 1544 1545
  {
    /* Lock is needed to make things safe on 32 bit systems */
    pthread_mutex_lock(&LOCK_global_system_variables);
1546
    global_system_variables.*offset= (ulonglong) tmp;
1547 1548
    pthread_mutex_unlock(&LOCK_global_system_variables);
  }
unknown's avatar
unknown committed
1549
  else
1550
    thd->variables.*offset= (ulonglong) tmp;
unknown's avatar
unknown committed
1551 1552 1553 1554 1555 1556 1557
  return 0;
}


void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
{
  if (type == OPT_GLOBAL)
1558 1559
  {
    pthread_mutex_lock(&LOCK_global_system_variables);
1560
    global_system_variables.*offset= (ulonglong) option_limits->def_value;
1561 1562
    pthread_mutex_unlock(&LOCK_global_system_variables);
  }
unknown's avatar
unknown committed
1563 1564 1565 1566 1567
  else
    thd->variables.*offset= global_system_variables.*offset;
}


1568 1569
byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type,
				       LEX_STRING *base)
unknown's avatar
unknown committed
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
{
  if (type == OPT_GLOBAL)
    return (byte*) &(global_system_variables.*offset);
  return (byte*) &(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;
}


1596 1597
byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
				  LEX_STRING *base)
unknown's avatar
unknown committed
1598 1599 1600 1601 1602 1603 1604 1605 1606
{
  if (type == OPT_GLOBAL)
    return (byte*) &(global_system_variables.*offset);
  return (byte*) &(thd->variables.*offset);
}


bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
{
unknown's avatar
unknown committed
1607
  char buff[STRING_BUFFER_USUAL_SIZE];
1608
  const char *value;
1609
  String str(buff, sizeof(buff), system_charset_info), *res;
unknown's avatar
unknown committed
1610 1611 1612 1613 1614

  if (var->value->result_type() == STRING_RESULT)
  {
    if (!(res=var->value->val_str(&str)) ||
	((long) (var->save_result.ulong_value=
1615 1616
		 (ulong) find_type(enum_names, res->ptr(),
				   res->length(),1)-1)) < 0)
unknown's avatar
unknown committed
1617
    {
1618
      value= res ? res->c_ptr() : "NULL";
unknown's avatar
unknown committed
1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
      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:
1636
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
unknown's avatar
unknown committed
1637 1638 1639
  return 1;
}

1640 1641 1642

bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
{
1643
  bool not_used;
unknown's avatar
unknown committed
1644
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1645 1646 1647 1648 1649 1650
  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)))
1651
    {
unknown's avatar
unknown committed
1652
      strmov(buff, "NULL");
1653
      goto err;
1654
    }
unknown's avatar
unknown committed
1655 1656
    var->save_result.ulong_value= ((ulong)
				   find_set(enum_names, res->c_ptr(),
1657 1658 1659
					    res->length(),
                                            NULL,
                                            &error, &error_len,
unknown's avatar
unknown committed
1660
					    &not_used));
1661 1662 1663 1664 1665 1666 1667 1668 1669
    if (error_len)
    {
      strmake(buff, error, min(sizeof(buff), error_len));
      goto err;
    }
  }
  else
  {
    ulonglong tmp= var->value->val_int();
1670 1671 1672 1673 1674 1675
   /*
     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)))
1676 1677 1678 1679 1680 1681 1682 1683 1684
    {
      llstr(tmp, buff);
      goto err;
    }
    var->save_result.ulong_value= (ulong) tmp;  // Save for update
  }
  return 0;

err:
1685
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
1686 1687 1688 1689
  return 1;
}


unknown's avatar
unknown committed
1690 1691 1692 1693 1694
/*
  Return an Item for a variable.  Used with @@[global.]variable_name
  If type is not given, return local value if exists, else global
*/

1695
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
unknown's avatar
unknown committed
1696 1697 1698 1699 1700
{
  if (check_type(var_type))
  {
    if (var_type != OPT_DEFAULT)
    {
1701 1702
      my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
               name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
unknown's avatar
unknown committed
1703 1704 1705 1706 1707 1708
      return 0;
    }
    /* As there was no local variable, return the global value */
    var_type= OPT_GLOBAL;
  }
  switch (type()) {
1709 1710 1711 1712 1713 1714
  case SHOW_INT:
  {
    uint value;
    pthread_mutex_lock(&LOCK_global_system_variables);
    value= *(uint*) value_ptr(thd, var_type, base);
    pthread_mutex_unlock(&LOCK_global_system_variables);
1715
    return new Item_uint((ulonglong) value);
1716
  }
unknown's avatar
unknown committed
1717
  case SHOW_LONG:
1718 1719 1720 1721 1722
  {
    ulong value;
    pthread_mutex_lock(&LOCK_global_system_variables);
    value= *(ulong*) value_ptr(thd, var_type, base);
    pthread_mutex_unlock(&LOCK_global_system_variables);
1723
    return new Item_uint((ulonglong) value);
1724
  }
unknown's avatar
unknown committed
1725
  case SHOW_LONGLONG:
1726 1727 1728
  {
    longlong value;
    pthread_mutex_lock(&LOCK_global_system_variables);
unknown's avatar
unknown committed
1729
    value= *(longlong*) value_ptr(thd, var_type, base);
1730 1731 1732
    pthread_mutex_unlock(&LOCK_global_system_variables);
    return new Item_int(value);
  }
1733
  case SHOW_HA_ROWS:
1734 1735 1736
  {
    ha_rows value;
    pthread_mutex_lock(&LOCK_global_system_variables);
unknown's avatar
unknown committed
1737
    value= *(ha_rows*) value_ptr(thd, var_type, base);
1738 1739 1740
    pthread_mutex_unlock(&LOCK_global_system_variables);
    return new Item_int((longlong) value);
  }
unknown's avatar
unknown committed
1741
  case SHOW_MY_BOOL:
1742
    return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type, base),1);
unknown's avatar
unknown committed
1743 1744
  case SHOW_CHAR:
  {
unknown's avatar
unknown committed
1745
    Item *tmp;
1746
    pthread_mutex_lock(&LOCK_global_system_variables);
1747
    char *str= (char*) value_ptr(thd, var_type, base);
unknown's avatar
unknown committed
1748 1749 1750 1751 1752 1753 1754 1755
    if (str)
      tmp= new Item_string(str, strlen(str),
                           system_charset_info, DERIVATION_SYSCONST);
    else
    {
      tmp= new Item_null();
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
    }
1756 1757
    pthread_mutex_unlock(&LOCK_global_system_variables);
    return tmp;
unknown's avatar
unknown committed
1758 1759
  }
  default:
1760
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
unknown's avatar
unknown committed
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784
  }
  return 0;
}


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;
}


1785 1786
byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
				  LEX_STRING *base)
unknown's avatar
unknown committed
1787 1788 1789 1790 1791 1792 1793
{
  ulong tmp= ((type == OPT_GLOBAL) ?
	      global_system_variables.*offset :
	      thd->variables.*offset);
  return (byte*) enum_names->type_names[tmp];
}

1794 1795 1796 1797 1798
bool sys_var_thd_bit::check(THD *thd, set_var *var)
{
  return (check_enum(thd, var, &bool_typelib) ||
          (check_func && (*check_func)(thd, var)));
}
unknown's avatar
unknown committed
1799 1800 1801

bool sys_var_thd_bit::update(THD *thd, set_var *var)
{
1802
  int res= (*update_func)(thd, var);
unknown's avatar
unknown committed
1803 1804 1805 1806
  return res;
}


1807 1808
byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
				 LEX_STRING *base)
unknown's avatar
unknown committed
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
{
  /*
    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 (byte*) &thd->sys_var_tmp.my_bool_value;
}


1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861
/* 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",(char*) 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)
{
unknown's avatar
unknown committed
1862
  char buff[STRING_BUFFER_USUAL_SIZE];
1863 1864 1865 1866 1867 1868 1869 1870 1871
  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())))
  {
1872
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
1873 1874
    return 1;
  }
unknown's avatar
foo1  
unknown committed
1875

1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925
  /*
    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);
}


byte *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 (byte*) res;
  }
  return (byte*) (thd->variables.*offset)->format.str;
}


1926 1927
typedef struct old_names_map_st
{
unknown's avatar
unknown committed
1928 1929 1930
  const char *old_name;
  const char *new_name;
} my_old_conv;
unknown's avatar
unknown committed
1931

unknown's avatar
foo1  
unknown committed
1932
static my_old_conv old_conv[]=
unknown's avatar
unknown committed
1933
{
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944
  {	"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		}
unknown's avatar
unknown committed
1945
};
unknown's avatar
unknown committed
1946

unknown's avatar
unknown committed
1947
CHARSET_INFO *get_old_charset_by_name(const char *name)
unknown's avatar
unknown committed
1948
{
unknown's avatar
unknown committed
1949
  my_old_conv *conv;
unknown's avatar
foo1  
unknown committed
1950

unknown's avatar
unknown committed
1951
  for (conv= old_conv; conv->old_name; conv++)
1952
  {
unknown's avatar
unknown committed
1953 1954
    if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
      return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0));
1955
  }
unknown's avatar
unknown committed
1956
  return NULL;
unknown's avatar
unknown committed
1957 1958
}

unknown's avatar
unknown committed
1959

1960
bool sys_var_collation::check(THD *thd, set_var *var)
unknown's avatar
unknown committed
1961 1962 1963
{
  CHARSET_INFO *tmp;

1964
  if (var->value->result_type() == STRING_RESULT)
1965
  {
unknown's avatar
unknown committed
1966
    char buff[STRING_BUFFER_USUAL_SIZE];
1967 1968 1969
    String str(buff,sizeof(buff), system_charset_info), *res;
    if (!(res=var->value->val_str(&str)))
    {
1970
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1971 1972 1973 1974
      return 1;
    }
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
    {
1975
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1976 1977
      return 1;
    }
1978
  }
1979
  else // INT_RESULT
1980
  {
1981
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1982 1983
    {
      char buf[20];
1984
      int10_to_str((int) var->value->val_int(), buf, -10);
1985
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1986 1987
      return 1;
    }
1988 1989 1990 1991 1992
  }
  var->save_result.charset= tmp;	// Save for update
  return 0;
}

1993

1994 1995 1996 1997
bool sys_var_character_set::check(THD *thd, set_var *var)
{
  CHARSET_INFO *tmp;

1998 1999
  if (var->value->result_type() == STRING_RESULT)
  {
unknown's avatar
unknown committed
2000
    char buff[STRING_BUFFER_USUAL_SIZE];
2001 2002
    String str(buff,sizeof(buff), system_charset_info), *res;
    if (!(res=var->value->val_str(&str)))
2003
    {
2004 2005
      if (!nullable)
      {
2006
        my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
2007 2008 2009 2010 2011 2012 2013
        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())))
    {
2014
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
2015 2016 2017
      return 1;
    }
  }
2018
  else // INT_RESULT
unknown's avatar
unknown committed
2019
  {
2020
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
2021 2022
    {
      char buf[20];
2023
      int10_to_str((int) var->value->val_int(), buf, -10);
2024 2025 2026
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
      return 1;
    }
unknown's avatar
unknown committed
2027 2028 2029 2030 2031
  }
  var->save_result.charset= tmp;	// Save for update
  return 0;
}

2032

2033
bool sys_var_character_set::update(THD *thd, set_var *var)
unknown's avatar
unknown committed
2034
{
2035
  ci_ptr(thd,var->type)[0]= var->save_result.charset;
unknown's avatar
unknown committed
2036
  thd->update_charset();
unknown's avatar
unknown committed
2037 2038 2039
  return 0;
}

2040 2041 2042

byte *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
				       LEX_STRING *base)
unknown's avatar
unknown committed
2043
{
2044
  CHARSET_INFO *cs= ci_ptr(thd,type)[0];
unknown's avatar
unknown committed
2045
  return cs ? (byte*) cs->csname : (byte*) NULL;
unknown's avatar
unknown committed
2046 2047
}

2048

2049 2050
CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd,
							 enum_var_type type)
unknown's avatar
unknown committed
2051 2052 2053 2054 2055 2056 2057
{
  if (type == OPT_GLOBAL)
    return &global_system_variables.collation_connection;
  else
    return &thd->variables.collation_connection;
}

2058 2059 2060

void sys_var_character_set_connection::set_default(THD *thd,
						   enum_var_type type)
unknown's avatar
unknown committed
2061 2062 2063 2064
{
 if (type == OPT_GLOBAL)
   global_system_variables.collation_connection= default_charset_info;
 else
unknown's avatar
unknown committed
2065
 {
unknown's avatar
unknown committed
2066
   thd->variables.collation_connection= global_system_variables.collation_connection;
unknown's avatar
unknown committed
2067 2068
   thd->update_charset();
 }
unknown's avatar
unknown committed
2069 2070
}

2071

2072 2073
CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd,
						     enum_var_type type)
2074 2075 2076 2077 2078 2079 2080
{
  if (type == OPT_GLOBAL)
    return &global_system_variables.character_set_client;
  else
    return &thd->variables.character_set_client;
}

2081

2082
void sys_var_character_set_client::set_default(THD *thd, enum_var_type type)
2083 2084
{
 if (type == OPT_GLOBAL)
2085
   global_system_variables.character_set_client= default_charset_info;
2086
 else
unknown's avatar
unknown committed
2087 2088 2089 2090 2091
 {
   thd->variables.character_set_client= (global_system_variables.
					 character_set_client);
   thd->update_charset();
 }
2092
}
unknown's avatar
unknown committed
2093

2094

unknown's avatar
unknown committed
2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120
CHARSET_INFO **
sys_var_character_set_filesystem::ci_ptr(THD *thd, enum_var_type type)
{
  if (type == OPT_GLOBAL)
    return &global_system_variables.character_set_filesystem;
  else
    return &thd->variables.character_set_filesystem;
}


extern CHARSET_INFO *character_set_filesystem;

void
sys_var_character_set_filesystem::set_default(THD *thd, enum_var_type type)
{
 if (type == OPT_GLOBAL)
   global_system_variables.character_set_filesystem= character_set_filesystem;
 else
 {
   thd->variables.character_set_filesystem= (global_system_variables.
					     character_set_filesystem);
   thd->update_charset();
 }
}


unknown's avatar
unknown committed
2121 2122
CHARSET_INFO **
sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type)
2123
{
2124 2125
  if (type == OPT_GLOBAL)
    return &global_system_variables.character_set_results;
2126
  else
2127
    return &thd->variables.character_set_results;
2128 2129
}

2130

2131
void sys_var_character_set_results::set_default(THD *thd, enum_var_type type)
2132
{
2133
 if (type == OPT_GLOBAL)
2134
   global_system_variables.character_set_results= default_charset_info;
2135
 else
unknown's avatar
unknown committed
2136 2137 2138 2139 2140
 {
   thd->variables.character_set_results= (global_system_variables.
					  character_set_results);
   thd->update_charset();
 }
2141 2142
}

2143

unknown's avatar
unknown committed
2144 2145
CHARSET_INFO **
sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type)
2146 2147
{
  if (type == OPT_GLOBAL)
2148
    return &global_system_variables.collation_server;
2149
  else
2150
    return &thd->variables.collation_server;
2151 2152
}

2153

2154
void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
2155 2156
{
 if (type == OPT_GLOBAL)
2157
   global_system_variables.collation_server= default_charset_info;
2158
 else
unknown's avatar
unknown committed
2159
 {
2160
   thd->variables.collation_server= global_system_variables.collation_server;
unknown's avatar
unknown committed
2161 2162
   thd->update_charset();
 }
2163 2164
}

2165 2166
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
						       enum_var_type type)
2167 2168
{
  if (type == OPT_GLOBAL)
2169
    return &global_system_variables.collation_database;
2170
  else
2171
    return &thd->variables.collation_database;
2172 2173
}

2174

2175 2176 2177
void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
{
 if (type == OPT_GLOBAL)
2178
    global_system_variables.collation_database= default_charset_info;
2179
  else
unknown's avatar
unknown committed
2180
  {
2181
    thd->variables.collation_database= thd->db_charset;
unknown's avatar
unknown committed
2182 2183
    thd->update_charset();
  }
2184 2185
}

2186

2187
bool sys_var_collation_connection::update(THD *thd, set_var *var)
2188 2189
{
  if (var->type == OPT_GLOBAL)
2190
    global_system_variables.collation_connection= var->save_result.charset;
2191
  else
unknown's avatar
unknown committed
2192
  {
2193
    thd->variables.collation_connection= var->save_result.charset;
unknown's avatar
unknown committed
2194 2195
    thd->update_charset();
  }
2196 2197 2198
  return 0;
}

2199 2200 2201

byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type,
					      LEX_STRING *base)
2202 2203
{
  CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
2204 2205 2206
		  global_system_variables.collation_connection :
		  thd->variables.collation_connection);
  return cs ? (byte*) cs->name : (byte*) "NULL";
2207 2208
}

2209

2210
void sys_var_collation_connection::set_default(THD *thd, enum_var_type type)
2211 2212
{
 if (type == OPT_GLOBAL)
2213
   global_system_variables.collation_connection= default_charset_info;
2214
 else
unknown's avatar
unknown committed
2215 2216 2217 2218 2219
 {
   thd->variables.collation_connection= (global_system_variables.
					 collation_connection);
   thd->update_charset();
 }
2220 2221
}

2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
bool sys_var_collation_database::update(THD *thd, set_var *var)
{
  if (var->type == OPT_GLOBAL)
    global_system_variables.collation_database= var->save_result.charset;
  else
  {
    thd->variables.collation_database= var->save_result.charset;
    thd->update_charset();
  }
  return 0;
}


byte *sys_var_collation_database::value_ptr(THD *thd, enum_var_type type,
					      LEX_STRING *base)
{
  CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
		  global_system_variables.collation_database :
		  thd->variables.collation_database);
  return cs ? (byte*) cs->name : (byte*) "NULL";
}


void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
{
 if (type == OPT_GLOBAL)
   global_system_variables.collation_database= default_charset_info;
 else
 {
   thd->variables.collation_database= (global_system_variables.
					 collation_database);
   thd->update_charset();
 }
}


bool sys_var_collation_server::update(THD *thd, set_var *var)
{
  if (var->type == OPT_GLOBAL)
    global_system_variables.collation_server= var->save_result.charset;
  else
  {
    thd->variables.collation_server= var->save_result.charset;
    thd->update_charset();
  }
  return 0;
}


byte *sys_var_collation_server::value_ptr(THD *thd, enum_var_type type,
					      LEX_STRING *base)
{
  CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
		  global_system_variables.collation_server :
		  thd->variables.collation_server);
  return cs ? (byte*) cs->name : (byte*) "NULL";
}


void sys_var_collation_server::set_default(THD *thd, enum_var_type type)
{
 if (type == OPT_GLOBAL)
   global_system_variables.collation_server= default_charset_info;
 else
 {
   thd->variables.collation_server= (global_system_variables.
					 collation_server);
   thd->update_charset();
 }
}

2293

2294
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
unknown's avatar
unknown committed
2295

unknown's avatar
unknown committed
2296
static KEY_CACHE zero_key_cache;
unknown's avatar
unknown committed
2297

unknown's avatar
unknown committed
2298
KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
unknown's avatar
unknown committed
2299
{
2300 2301
  safe_mutex_assert_owner(&LOCK_global_system_variables);
  if (!cache_name || ! cache_name->length)
unknown's avatar
unknown committed
2302
    cache_name= &default_key_cache_base;
unknown's avatar
unknown committed
2303
  return ((KEY_CACHE*) find_named(&key_caches,
2304
                                      cache_name->str, cache_name->length, 0));
unknown's avatar
unknown committed
2305 2306
}

2307

unknown's avatar
unknown committed
2308 2309
byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
					 LEX_STRING *base)
2310
{
unknown's avatar
unknown committed
2311
  KEY_CACHE *key_cache= get_key_cache(base);
unknown's avatar
unknown committed
2312 2313 2314 2315
  if (!key_cache)
    key_cache= &zero_key_cache;
  return (byte*) key_cache + offset ;
}
2316

2317

2318 2319
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
{
2320
  ulonglong tmp= var->save_result.ulonglong_value;
unknown's avatar
unknown committed
2321
  LEX_STRING *base_name= &var->base;
unknown's avatar
unknown committed
2322
  KEY_CACHE *key_cache;
2323 2324 2325
  bool error= 0;

  /* If no basename, assume it's for the key cache named 'default' */
unknown's avatar
unknown committed
2326
  if (!base_name->length)
2327
    base_name= &default_key_cache_base;
2328 2329 2330

  pthread_mutex_lock(&LOCK_global_system_variables);
  key_cache= get_key_cache(base_name);
unknown's avatar
foo1  
unknown committed
2331

2332 2333
  if (!key_cache)
  {
2334
    /* Key cache didn't exists */
2335
    if (!tmp)					// Tried to delete cache
2336 2337 2338 2339 2340 2341
      goto end;					// Ok, nothing to do
    if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
    {
      error= 1;
      goto end;
    }
2342
  }
2343 2344 2345 2346 2347 2348 2349 2350 2351

  /*
    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;

unknown's avatar
unknown committed
2352
  if (!tmp)					// Zero size means delete
2353
  {
unknown's avatar
unknown committed
2354
    if (key_cache == dflt_key_cache)
2355 2356 2357 2358
    {
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                          ER_WARN_CANT_DROP_DEFAULT_KEYCACHE,
                          ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE));
2359
      goto end;					// Ignore default key cache
2360
    }
2361

unknown's avatar
unknown committed
2362
    if (key_cache->key_cache_inited)		// If initied
2363 2364
    {
      /*
2365 2366
	Move tables using this key cache to the default key cache
	and clear the old key cache.
2367
      */
unknown's avatar
foo1  
unknown committed
2368
      NAMED_LIST *list;
unknown's avatar
unknown committed
2369
      key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
2370
					      base_name->length, &list);
2371 2372
      key_cache->in_init= 1;
      pthread_mutex_unlock(&LOCK_global_system_variables);
unknown's avatar
unknown committed
2373
      error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
2374 2375
      pthread_mutex_lock(&LOCK_global_system_variables);
      key_cache->in_init= 0;
2376
    }
2377 2378 2379 2380 2381
    /*
      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;
2382 2383
  }

unknown's avatar
unknown committed
2384 2385
  key_cache->param_buff_size=
    (ulonglong) getopt_ull_limit_value(tmp, option_limits);
2386

2387 2388 2389 2390
  /* If key cache didn't existed initialize it, else resize it */
  key_cache->in_init= 1;
  pthread_mutex_unlock(&LOCK_global_system_variables);

unknown's avatar
unknown committed
2391
  if (!key_cache->key_cache_inited)
2392
    error= (bool) (ha_init_key_cache("", key_cache));
unknown's avatar
unknown committed
2393
  else
2394
    error= (bool)(ha_resize_key_cache(key_cache));
2395

2396
  pthread_mutex_lock(&LOCK_global_system_variables);
unknown's avatar
foo1  
unknown committed
2397
  key_cache->in_init= 0;
2398

2399 2400 2401
end:
  pthread_mutex_unlock(&LOCK_global_system_variables);
  return error;
2402 2403
}

2404 2405

bool sys_var_key_cache_long::update(THD *thd, set_var *var)
2406
{
unknown's avatar
unknown committed
2407
  ulong tmp= (ulong) var->value->val_int();
2408
  LEX_STRING *base_name= &var->base;
2409 2410
  bool error= 0;

2411
  if (!base_name->length)
unknown's avatar
unknown committed
2412
    base_name= &default_key_cache_base;
2413 2414

  pthread_mutex_lock(&LOCK_global_system_variables);
unknown's avatar
unknown committed
2415
  KEY_CACHE *key_cache= get_key_cache(base_name);
2416

unknown's avatar
unknown committed
2417 2418
  if (!key_cache && !(key_cache= create_key_cache(base_name->str,
				                  base_name->length)))
2419 2420 2421 2422
  {
    error= 1;
    goto end;
  }
2423

2424 2425 2426 2427 2428 2429 2430 2431 2432
  /*
    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;

  *((ulong*) (((char*) key_cache) + offset))=
2433
    (ulong) getopt_ull_limit_value(tmp, option_limits);
unknown's avatar
unknown committed
2434

2435 2436 2437 2438 2439
  /*
    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;
2440

2441
  pthread_mutex_unlock(&LOCK_global_system_variables);
2442

2443 2444 2445
  error= (bool) (ha_resize_key_cache(key_cache));

  pthread_mutex_lock(&LOCK_global_system_variables);
unknown's avatar
foo1  
unknown committed
2446
  key_cache->in_init= 0;
2447 2448 2449 2450

end:
  pthread_mutex_unlock(&LOCK_global_system_variables);
  return error;
2451 2452
}

2453

2454 2455 2456 2457
/*****************************************************************************
  Functions to handle SET NAMES and SET CHARACTER SET
*****************************************************************************/

unknown's avatar
unknown committed
2458
int set_var_collation_client::check(THD *thd)
2459 2460 2461 2462
{
  return 0;
}

unknown's avatar
unknown committed
2463
int set_var_collation_client::update(THD *thd)
2464
{
2465 2466
  thd->variables.character_set_client= character_set_client;
  thd->variables.character_set_results= character_set_results;
unknown's avatar
unknown committed
2467
  thd->variables.collation_connection= collation_connection;
unknown's avatar
unknown committed
2468
  thd->update_charset();
2469 2470 2471 2472 2473 2474 2475
  thd->protocol_simple.init(thd);
  thd->protocol_prep.init(thd);
  return 0;
}

/****************************************************************************/

unknown's avatar
unknown committed
2476 2477
bool sys_var_timestamp::update(THD *thd,  set_var *var)
{
2478
  thd->set_time((time_t) var->save_result.ulonglong_value);
unknown's avatar
unknown committed
2479 2480 2481 2482 2483 2484 2485 2486 2487 2488
  return 0;
}


void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
{
  thd->user_time=0;
}


2489 2490
byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
				   LEX_STRING *base)
unknown's avatar
unknown committed
2491 2492 2493 2494 2495 2496 2497 2498
{
  thd->sys_var_tmp.long_value= (long) thd->start_time;
  return (byte*) &thd->sys_var_tmp.long_value;
}


bool sys_var_last_insert_id::update(THD *thd, set_var *var)
{
2499
  thd->insert_id(var->save_result.ulonglong_value);
unknown's avatar
unknown committed
2500 2501 2502 2503
  return 0;
}


2504 2505
byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
					LEX_STRING *base)
unknown's avatar
unknown committed
2506 2507 2508 2509 2510 2511 2512 2513
{
  thd->sys_var_tmp.long_value= (long) thd->insert_id();
  return (byte*) &thd->last_insert_id;
}


bool sys_var_insert_id::update(THD *thd, set_var *var)
{
2514
  thd->next_insert_id= var->save_result.ulonglong_value;
unknown's avatar
unknown committed
2515 2516 2517 2518
  return 0;
}


2519 2520
byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
				   LEX_STRING *base)
unknown's avatar
unknown committed
2521 2522 2523 2524 2525
{
  return (byte*) &thd->current_insert_id;
}


unknown's avatar
SCRUM  
unknown committed
2526
#ifdef HAVE_REPLICATION
unknown's avatar
unknown committed
2527 2528
bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
{
2529
  int result= 0;
2530
  pthread_mutex_lock(&LOCK_active_mi);
unknown's avatar
unknown committed
2531 2532 2533
  pthread_mutex_lock(&active_mi->rli.run_lock);
  if (active_mi->rli.slave_running)
  {
unknown's avatar
unknown committed
2534
    my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
unknown's avatar
unknown committed
2535 2536 2537
    result=1;
  }
  pthread_mutex_unlock(&active_mi->rli.run_lock);
2538
  pthread_mutex_unlock(&LOCK_active_mi);
2539
  var->save_result.ulong_value= (ulong) var->value->val_int();
unknown's avatar
unknown committed
2540 2541 2542 2543 2544 2545
  return result;
}


bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
{
2546
  pthread_mutex_lock(&LOCK_active_mi);
unknown's avatar
unknown committed
2547 2548 2549 2550 2551 2552 2553 2554 2555
  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);
2556
    active_mi->rli.slave_skip_counter= var->save_result.ulong_value;
unknown's avatar
unknown committed
2557 2558 2559
    pthread_mutex_unlock(&active_mi->rli.data_lock);
  }
  pthread_mutex_unlock(&active_mi->rli.run_lock);
2560
  pthread_mutex_unlock(&LOCK_active_mi);
unknown's avatar
unknown committed
2561 2562
  return 0;
}
2563 2564 2565 2566


bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
{
2567
  sync_binlog_period= (ulong) var->save_result.ulonglong_value;
2568
  return 0;
unknown's avatar
unknown committed
2569
}
unknown's avatar
SCRUM  
unknown committed
2570
#endif /* HAVE_REPLICATION */
unknown's avatar
unknown committed
2571

2572 2573
bool sys_var_rand_seed1::update(THD *thd, set_var *var)
{
2574
  thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
2575 2576 2577 2578 2579
  return 0;
}

bool sys_var_rand_seed2::update(THD *thd, set_var *var)
{
2580
  thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
2581 2582 2583 2584
  return 0;
}


2585 2586
bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
{
2587
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
2588 2589 2590
  String str(buff, sizeof(buff), &my_charset_latin1);
  String *res= var->value->val_str(&str);

2591
  if (!(var->save_result.time_zone=
2592
        my_tz_find(res, thd->lex->time_zone_tables_used)))
2593
  {
2594
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
2595 2596 2597 2598 2599 2600 2601 2602
    return 1;
  }
  return 0;
}


bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
{
2603 2604 2605 2606 2607 2608 2609 2610 2611
  /* 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;
2612 2613 2614 2615 2616 2617 2618
  return 0;
}


byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
				       LEX_STRING *base)
{
unknown's avatar
foo1  
unknown committed
2619
  /*
2620 2621 2622 2623
    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)
2624
    return (byte *)(global_system_variables.time_zone->get_name()->ptr());
2625
  else
2626 2627 2628 2629 2630 2631 2632 2633 2634 2635
  {
    /*
      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;
2636
    return (byte *)(thd->variables.time_zone->get_name()->ptr());
2637
  }
2638 2639 2640 2641 2642
}


void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
{
2643
 pthread_mutex_lock(&LOCK_global_system_variables);
2644 2645 2646 2647 2648
 if (type == OPT_GLOBAL)
 {
   if (default_tz_name)
   {
     String str(default_tz_name, &my_charset_latin1);
2649 2650 2651 2652
     /*
       We are guaranteed to find this time zone since its existence
       is checked during start-up.
     */
2653 2654
     global_system_variables.time_zone=
       my_tz_find(&str, thd->lex->time_zone_tables_used);
2655 2656 2657 2658 2659 2660
   }
   else
     global_system_variables.time_zone= my_tz_SYSTEM;
 }
 else
   thd->variables.time_zone= global_system_variables.time_zone;
2661
 pthread_mutex_unlock(&LOCK_global_system_variables);
2662 2663
}

2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683

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.
      QQ: 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);
2684
  max_user_connections= (uint)var->save_result.ulonglong_value;
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708
  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);
}


byte *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 (byte*) &(thd->user_connect->user_resources.user_conn);
  return (byte*) &(max_user_connections);
}


unknown's avatar
unknown committed
2709 2710 2711 2712 2713 2714
/*
  Functions to update thd->options bits
*/

static bool set_option_bit(THD *thd, set_var *var)
{
2715 2716 2717
  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;
unknown's avatar
unknown committed
2718
  else
2719
    thd->options|= sys_var->bit_flag;
unknown's avatar
unknown committed
2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753
  return 0;
}


static bool set_option_autocommit(THD *thd, set_var *var)
{
  /* The test is negative as the flag we use is NOT autocommit */

  ulong org_options=thd->options;

  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&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
      thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
      if (ha_commit(thd))
	return 1;
    }
    else
    {
      thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
      thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
    }
  }
  return 0;
}

2754 2755 2756
static int check_log_update(THD *thd, set_var *var)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
2757
  if (!(thd->security_ctx->master_access & SUPER_ACL))
2758 2759 2760 2761 2762 2763 2764
  {
    my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
    return 1;
  }
#endif
  return 0;
}
unknown's avatar
unknown committed
2765 2766 2767

static bool set_log_update(THD *thd, set_var *var)
{
2768 2769 2770 2771 2772
  /*
    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
  */
unknown's avatar
foo1  
unknown committed
2773

unknown's avatar
unknown committed
2774
  if (opt_sql_bin_update)
2775
  {
unknown's avatar
unknown committed
2776 2777
    ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
					       OPTION_UPDATE_LOG);
2778 2779 2780 2781 2782 2783 2784 2785
    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));
unknown's avatar
unknown committed
2786 2787 2788 2789
  set_option_bit(thd, var);
  return 0;
}

2790
static bool set_log_bin(THD *thd, set_var *var)
unknown's avatar
unknown committed
2791 2792 2793 2794 2795 2796 2797 2798
{
  if (opt_sql_bin_update)
    ((sys_var_thd_bit*) var->var)->bit_flag|= (OPTION_BIN_LOG |
					       OPTION_UPDATE_LOG);
  set_option_bit(thd, var);
  return 0;
}

2799 2800 2801 2802
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
2803
  if (thd->security_ctx->master_access & SUPER_ACL)
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813
    return 0;
  else
  {
    my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
    return 1;
  }
#else
  return 0;
#endif
}
2814

2815 2816 2817 2818 2819 2820 2821 2822 2823 2824
static byte *get_warning_count(THD *thd)
{
  thd->sys_var_tmp.long_value=
    (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
     thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
  return (byte*) &thd->sys_var_tmp.long_value;
}

static byte *get_error_count(THD *thd)
{
unknown's avatar
foo1  
unknown committed
2825
  thd->sys_var_tmp.long_value=
2826 2827 2828 2829
    thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
  return (byte*) &thd->sys_var_tmp.long_value;
}

unknown's avatar
unknown committed
2830

2831 2832 2833 2834 2835 2836
static byte *get_have_innodb(THD *thd)
{
  return (byte*) show_comp_option_name[have_innodb];
}


2837 2838 2839 2840 2841 2842 2843 2844
static byte *get_prepared_stmt_count(THD *thd)
{
  pthread_mutex_lock(&LOCK_prepared_stmt_count);
  thd->sys_var_tmp.ulong_value= prepared_stmt_count;
  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
  return (byte*) &thd->sys_var_tmp.ulong_value;
}

unknown's avatar
unknown committed
2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864
/****************************************************************************
  Main handling of variables:
  - Initialisation
  - Searching during parsing
  - Update loop
****************************************************************************/

/*
  Find variable name in option my_getopt structure used for command line args

  SYNOPSIS
    find_option()
    opt		option structure array to search in
    name	variable name

  RETURN VALUES
    0		Error
    ptr		pointer to option structure
*/

unknown's avatar
foo1  
unknown committed
2865
static struct my_option *find_option(struct my_option *opt, const char *name)
unknown's avatar
unknown committed
2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902
{
  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 byte *get_sys_var_length(const sys_var *var, uint *length,
				my_bool first)
{
  *length= var->name_length;
  return (byte*) var->name;
}


/*
  Initialises sys variables and put them in system_variable_hash
*/


void set_var_init()
{
2903 2904
  hash_init(&system_variable_hash, system_charset_info,
	    array_elements(sys_variables),0,0,
unknown's avatar
unknown committed
2905
	    (hash_get_key) get_sys_var_length,0,0);
unknown's avatar
unknown committed
2906 2907 2908 2909 2910 2911 2912
  sys_var **var, **end;
  for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ;
       var < end;
       var++)
  {
    (*var)->name_length= strlen((*var)->name);
    (*var)->option_limits= find_option(my_long_options, (*var)->name);
unknown's avatar
SCRUM  
unknown committed
2913
    my_hash_insert(&system_variable_hash, (byte*) *var);
unknown's avatar
unknown committed
2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944
  }
  /*
    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;
}


void set_var_free()
{
  hash_free(&system_variable_hash);
}


/*
  Find a user set-table variable

  SYNOPSIS
    find_sys_var()
    str		Name of system variable to find
    length	Length of variable.  zero means that we should use strlen()
		on the variable

  RETURN VALUES
    pointer	pointer to variable definitions
    0		Unknown variable (error message is given)
*/

2945
sys_var *find_sys_var(const char *str, uint length)
unknown's avatar
unknown committed
2946
{
unknown's avatar
unknown committed
2947 2948
  sys_var *var= (sys_var*) hash_search(&system_variable_hash,
				       (byte*) str,
unknown's avatar
unknown committed
2949 2950 2951
				       length ? length :
				       strlen(str));
  if (!var)
2952
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
unknown's avatar
unknown committed
2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974
  return var;
}


/*
  Execute update of all variables

  SYNOPSIS

  sql_set
    THD		Thread id
    set_var	List of variables to update

  DESCRIPTION
    First run a check of all variables that all updates will go ok.
    If yes, then execute all updates, returning an error if any one failed.

    This should ensure that in all normal cases none all or variables are
    updated

    RETURN VALUE
    0	ok
2975 2976
    1	ERROR, message sent (normally no variables was updated)
    -1  ERROR, message not sent
unknown's avatar
unknown committed
2977 2978
*/

2979
int sql_set_variables(THD *thd, List<set_var_base> *var_list)
unknown's avatar
unknown committed
2980
{
unknown's avatar
unknown committed
2981
  int error;
unknown's avatar
unknown committed
2982
  List_iterator_fast<set_var_base> it(*var_list);
unknown's avatar
unknown committed
2983
  DBUG_ENTER("sql_set_variables");
unknown's avatar
unknown committed
2984 2985 2986 2987

  set_var_base *var;
  while ((var=it++))
  {
unknown's avatar
unknown committed
2988
    if ((error= var->check(thd)))
2989
      goto err;
unknown's avatar
unknown committed
2990
  }
unknown's avatar
unknown committed
2991
  if (!(error= test(thd->net.report_error)))
2992 2993 2994 2995 2996
  {
    it.rewind();
    while ((var= it++))
      error|= var->update(thd);         // Returns 0, -1 or 1
  }
unknown's avatar
unknown committed
2997

2998 2999
err:
  free_underlaid_joins(thd, &thd->lex->select_lex);
unknown's avatar
unknown committed
3000
  DBUG_RETURN(error);
unknown's avatar
unknown committed
3001 3002 3003
}


3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033
/*
  Say if all variables set by a SET support the ONE_SHOT keyword (currently,
  only character set and collation do; later timezones will).

  SYNOPSIS

  not_all_support_one_shot
    set_var	List of variables to update

  NOTES
    It has a "not_" because it makes faster tests (no need to "!")

    RETURN VALUE
    0	all variables of the list support ONE_SHOT
    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;
}


unknown's avatar
unknown committed
3034 3035 3036 3037
/*****************************************************************************
  Functions to handle SET mysql_internal_variable=const_expr
*****************************************************************************/

3038
int set_var::check(THD *thd)
unknown's avatar
unknown committed
3039
{
3040 3041 3042 3043 3044
  if (var->is_readonly())
  {
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
    return -1;
  }
unknown's avatar
unknown committed
3045 3046
  if (var->check_type(type))
  {
unknown's avatar
unknown committed
3047
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
3048
    my_error(err, MYF(0), var->name);
3049
    return -1;
unknown's avatar
unknown committed
3050 3051 3052 3053 3054 3055 3056 3057
  }
  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))
    {
3058
      my_error(ER_NO_DEFAULT, MYF(0), var->name);
3059
      return -1;
unknown's avatar
unknown committed
3060 3061 3062 3063
    }
    return 0;
  }

unknown's avatar
unknown committed
3064
  if ((!value->fixed &&
3065
       value->fix_fields(thd, &value)) || value->check_cols(1))
3066
    return -1;
unknown's avatar
unknown committed
3067 3068
  if (var->check_update_type(value->result_type()))
  {
3069
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
3070
    return -1;
3071
  }
3072
  return var->check(thd, this) ? -1 : 0;
unknown's avatar
unknown committed
3073 3074 3075
}


unknown's avatar
unknown committed
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087
/*
  Check variable, but without assigning value (used by PS)

  SYNOPSIS
    set_var::light_check()
    thd		thread handler

  RETURN VALUE
    0	ok
    1	ERROR, message sent (normally no variables was updated)
    -1  ERROR, message not sent
*/
3088 3089 3090 3091
int set_var::light_check(THD *thd)
{
  if (var->check_type(type))
  {
unknown's avatar
unknown committed
3092
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
3093
    my_error(err, MYF(0), var->name);
3094 3095
    return -1;
  }
unknown's avatar
unknown committed
3096
  if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
3097 3098
    return 1;

3099
  if (value && ((!value->fixed && value->fix_fields(thd, &value)) ||
unknown's avatar
unknown committed
3100
                value->check_cols(1)))
3101 3102 3103 3104 3105
    return -1;
  return 0;
}


3106
int set_var::update(THD *thd)
unknown's avatar
unknown committed
3107 3108 3109 3110
{
  if (!value)
    var->set_default(thd, type);
  else if (var->update(thd, this))
3111
    return -1;				// should never happen
unknown's avatar
unknown committed
3112 3113 3114 3115 3116 3117 3118 3119 3120 3121
  if (var->after_update)
    (*var->after_update)(thd, type);
  return 0;
}


/*****************************************************************************
  Functions to handle SET @user_variable=const_expr
*****************************************************************************/

3122
int set_var_user::check(THD *thd)
unknown's avatar
unknown committed
3123
{
unknown's avatar
unknown committed
3124 3125
  /*
    Item_func_set_user_var can't substitute something else on its place =>
3126
    0 can be passed as last argument (reference on item)
unknown's avatar
unknown committed
3127
  */
3128
  return (user_var_item->fix_fields(thd, (Item**) 0) ||
3129
	  user_var_item->check()) ? -1 : 0;
unknown's avatar
unknown committed
3130 3131 3132
}


unknown's avatar
unknown committed
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144
/*
  Check variable, but without assigning value (used by PS)

  SYNOPSIS
    set_var_user::light_check()
    thd		thread handler

  RETURN VALUE
    0	ok
    1	ERROR, message sent (normally no variables was updated)
    -1  ERROR, message not sent
*/
3145 3146 3147 3148 3149 3150
int set_var_user::light_check(THD *thd)
{
  /*
    Item_func_set_user_var can't substitute something else on its place =>
    0 can be passed as last argument (reference on item)
  */
3151
  return (user_var_item->fix_fields(thd, (Item**) 0));
3152 3153 3154
}


3155
int set_var_user::update(THD *thd)
unknown's avatar
unknown committed
3156 3157 3158 3159
{
  if (user_var_item->update())
  {
    /* Give an error if it's not given already */
unknown's avatar
unknown committed
3160
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
3161
    return -1;
unknown's avatar
unknown committed
3162 3163 3164 3165 3166 3167 3168 3169 3170
  }
  return 0;
}


/*****************************************************************************
  Functions to handle SET PASSWORD
*****************************************************************************/

3171
int set_var_password::check(THD *thd)
unknown's avatar
unknown committed
3172
{
unknown's avatar
unknown committed
3173
#ifndef NO_EMBEDDED_ACCESS_CHECKS
unknown's avatar
unknown committed
3174
  if (!user->host.str)
3175
  {
3176
    if (*thd->security_ctx->priv_host != 0)
3177
    {
3178 3179
      user->host.str= (char *) thd->security_ctx->priv_host;
      user->host.length= strlen(thd->security_ctx->priv_host);
3180 3181 3182 3183 3184 3185 3186
    }
    else
    {
      user->host.str= (char *)"%";
      user->host.length= 1;
    }
  }
3187
  /* Returns 1 as the function sends error to client */
3188 3189
  return check_change_password(thd, user->host.str, user->user.str,
                               password, strlen(password)) ? 1 : 0;
3190
#else
unknown's avatar
unknown committed
3191 3192
  return 0;
#endif
unknown's avatar
unknown committed
3193 3194
}

3195
int set_var_password::update(THD *thd)
unknown's avatar
unknown committed
3196
{
unknown's avatar
unknown committed
3197
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3198
  /* Returns 1 as the function sends error to client */
3199 3200
  return change_password(thd, user->host.str, user->user.str, password) ?
	  1 : 0;
unknown's avatar
unknown committed
3201 3202 3203
#else
  return 0;
#endif
unknown's avatar
unknown committed
3204 3205
}

3206 3207 3208 3209
/****************************************************************************
 Functions to handle table_type
****************************************************************************/

unknown's avatar
unknown committed
3210 3211
/* Based upon sys_var::check_enum() */

unknown's avatar
unknown committed
3212
bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
3213
{
unknown's avatar
unknown committed
3214
  char buff[STRING_BUFFER_USUAL_SIZE];
3215 3216 3217 3218 3219
  const char *value;
  String str(buff, sizeof(buff), &my_charset_latin1), *res;

  if (var->value->result_type() == STRING_RESULT)
  {
3220
    enum db_type db_type;
3221 3222
    if (!(res=var->value->val_str(&str)) ||
	!(var->save_result.ulong_value=
3223
          (ulong) (db_type= ha_resolve_by_name(res->ptr(), res->length()))) ||
3224
        ha_checktype(thd, db_type, 1, 0) != db_type)
3225 3226 3227 3228 3229 3230
    {
      value= res ? res->c_ptr() : "NULL";
      goto err;
    }
    return 0;
  }
unknown's avatar
unknown committed
3231
  value= "unknown";
3232 3233

err:
3234
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
unknown's avatar
unknown committed
3235
  return 1;
3236 3237
}

unknown's avatar
unknown committed
3238

unknown's avatar
unknown committed
3239 3240
byte *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
					    LEX_STRING *base)
3241 3242 3243 3244
{
  ulong val;
  val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
        thd->variables.*offset);
unknown's avatar
unknown committed
3245
  const char *table_type= ha_get_storage_engine((enum db_type)val);
unknown's avatar
unknown committed
3246
  return (byte *) table_type;
3247 3248
}

unknown's avatar
unknown committed
3249

unknown's avatar
unknown committed
3250
void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
3251 3252 3253 3254 3255 3256 3257
{
  if (type == OPT_GLOBAL)
    global_system_variables.*offset= (ulong) DB_TYPE_MYISAM;
  else
    thd->variables.*offset= (ulong) (global_system_variables.*offset);
}

unknown's avatar
unknown committed
3258

unknown's avatar
unknown committed
3259
bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
3260 3261 3262 3263 3264 3265 3266 3267
{
  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;
}

unknown's avatar
unknown committed
3268 3269 3270 3271
void sys_var_thd_table_type::warn_deprecated(THD *thd)
{
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
		      ER_WARN_DEPRECATED_SYNTAX,
3272
		      ER(ER_WARN_DEPRECATED_SYNTAX), "table_type",
unknown's avatar
foo1  
unknown committed
3273
                      "storage_engine");
unknown's avatar
unknown committed
3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287
}

void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type)
{
  warn_deprecated(thd);
  sys_var_thd_storage_engine::set_default(thd, type);
}

bool sys_var_thd_table_type::update(THD *thd, set_var *var)
{
  warn_deprecated(thd);
  return sys_var_thd_storage_engine::update(thd, var);
}

unknown's avatar
unknown committed
3288

3289 3290 3291
/****************************************************************************
 Functions to handle sql_mode
****************************************************************************/
3292

3293 3294 3295
/*
  Make string representation of mode

3296 3297 3298 3299 3300 3301 3302
  SYNOPSIS
    thd   in  thread handler
    val   in  sql_mode value
    len   out pointer on length of string

  RETURN
    pointer to string with sql_mode representation
3303 3304 3305 3306
*/

byte *sys_var_thd_sql_mode::symbolic_mode_representation(THD *thd, ulong val,
                                                         ulong *len)
3307 3308 3309
{
  char buff[256];
  String tmp(buff, sizeof(buff), &my_charset_latin1);
unknown's avatar
unknown committed
3310
  ulong length;
3311 3312 3313 3314 3315 3316

  tmp.length(0);
  for (uint i= 0; val; val>>= 1, i++)
  {
    if (val & 1)
    {
3317 3318
      tmp.append(sql_mode_typelib.type_names[i],
                 sql_mode_typelib.type_lengths[i]);
3319 3320 3321
      tmp.append(',');
    }
  }
unknown's avatar
unknown committed
3322 3323 3324 3325 3326

  if ((length= tmp.length()))
    length--;
  *len= length;
  return (byte*) thd->strmake(tmp.ptr(), length);
3327 3328
}

unknown's avatar
unknown committed
3329

3330 3331 3332 3333 3334 3335 3336 3337 3338
byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
				      LEX_STRING *base)
{
  ulong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
              thd->variables.*offset);
  ulong length_unused;
  return symbolic_mode_representation(thd, val, &length_unused);
}

3339 3340 3341 3342 3343 3344 3345 3346 3347

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;
}

unknown's avatar
unknown committed
3348

3349 3350 3351 3352 3353 3354
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
3355
  {
3356
    thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
3357 3358 3359 3360 3361 3362 3363 3364
    /*
      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;
  }
3365 3366 3367
}

/* Map database specific bits to function bits */
3368

3369 3370 3371
ulong fix_sql_mode(ulong sql_mode)
{
  /*
unknown's avatar
foo1  
unknown committed
3372
    Note that we dont set
3373 3374 3375 3376 3377
    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)
3378
  {
3379
    sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
3380
		MODE_IGNORE_SPACE);
unknown's avatar
foo1  
unknown committed
3381
    /*
3382 3383 3384 3385
      MODE_ONLY_FULL_GROUP_BY removed from ANSI mode because it is currently
      overly restrictive (see BUG#8510).
    */
  }
3386 3387 3388 3389
  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 |
3390
		MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405
  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);
3406
  if (sql_mode & MODE_MAXDB)
3407 3408 3409
    sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
		MODE_IGNORE_SPACE |
		MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
3410
		MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
3411
  if (sql_mode & MODE_MYSQL40)
3412
    sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_HIGH_NOT_PRECEDENCE;
3413
  if (sql_mode & MODE_MYSQL323)
3414
    sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_HIGH_NOT_PRECEDENCE;
unknown's avatar
unknown committed
3415 3416 3417
  if (sql_mode & MODE_TRADITIONAL)
    sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
                MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
3418
                MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER);
3419 3420
  return sql_mode;
}
3421 3422


3423 3424 3425 3426
/****************************************************************************
  Named list handling
****************************************************************************/

unknown's avatar
unknown committed
3427 3428
gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
		NAMED_LIST **found)
3429 3430 3431 3432 3433 3434
{
  I_List_iterator<NAMED_LIST> it(*list);
  NAMED_LIST *element;
  while ((element= it++))
  {
    if (element->cmp(name, length))
unknown's avatar
unknown committed
3435
    {
3436 3437
      if (found)
        *found= element;
3438
      return element->data;
unknown's avatar
unknown committed
3439
    }
3440 3441 3442 3443 3444
  }
  return 0;
}


3445 3446
void delete_elements(I_List<NAMED_LIST> *list,
		     void (*free_element)(const char *name, gptr))
3447 3448
{
  NAMED_LIST *element;
unknown's avatar
unknown committed
3449
  DBUG_ENTER("delete_elements");
3450 3451
  while ((element= list->get()))
  {
3452
    (*free_element)(element->name, element->data);
3453 3454
    delete element;
  }
unknown's avatar
unknown committed
3455
  DBUG_VOID_RETURN;
3456 3457 3458 3459 3460
}


/* Key cache functions */

unknown's avatar
unknown committed
3461
static KEY_CACHE *create_key_cache(const char *name, uint length)
3462
{
unknown's avatar
unknown committed
3463
  KEY_CACHE *key_cache;
3464 3465
  DBUG_ENTER("create_key_cache");
  DBUG_PRINT("enter",("name: %.*s", length, name));
unknown's avatar
foo1  
unknown committed
3466

unknown's avatar
unknown committed
3467
  if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
3468
					     MYF(MY_ZEROFILL | MY_WME))))
unknown's avatar
unknown committed
3469 3470
  {
    if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
3471 3472
    {
      my_free((char*) key_cache, MYF(0));
unknown's avatar
unknown committed
3473
      key_cache= 0;
3474 3475 3476 3477 3478 3479 3480 3481 3482
    }
    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
      */
unknown's avatar
unknown committed
3483 3484 3485
      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;
3486
    }
unknown's avatar
unknown committed
3487
  }
3488
  DBUG_RETURN(key_cache);
3489 3490 3491
}


unknown's avatar
unknown committed
3492
KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
3493
{
unknown's avatar
unknown committed
3494
  LEX_STRING key_cache_name;
unknown's avatar
unknown committed
3495
  KEY_CACHE *key_cache;
3496

unknown's avatar
unknown committed
3497 3498
  key_cache_name.str= (char *) name;
  key_cache_name.length= length;
3499 3500
  pthread_mutex_lock(&LOCK_global_system_variables);
  if (!(key_cache= get_key_cache(&key_cache_name)))
3501
    key_cache= create_key_cache(name, length);
3502
  pthread_mutex_unlock(&LOCK_global_system_variables);
3503 3504 3505 3506
  return key_cache;
}


unknown's avatar
unknown committed
3507
void free_key_cache(const char *name, KEY_CACHE *key_cache)
3508
{
3509 3510
  ha_end_key_cache(key_cache);
  my_free((char*) key_cache, MYF(0));
unknown's avatar
unknown committed
3511 3512 3513
}


unknown's avatar
unknown committed
3514
bool process_key_caches(int (* func) (const char *name, KEY_CACHE *))
3515
{
unknown's avatar
unknown committed
3516 3517
  I_List_iterator<NAMED_LIST> it(key_caches);
  NAMED_LIST *element;
3518

unknown's avatar
unknown committed
3519 3520
  while ((element= it++))
  {
unknown's avatar
unknown committed
3521
    KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
3522
    func(element->name, key_cache);
unknown's avatar
unknown committed
3523 3524
  }
  return 0;
3525 3526
}

3527

3528 3529 3530 3531 3532
void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
{
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
		      ER_WARN_DEPRECATED_SYNTAX,
		      ER(ER_WARN_DEPRECATED_SYNTAX), "log_bin_trust_routine_creators",
unknown's avatar
foo1  
unknown committed
3533
                      "log_bin_trust_function_creators");
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547
}

void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
{
  warn_deprecated(thd);
  sys_var_bool_ptr::set_default(thd, type);
}

bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
{
  warn_deprecated(thd);
  return sys_var_bool_ptr::update(thd, var);
}

unknown's avatar
unknown committed
3548 3549 3550 3551
/****************************************************************************
  Used templates
****************************************************************************/

3552
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
unknown's avatar
unknown committed
3553
template class List<set_var_base>;
unknown's avatar
unknown committed
3554
template class List_iterator_fast<set_var_base>;
3555
template class I_List_iterator<NAMED_LIST>;
unknown's avatar
unknown committed
3556
#endif