~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/**
17
  @file
18
19
  @brief
20
  Handling of MySQL SQL variables
21
22
  @details
23
  To add a new variable, one has to do the following:
24
25
  - Use one of the 'sys_var... classes from set_var.h or write a specific
26
    one for the variable type.
27
  - Define it in the 'variable definition list' in this file.
28
  - If the variable is thread specific, add it to 'system_variables' struct.
29
    If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
30
  - If the variable should be changed from the command line, add a definition
31
    of it in the my_option structure list in mysqld.cc
32
  - Don't forget to initialize new fields in global_system_variables and
33
    max_system_variables!
34
35
  @todo
36
    Add full support for the variable character_set (for 4.1)
37
38
  @todo
39
    When updating myisam_delay_key_write, we should do a 'flush tables'
40
    of all MyISAM tables to ensure that they are reopen with the
41
    new attribute.
42
43
  @note
44
    Be careful with var->save_result: sys_var::check() only updates
45
    ulonglong_value; so other members of the union are garbage then; to use
46
    them you must first assign a value to them (in specific ::check() for
47
    example).
48
*/
49
50
#ifdef USE_PRAGMA_IMPLEMENTATION
51
#pragma implementation				// gcc: Class implementation
52
#endif
53
54
#include "mysql_priv.h"
55
#include <mysql.h>
56
#include "slave.h"
57
#include "rpl_mi.h"
58
#include <my_getopt.h>
59
#include <thr_alarm.h>
60
#include <myisam.h>
61
#include <my_dir.h>
62
63
extern CHARSET_INFO *character_set_filesystem;
64
65
66
static DYNAMIC_ARRAY fixed_show_vars;
67
static HASH system_variable_hash;
68
69
const char *bool_type_names[]= { "OFF", "ON", NullS };
70
TYPELIB bool_typelib=
71
{
72
  array_elements(bool_type_names)-1, "", bool_type_names, NULL
73
};
74
75
const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
76
TYPELIB delay_key_write_typelib=
77
{
78
  array_elements(delay_key_write_type_names)-1, "",
79
  delay_key_write_type_names, NULL
80
};
81
82
const char *slave_exec_mode_names[]=
83
{ "STRICT", "IDEMPOTENT", NullS };
84
static const unsigned int slave_exec_mode_names_len[]=
85
{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 };
86
TYPELIB slave_exec_mode_typelib=
87
{
88
  array_elements(slave_exec_mode_names)-1, "",
89
  slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len
90
};
91
92
static bool sys_update_init_connect(THD*, set_var*);
93
static void sys_default_init_connect(THD*, enum_var_type type);
94
static bool sys_update_init_slave(THD*, set_var*);
95
static void sys_default_init_slave(THD*, enum_var_type type);
96
static bool set_option_bit(THD *thd, set_var *var);
97
static bool set_option_autocommit(THD *thd, set_var *var);
98
static int  check_log_update(THD *thd, set_var *var);
99
static bool set_log_update(THD *thd, set_var *var);
100
static int  check_pseudo_thread_id(THD *thd, set_var *var);
101
void fix_binlog_format_after_update(THD *thd, enum_var_type type);
102
static void fix_low_priority_updates(THD *thd, enum_var_type type);
103
static int check_tx_isolation(THD *thd, set_var *var);
104
static void fix_tx_isolation(THD *thd, enum_var_type type);
105
static int check_completion_type(THD *thd, set_var *var);
106
static void fix_completion_type(THD *thd, enum_var_type type);
107
static void fix_net_read_timeout(THD *thd, enum_var_type type);
108
static void fix_net_write_timeout(THD *thd, enum_var_type type);
109
static void fix_net_retry_count(THD *thd, enum_var_type type);
110
static void fix_max_join_size(THD *thd, enum_var_type type);
111
static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
112
static void fix_max_binlog_size(THD *thd, enum_var_type type);
113
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 void fix_thd_mem_root(THD *thd, enum_var_type type);
116
static void fix_trans_mem_root(THD *thd, enum_var_type type);
117
static void fix_server_id(THD *thd, enum_var_type type);
118
static ulonglong fix_unsigned(THD *, ulonglong, const struct my_option *);
119
static bool get_unsigned(THD *thd, set_var *var);
120
bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
121
                          const char *name, longlong val);
122
static KEY_CACHE *create_key_cache(const char *name, uint length);
123
static uchar *get_error_count(THD *thd);
124
static uchar *get_warning_count(THD *thd);
125
static uchar *get_tmpdir(THD *thd);
126
static int  sys_check_log_path(THD *thd,  set_var *var);
127
static bool sys_update_general_log_path(THD *thd, set_var * var);
128
static void sys_default_general_log_path(THD *thd, enum_var_type type);
129
static bool sys_update_slow_log_path(THD *thd, set_var * var);
130
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
131
132
/*
133
  Variable definition list
134
135
  These are variables that can be set from the command line, in
136
  alphabetic order.
137
138
  The variables are linked into the list. A variable is added to
139
  it in the constructor (see sys_var class for details).
140
*/
141
142
static sys_var_chain vars = { NULL, NULL };
143
144
static sys_var_thd_ulong
145
sys_auto_increment_increment(&vars, "auto_increment_increment",
146
                             &SV::auto_increment_increment, NULL, NULL,
147
                             sys_var::SESSION_VARIABLE_IN_BINLOG);
148
static sys_var_thd_ulong
149
sys_auto_increment_offset(&vars, "auto_increment_offset",
150
                          &SV::auto_increment_offset, NULL, NULL,
151
                          sys_var::SESSION_VARIABLE_IN_BINLOG);
152
153
static sys_var_const_str       sys_basedir(&vars, "basedir", mysql_home);
154
static sys_var_long_ptr	sys_binlog_cache_size(&vars, "binlog_cache_size",
155
					      &binlog_cache_size);
156
static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
157
                                            &SV::binlog_format);
158
static sys_var_thd_ulong	sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
159
						  &SV::bulk_insert_buff_size);
160
static sys_var_character_set_sv
161
sys_character_set_server(&vars, "character_set_server",
162
                         &SV::collation_server, &default_charset_info, 0,
163
                         sys_var::SESSION_VARIABLE_IN_BINLOG);
164
sys_var_const_str       sys_charset_system(&vars, "character_set_system",
165
                                           (char *)my_charset_utf8_general_ci.name);
166
static sys_var_character_set_database
167
sys_character_set_database(&vars, "character_set_database",
168
                           sys_var::SESSION_VARIABLE_IN_BINLOG);
169
static sys_var_character_set_client
170
sys_character_set_client(&vars, "character_set_client",
171
                         &SV::character_set_client,
172
                         &default_charset_info,
173
                         sys_var::SESSION_VARIABLE_IN_BINLOG);
174
static sys_var_character_set_sv
175
sys_character_set_connection(&vars, "character_set_connection",
176
                             &SV::collation_connection,
177
                             &default_charset_info, 0,
178
                             sys_var::SESSION_VARIABLE_IN_BINLOG);
179
static sys_var_character_set_sv sys_character_set_results(&vars, "character_set_results",
180
                                        &SV::character_set_results,
181
                                        &default_charset_info, true);
182
static sys_var_character_set_sv sys_character_set_filesystem(&vars, "character_set_filesystem",
183
                                        &SV::character_set_filesystem,
184
                                        &character_set_filesystem);
185
static sys_var_thd_ulong	sys_completion_type(&vars, "completion_type",
186
					 &SV::completion_type,
187
					 check_completion_type,
188
					 fix_completion_type);
189
static sys_var_collation_sv
190
sys_collation_connection(&vars, "collation_connection",
191
                         &SV::collation_connection, &default_charset_info,
192
                         sys_var::SESSION_VARIABLE_IN_BINLOG);
193
static sys_var_collation_sv
194
sys_collation_database(&vars, "collation_database", &SV::collation_database,
195
                       &default_charset_info,
196
                       sys_var::SESSION_VARIABLE_IN_BINLOG);
197
static sys_var_collation_sv
198
sys_collation_server(&vars, "collation_server", &SV::collation_server,
199
                     &default_charset_info,
200
                     sys_var::SESSION_VARIABLE_IN_BINLOG);
201
static sys_var_long_ptr	sys_concurrent_insert(&vars, "concurrent_insert",
202
                                              &myisam_concurrent_insert);
203
static sys_var_long_ptr	sys_connect_timeout(&vars, "connect_timeout",
204
					    &connect_timeout);
205
static sys_var_const_str       sys_datadir(&vars, "datadir", mysql_real_data_home);
206
#ifndef DBUG_OFF
207
static sys_var_thd_dbug        sys_dbug(&vars, "debug");
208
#endif
209
static sys_var_enum		sys_delay_key_write(&vars, "delay_key_write",
210
					    &delay_key_write_options,
211
					    &delay_key_write_typelib,
212
					    fix_delay_key_write);
213
214
static sys_var_long_ptr	sys_expire_logs_days(&vars, "expire_logs_days",
215
					     &expire_logs_days);
216
static sys_var_bool_ptr	sys_flush(&vars, "flush", &myisam_flush);
217
static sys_var_long_ptr	sys_flush_time(&vars, "flush_time", &flush_time);
218
sys_var_str             sys_init_connect(&vars, "init_connect", 0,
219
                                         sys_update_init_connect,
220
                                         sys_default_init_connect,0);
221
sys_var_str             sys_init_slave(&vars, "init_slave", 0,
222
                                       sys_update_init_slave,
223
                                       sys_default_init_slave,0);
224
static sys_var_thd_ulong	sys_interactive_timeout(&vars, "interactive_timeout",
225
						&SV::net_interactive_timeout);
226
static sys_var_thd_ulong	sys_join_buffer_size(&vars, "join_buffer_size",
227
					     &SV::join_buff_size);
228
static sys_var_key_buffer_size	sys_key_buffer_size(&vars, "key_buffer_size");
229
static sys_var_key_cache_long  sys_key_cache_block_size(&vars, "key_cache_block_size",
230
						 offsetof(KEY_CACHE,
231
							  param_block_size));
232
static sys_var_key_cache_long	sys_key_cache_division_limit(&vars, "key_cache_division_limit",
233
						     offsetof(KEY_CACHE,
234
							      param_division_limit));
235
static sys_var_key_cache_long  sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
236
						     offsetof(KEY_CACHE,
237
							      param_age_threshold));
238
static sys_var_bool_ptr	sys_local_infile(&vars, "local_infile",
239
					 &opt_local_infile);
240
static sys_var_bool_ptr
241
  sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes",
242
                                    &opt_log_queries_not_using_indexes);
243
static sys_var_thd_ulong	sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
244
static sys_var_microseconds	sys_var_long_query_time(&vars, "long_query_time",
245
                                                        &SV::long_query_time);
246
static sys_var_thd_bool	sys_low_priority_updates(&vars, "low_priority_updates",
247
						 &SV::low_priority_updates,
248
						 fix_low_priority_updates);
249
#ifndef TO_BE_DELETED	/* Alias for the low_priority_updates */
250
static sys_var_thd_bool	sys_sql_low_priority_updates(&vars, "sql_low_priority_updates",
251
						     &SV::low_priority_updates,
252
						     fix_low_priority_updates);
253
#endif
254
static sys_var_thd_ulong	sys_max_allowed_packet(&vars, "max_allowed_packet",
255
					       &SV::max_allowed_packet);
256
static sys_var_long_ptr	sys_max_binlog_cache_size(&vars, "max_binlog_cache_size",
257
						  &max_binlog_cache_size);
258
static sys_var_long_ptr	sys_max_binlog_size(&vars, "max_binlog_size",
259
					    &max_binlog_size,
260
                                            fix_max_binlog_size);
261
static sys_var_long_ptr	sys_max_connections(&vars, "max_connections",
262
					    &max_connections,
263
                                            fix_max_connections);
264
static sys_var_long_ptr	sys_max_connect_errors(&vars, "max_connect_errors",
265
					       &max_connect_errors);
266
static sys_var_thd_ulong	sys_max_error_count(&vars, "max_error_count",
267
					    &SV::max_error_count);
268
static sys_var_thd_ulonglong	sys_max_heap_table_size(&vars, "max_heap_table_size",
269
						&SV::max_heap_table_size);
270
static sys_var_thd_ulong sys_pseudo_thread_id(&vars, "pseudo_thread_id",
271
                                              &SV::pseudo_thread_id,
272
                                              check_pseudo_thread_id, 0,
273
                                              sys_var::SESSION_VARIABLE_IN_BINLOG);
274
static sys_var_thd_ha_rows	sys_max_join_size(&vars, "max_join_size",
275
					  &SV::max_join_size,
276
					  fix_max_join_size);
277
static sys_var_thd_ulong	sys_max_seeks_for_key(&vars, "max_seeks_for_key",
278
					      &SV::max_seeks_for_key);
279
static sys_var_thd_ulong   sys_max_length_for_sort_data(&vars, "max_length_for_sort_data",
280
                                                 &SV::max_length_for_sort_data);
281
#ifndef TO_BE_DELETED	/* Alias for max_join_size */
282
static sys_var_thd_ha_rows	sys_sql_max_join_size(&vars, "sql_max_join_size",
283
					      &SV::max_join_size,
284
					      fix_max_join_size);
285
#endif
286
static sys_var_long_ptr	sys_max_relay_log_size(&vars, "max_relay_log_size",
287
                                               &max_relay_log_size,
288
                                               fix_max_relay_log_size);
289
static sys_var_thd_ulong	sys_max_sort_length(&vars, "max_sort_length",
290
					    &SV::max_sort_length);
291
static sys_var_max_user_conn   sys_max_user_connections(&vars, "max_user_connections");
292
static sys_var_thd_ulong	sys_max_tmp_tables(&vars, "max_tmp_tables",
293
					   &SV::max_tmp_tables);
294
static sys_var_long_ptr	sys_max_write_lock_count(&vars, "max_write_lock_count",
295
						 &max_write_lock_count);
296
static sys_var_thd_ulong       sys_min_examined_row_limit(&vars, "min_examined_row_limit",
297
                                                          &SV::min_examined_row_limit);
298
static sys_var_long_ptr	sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
299
                                                    &myisam_data_pointer_size);
300
static sys_var_thd_ulonglong	sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
301
static sys_var_thd_ulong       sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads);
302
static sys_var_thd_ulong	sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
303
304
static sys_var_thd_enum         sys_myisam_stats_method(&vars, "myisam_stats_method",
305
                                                &SV::myisam_stats_method,
306
                                                &myisam_stats_method_typelib,
307
                                                NULL);
308
static sys_var_thd_ulong	sys_net_buffer_length(&vars, "net_buffer_length",
309
					      &SV::net_buffer_length);
310
static sys_var_thd_ulong	sys_net_read_timeout(&vars, "net_read_timeout",
311
					     &SV::net_read_timeout,
312
					     0, fix_net_read_timeout);
313
static sys_var_thd_ulong	sys_net_write_timeout(&vars, "net_write_timeout",
314
					      &SV::net_write_timeout,
315
					      0, fix_net_write_timeout);
316
static sys_var_thd_ulong	sys_net_retry_count(&vars, "net_retry_count",
317
					    &SV::net_retry_count,
318
					    0, fix_net_retry_count);
319
static sys_var_thd_bool	sys_new_mode(&vars, "new", &SV::new_mode);
320
static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
321
                                       &global_system_variables.old_mode);
322
/* these two cannot be static */
323
sys_var_thd_bool                sys_old_alter_table(&vars, "old_alter_table",
324
                                            &SV::old_alter_table);
325
sys_var_thd_bool                sys_old_passwords(&vars, "old_passwords", &SV::old_passwords);
326
static sys_var_thd_ulong        sys_optimizer_prune_level(&vars, "optimizer_prune_level",
327
                                                  &SV::optimizer_prune_level);
328
static sys_var_thd_ulong        sys_optimizer_search_depth(&vars, "optimizer_search_depth",
329
                                                   &SV::optimizer_search_depth);
330
331
const char *optimizer_use_mrr_names[] = {"auto", "force", "disable", NullS};
332
TYPELIB optimizer_use_mrr_typelib= {
333
  array_elements(optimizer_use_mrr_names) - 1, "",
334
  optimizer_use_mrr_names, NULL
335
};
336
337
static sys_var_thd_enum        sys_optimizer_use_mrr(&vars, "optimizer_use_mrr",
338
                                              &SV::optimizer_use_mrr,
339
                                              &optimizer_use_mrr_typelib,
340
                                              NULL);
341
342
static sys_var_thd_ulong        sys_preload_buff_size(&vars, "preload_buffer_size",
343
                                              &SV::preload_buff_size);
344
static sys_var_thd_ulong	sys_read_buff_size(&vars, "read_buffer_size",
345
					   &SV::read_buff_size);
346
static sys_var_opt_readonly	sys_readonly(&vars, "read_only", &opt_readonly);
347
static sys_var_thd_ulong	sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
348
					       &SV::read_rnd_buff_size);
349
static sys_var_thd_ulong	sys_div_precincrement(&vars, "div_precision_increment",
350
                                              &SV::div_precincrement);
351
static sys_var_long_ptr	sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
352
					      &rpl_recovery_rank);
353
354
static sys_var_thd_ulong	sys_range_alloc_block_size(&vars, "range_alloc_block_size",
355
						   &SV::range_alloc_block_size);
356
static sys_var_thd_ulong	sys_query_alloc_block_size(&vars, "query_alloc_block_size",
357
						   &SV::query_alloc_block_size,
358
						   0, fix_thd_mem_root);
359
static sys_var_thd_ulong	sys_query_prealloc_size(&vars, "query_prealloc_size",
360
						&SV::query_prealloc_size,
361
						0, fix_thd_mem_root);
362
static sys_var_readonly        sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
363
static sys_var_thd_ulong	sys_trans_alloc_block_size(&vars, "transaction_alloc_block_size",
364
						   &SV::trans_alloc_block_size,
365
						   0, fix_trans_mem_root);
366
static sys_var_thd_ulong	sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
367
						&SV::trans_prealloc_size,
368
						0, fix_trans_mem_root);
369
370
static sys_var_bool_ptr	sys_secure_auth(&vars, "secure_auth", &opt_secure_auth);
371
static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
372
                                             &opt_secure_file_priv);
373
static sys_var_long_ptr	sys_server_id(&vars, "server_id", &server_id, fix_server_id);
374
static sys_var_bool_ptr	sys_slave_compressed_protocol(&vars, "slave_compressed_protocol",
375
						      &opt_slave_compressed_protocol);
376
#ifdef HAVE_REPLICATION
377
static sys_var_bool_ptr         sys_slave_allow_batching(&vars, "slave_allow_batching",
378
                                                         &slave_allow_batching);
379
static sys_var_set_slave_mode slave_exec_mode(&vars,
380
                                              "slave_exec_mode",
381
                                              &slave_exec_mode_options,
382
                                              &slave_exec_mode_typelib,
383
                                              0);
384
#endif
385
static sys_var_long_ptr	sys_slow_launch_time(&vars, "slow_launch_time",
386
					     &slow_launch_time);
387
static sys_var_thd_ulong	sys_sort_buffer(&vars, "sort_buffer_size",
388
					&SV::sortbuff_size);
389
/*
390
  sql_mode should *not* have binlog_mode=SESSION_VARIABLE_IN_BINLOG:
391
  even though it is written to the binlog, the slave ignores the
392
  MODE_NO_DIR_IN_CREATE variable, so slave's value differs from
393
  master's (see log_event.cc: Query_log_event::do_apply_event()).
394
*/
395
static sys_var_thd_optimizer_switch   sys_optimizer_switch(&vars, "optimizer_switch",
396
                                     &SV::optimizer_switch);
397
static sys_var_const_str	sys_ssl_ca(&vars, "ssl_ca", NULL);
398
static sys_var_const_str	sys_ssl_capath(&vars, "ssl_capath", NULL);
399
static sys_var_const_str	sys_ssl_cert(&vars, "ssl_cert", NULL);
400
static sys_var_const_str	sys_ssl_cipher(&vars, "ssl_cipher", NULL);
401
static sys_var_const_str	sys_ssl_key(&vars, "ssl_key", NULL);
402
403
static sys_var_thd_storage_engine sys_storage_engine(&vars, "storage_engine",
404
				       &SV::table_plugin);
405
static sys_var_bool_ptr	sys_sync_frm(&vars, "sync_frm", &opt_sync_frm);
406
static sys_var_const_str	sys_system_time_zone(&vars, "system_time_zone",
407
                                             system_time_zone);
408
static sys_var_long_ptr	sys_table_def_size(&vars, "table_definition_cache",
409
                                           &table_def_size);
410
static sys_var_long_ptr	sys_table_cache_size(&vars, "table_open_cache",
411
					     &table_cache_size);
412
static sys_var_long_ptr	sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
413
                                                    &table_lock_wait_timeout);
414
static sys_var_long_ptr	sys_thread_cache_size(&vars, "thread_cache_size",
415
					      &thread_cache_size);
416
sys_var_long_ptr	sys_thread_pool_size(&vars, "thread_pool_size",
417
					      &thread_pool_size);
418
static sys_var_thd_enum	sys_tx_isolation(&vars, "tx_isolation",
419
					 &SV::tx_isolation,
420
					 &tx_isolation_typelib,
421
					 fix_tx_isolation,
422
					 check_tx_isolation);
423
static sys_var_thd_ulonglong	sys_tmp_table_size(&vars, "tmp_table_size",
424
					   &SV::tmp_table_size);
425
static sys_var_bool_ptr  sys_timed_mutexes(&vars, "timed_mutexes",
426
                                    &timed_mutexes);
427
static sys_var_const_str	sys_version(&vars, "version", server_version);
428
static sys_var_const_str	sys_version_comment(&vars, "version_comment",
429
                                            MYSQL_COMPILATION_COMMENT);
430
static sys_var_const_str	sys_version_compile_machine(&vars, "version_compile_machine",
431
                                                    MACHINE_TYPE);
432
static sys_var_const_str	sys_version_compile_os(&vars, "version_compile_os",
433
                                               SYSTEM_TYPE);
434
static sys_var_thd_ulong	sys_net_wait_timeout(&vars, "wait_timeout",
435
					     &SV::net_wait_timeout);
436
437
/* Condition pushdown to storage engine */
438
static sys_var_thd_bool
439
sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
440
			      &SV::engine_condition_pushdown);
441
442
/* Time/date/datetime formats */
443
444
static sys_var_thd_date_time_format sys_time_format(&vars, "time_format",
445
					     &SV::time_format,
446
					     MYSQL_TIMESTAMP_TIME);
447
static sys_var_thd_date_time_format sys_date_format(&vars, "date_format",
448
					     &SV::date_format,
449
					     MYSQL_TIMESTAMP_DATE);
450
static sys_var_thd_date_time_format sys_datetime_format(&vars, "datetime_format",
451
						 &SV::datetime_format,
452
						 MYSQL_TIMESTAMP_DATETIME);
453
454
/* Variables that are bits in THD */
455
456
sys_var_thd_bit sys_autocommit(&vars, "autocommit", 0,
457
                               set_option_autocommit,
458
                               OPTION_NOT_AUTOCOMMIT,
459
                               1);
460
static sys_var_thd_bit	sys_big_tables(&vars, "big_tables", 0,
461
				       set_option_bit,
462
				       OPTION_BIG_TABLES);
463
#ifndef TO_BE_DELETED	/* Alias for big_tables */
464
static sys_var_thd_bit	sys_sql_big_tables(&vars, "sql_big_tables", 0,
465
					   set_option_bit,
466
					   OPTION_BIG_TABLES);
467
#endif
468
static sys_var_thd_bit	sys_big_selects(&vars, "sql_big_selects", 0,
469
					set_option_bit,
470
					OPTION_BIG_SELECTS);
471
static sys_var_thd_bit	sys_log_off(&vars, "sql_log_off",
472
				    check_log_update,
473
				    set_option_bit,
474
				    OPTION_LOG_OFF);
475
static sys_var_thd_bit	sys_log_update(&vars, "sql_log_update",
476
                                       check_log_update,
477
				       set_log_update,
478
				       OPTION_BIN_LOG);
479
static sys_var_thd_bit	sys_log_binlog(&vars, "sql_log_bin",
480
                                       check_log_update,
481
				       set_option_bit,
482
				       OPTION_BIN_LOG);
483
static sys_var_thd_bit	sys_sql_warnings(&vars, "sql_warnings", 0,
484
					 set_option_bit,
485
					 OPTION_WARNINGS);
486
static sys_var_thd_bit	sys_sql_notes(&vars, "sql_notes", 0,
487
					 set_option_bit,
488
					 OPTION_SQL_NOTES);
489
static sys_var_thd_bit	sys_auto_is_null(&vars, "sql_auto_is_null", 0,
490
					 set_option_bit,
491
                                         OPTION_AUTO_IS_NULL, 0,
492
                                         sys_var::SESSION_VARIABLE_IN_BINLOG);
493
static sys_var_thd_bit	sys_safe_updates(&vars, "sql_safe_updates", 0,
494
					 set_option_bit,
495
					 OPTION_SAFE_UPDATES);
496
static sys_var_thd_bit	sys_buffer_results(&vars, "sql_buffer_result", 0,
497
					   set_option_bit,
498
					   OPTION_BUFFER_RESULT);
499
static sys_var_thd_bit	sys_quote_show_create(&vars, "sql_quote_show_create", 0,
500
					      set_option_bit,
501
					      OPTION_QUOTE_SHOW_CREATE);
502
static sys_var_thd_bit	sys_foreign_key_checks(&vars, "foreign_key_checks", 0,
503
					       set_option_bit,
504
					       OPTION_NO_FOREIGN_KEY_CHECKS,
505
                                               1, sys_var::SESSION_VARIABLE_IN_BINLOG);
506
static sys_var_thd_bit	sys_unique_checks(&vars, "unique_checks", 0,
507
					  set_option_bit,
508
					  OPTION_RELAXED_UNIQUE_CHECKS,
509
                                          1,
510
                                          sys_var::SESSION_VARIABLE_IN_BINLOG);
511
/* Local state variables */
512
513
static sys_var_thd_ha_rows	sys_select_limit(&vars, "sql_select_limit",
514
						 &SV::select_limit);
515
static sys_var_timestamp sys_timestamp(&vars, "timestamp",
516
                                       sys_var::SESSION_VARIABLE_IN_BINLOG);
517
static sys_var_last_insert_id
518
sys_last_insert_id(&vars, "last_insert_id",
519
                   sys_var::SESSION_VARIABLE_IN_BINLOG);
520
/*
521
  identity is an alias for last_insert_id(), so that we are compatible
522
  with Sybase
523
*/
524
static sys_var_last_insert_id
525
sys_identity(&vars, "identity", sys_var::SESSION_VARIABLE_IN_BINLOG);
526
527
static sys_var_thd_lc_time_names
528
sys_lc_time_names(&vars, "lc_time_names", sys_var::SESSION_VARIABLE_IN_BINLOG);
529
530
/*
531
  insert_id should *not* be marked as written to the binlog (i.e., it
532
  should *not* have binlog_status==SESSION_VARIABLE_IN_BINLOG),
533
  because we want any statement that refers to insert_id explicitly to
534
  be unsafe.  (By "explicitly", we mean using @@session.insert_id,
535
  whereas insert_id is used "implicitly" when NULL value is inserted
536
  into an auto_increment column).
537
538
  We want statements referring explicitly to @@session.insert_id to be
539
  unsafe, because insert_id is modified internally by the slave sql
540
  thread when NULL values are inserted in an AUTO_INCREMENT column.
541
  This modification interfers with the value of the
542
  @@session.insert_id variable if @@session.insert_id is referred
543
  explicitly by an insert statement (as is seen by executing "SET
544
  @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
545
  AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
546
  statement-based logging mode: t will be different on master and
547
  slave).
548
*/
549
static sys_var_insert_id sys_insert_id(&vars, "insert_id");
550
static sys_var_readonly		sys_error_count(&vars, "error_count",
551
						OPT_SESSION,
552
						SHOW_LONG,
553
						get_error_count);
554
static sys_var_readonly		sys_warning_count(&vars, "warning_count",
555
						  OPT_SESSION,
556
						  SHOW_LONG,
557
						  get_warning_count);
558
559
static sys_var_rand_seed1 sys_rand_seed1(&vars, "rand_seed1",
560
                                         sys_var::SESSION_VARIABLE_IN_BINLOG);
561
static sys_var_rand_seed2 sys_rand_seed2(&vars, "rand_seed2",
562
                                         sys_var::SESSION_VARIABLE_IN_BINLOG);
563
564
static sys_var_thd_ulong        sys_default_week_format(&vars, "default_week_format",
565
					                &SV::default_week_format);
566
567
sys_var_thd_ulong               sys_group_concat_max_len(&vars, "group_concat_max_len",
568
                                                         &SV::group_concat_max_len);
569
570
sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
571
                                    sys_var::SESSION_VARIABLE_IN_BINLOG);
572
573
/* Global read-only variable containing hostname */
574
static sys_var_const_str        sys_hostname(&vars, "hostname", glob_hostname);
575
576
static sys_var_const_str_ptr    sys_repl_report_host(&vars, "report_host", &report_host);
577
static sys_var_const_str_ptr    sys_repl_report_user(&vars, "report_user", &report_user);
578
static sys_var_const_str_ptr    sys_repl_report_password(&vars, "report_password", &report_password);
579
580
static uchar *slave_get_report_port(THD *thd)
581
{
582
  thd->sys_var_tmp.long_value= report_port;
583
  return (uchar*) &thd->sys_var_tmp.long_value;
584
}
585
586
static sys_var_readonly    sys_repl_report_port(&vars, "report_port", OPT_GLOBAL, SHOW_INT, slave_get_report_port);
587
588
sys_var_thd_bool  sys_keep_files_on_create(&vars, "keep_files_on_create", 
589
                                           &SV::keep_files_on_create);
590
/* Read only variables */
591
592
static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
593
static sys_var_have_variable sys_have_crypt(&vars, "have_crypt", &have_crypt);
594
static sys_var_have_plugin sys_have_csv(&vars, "have_csv", C_STRING_WITH_LEN("csv"), MYSQL_STORAGE_ENGINE_PLUGIN);
595
static sys_var_have_variable sys_have_dlopen(&vars, "have_dynamic_loading", &have_dlopen);
596
static sys_var_have_plugin sys_have_innodb(&vars, "have_innodb", C_STRING_WITH_LEN("innodb"), MYSQL_STORAGE_ENGINE_PLUGIN);
597
static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
598
/* Global read-only variable describing server license */
599
static sys_var_const_str	sys_license(&vars, "license", STRINGIFY_ARG(LICENSE));
600
/* Global variables which enable|disable logging */
601
static sys_var_log_state sys_var_general_log(&vars, "general_log", &opt_log,
602
                                      QUERY_LOG_GENERAL);
603
/* Synonym of "general_log" for consistency with SHOW VARIABLES output */
604
static sys_var_log_state sys_var_log(&vars, "log", &opt_log,
605
                                      QUERY_LOG_GENERAL);
606
static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
607
                                         QUERY_LOG_SLOW);
608
/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
609
static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
610
                                          &opt_slow_log, QUERY_LOG_SLOW);
611
sys_var_str sys_var_general_log_path(&vars, "general_log_file", sys_check_log_path,
612
				     sys_update_general_log_path,
613
				     sys_default_general_log_path,
614
				     opt_logname);
615
sys_var_str sys_var_slow_log_path(&vars, "slow_query_log_file", sys_check_log_path,
616
				  sys_update_slow_log_path, 
617
				  sys_default_slow_log_path,
618
				  opt_slow_logname);
619
static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
620
					    &log_output_typelib, 0);
621
622
623
/*
624
  Additional variables (not derived from sys_var class, not accessible as
625
  @@varname in SELECT or SET). Sorted in alphabetical order to facilitate
626
  maintenance - SHOW VARIABLES will sort its output.
627
  TODO: remove this list completely
628
*/
629
630
#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR))
631
static SHOW_VAR fixed_vars[]= {
632
  {"back_log",                (char*) &back_log,                    SHOW_LONG},
633
  {"character_sets_dir",      mysql_charsets_dir,                   SHOW_CHAR},
634
  {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
635
  {"language",                language,                             SHOW_CHAR},
636
#ifdef HAVE_MLOCKALL
637
  {"locked_in_memory",	      (char*) &locked_in_memory,	    SHOW_MY_BOOL},
638
#endif
639
  {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
640
  {"log_error",               (char*) log_error_file,               SHOW_CHAR},
641
  {"lower_case_file_system",  (char*) &lower_case_file_system,      SHOW_MY_BOOL},
642
  {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_INT},
643
  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
644
  {"open_files_limit",	      (char*) &open_files_limit,	    SHOW_LONG},
645
  {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
646
  {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
647
  {"port",                    (char*) &mysqld_port,                 SHOW_INT},
648
  {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
649
  {"skip_external_locking",   (char*) &my_disable_locking,          SHOW_MY_BOOL},
650
  {"skip_networking",         (char*) &opt_disable_networking,      SHOW_BOOL},
651
  {"skip_show_database",      (char*) &opt_skip_show_db,            SHOW_BOOL},
652
  {"thread_stack",            (char*) &my_thread_stack_size,        SHOW_LONG},
653
};
654
655
656
bool sys_var::check(THD *thd, set_var *var)
657
{
658
  var->save_result.ulonglong_value= var->value->val_int();
659
  return 0;
660
}
661
662
bool sys_var_str::check(THD *thd, set_var *var)
663
{
664
  int res;
665
  if (!check_func)
666
    return 0;
667
668
  if ((res=(*check_func)(thd, var)) < 0)
669
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
670
             name, var->value->str_value.ptr());
671
  return res;
672
}
673
674
/*
675
  Functions to check and update variables
676
*/
677
678
679
/*
680
  Update variables 'init_connect, init_slave'.
681
682
  In case of 'DEFAULT' value
683
  (for example: 'set GLOBAL init_connect=DEFAULT')
684
  'var' parameter is NULL pointer.
685
*/
686
687
bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
688
			set_var *var)
689
{
690
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
691
  uint new_length= (var ? var->value->str_value.length() : 0);
692
  if (!old_value)
693
    old_value= (char*) "";
694
  if (!(res= my_strndup(old_value, new_length, MYF(0))))
695
    return 1;
696
  /*
697
    Replace the old value in such a way that the any thread using
698
    the value will work.
699
  */
700
  rw_wrlock(var_mutex);
701
  old_value= var_str->value;
702
  var_str->value= res;
703
  var_str->value_length= new_length;
704
  rw_unlock(var_mutex);
705
  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
706
  return 0;
707
}
708
709
710
static bool sys_update_init_connect(THD *thd, set_var *var)
711
{
712
  return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
713
}
714
715
716
static void sys_default_init_connect(THD* thd, enum_var_type type)
717
{
718
  update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
719
}
720
721
722
static bool sys_update_init_slave(THD *thd, set_var *var)
723
{
724
  return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
725
}
726
727
728
static void sys_default_init_slave(THD* thd, enum_var_type type)
729
{
730
  update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
731
}
732
733
734
/**
735
  If one sets the LOW_PRIORIY UPDATES flag, we also must change the
736
  used lock type.
737
*/
738
739
static void fix_low_priority_updates(THD *thd, enum_var_type type)
740
{
741
  if (type == OPT_GLOBAL)
742
    thr_upgraded_concurrent_insert_lock= 
743
      (global_system_variables.low_priority_updates ?
744
       TL_WRITE_LOW_PRIORITY : TL_WRITE);
745
  else
746
    thd->update_lock_default= (thd->variables.low_priority_updates ?
747
			       TL_WRITE_LOW_PRIORITY : TL_WRITE);
748
}
749
750
751
static void
752
fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
753
{
754
  myisam_max_temp_length=
755
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
756
}
757
758
/**
759
  Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
760
*/
761
762
static void fix_max_join_size(THD *thd, enum_var_type type)
763
{
764
  if (type != OPT_GLOBAL)
765
  {
766
    if (thd->variables.max_join_size == HA_POS_ERROR)
767
      thd->options|= OPTION_BIG_SELECTS;
768
    else
769
      thd->options&= ~OPTION_BIG_SELECTS;
770
  }
771
}
772
773
774
/**
775
  Can't change the 'next' tx_isolation while we are already in
776
  a transaction
777
*/
778
static int check_tx_isolation(THD *thd, set_var *var)
779
{
780
  if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
781
  {
782
    my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
783
    return 1;
784
  }
785
  return 0;
786
}
787
788
/*
789
  If one doesn't use the SESSION modifier, the isolation level
790
  is only active for the next command.
791
*/
792
static void fix_tx_isolation(THD *thd, enum_var_type type)
793
{
794
  if (type == OPT_SESSION)
795
    thd->session_tx_isolation= ((enum_tx_isolation)
796
				thd->variables.tx_isolation);
797
}
798
799
static void fix_completion_type(THD *thd __attribute__((unused)),
800
				enum_var_type type __attribute__((unused))) {}
801
802
static int check_completion_type(THD *thd, set_var *var)
803
{
804
  longlong val= var->value->val_int();
805
  if (val < 0 || val > 2)
806
  {
807
    char buf[64];
808
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
809
    return 1;
810
  }
811
  return 0;
812
}
813
814
815
/*
816
  If we are changing the thread variable, we have to copy it to NET too
817
*/
818
819
#ifdef HAVE_REPLICATION
820
static void fix_net_read_timeout(THD *thd, enum_var_type type)
821
{
822
  if (type != OPT_GLOBAL)
823
    my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
824
}
825
826
827
static void fix_net_write_timeout(THD *thd, enum_var_type type)
828
{
829
  if (type != OPT_GLOBAL)
830
    my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
831
}
832
833
static void fix_net_retry_count(THD *thd, enum_var_type type)
834
{
835
  if (type != OPT_GLOBAL)
836
    thd->net.retry_count=thd->variables.net_retry_count;
837
}
838
#else /* HAVE_REPLICATION */
839
static void fix_net_read_timeout(THD *thd __attribute__((unused)),
840
				 enum_var_type type __attribute__((unused)))
841
{}
842
static void fix_net_write_timeout(THD *thd __attribute__((unused)),
843
				  enum_var_type type __attribute__((unused)))
844
{}
845
static void fix_net_retry_count(THD *thd __attribute__((unused)),
846
				enum_var_type type __attribute__((unused)))
847
{}
848
#endif /* HAVE_REPLICATION */
849
850
851
extern void fix_delay_key_write(THD *thd, enum_var_type type)
852
{
853
  switch ((enum_delay_key_write) delay_key_write_options) {
854
  case DELAY_KEY_WRITE_NONE:
855
    myisam_delay_key_write=0;
856
    break;
857
  case DELAY_KEY_WRITE_ON:
858
    myisam_delay_key_write=1;
859
    break;
860
  case DELAY_KEY_WRITE_ALL:
861
    myisam_delay_key_write=1;
862
    ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
863
    break;
864
  }
865
}
866
867
bool sys_var_set::update(THD *thd, set_var *var)
868
{
869
  *value= var->save_result.ulong_value;
870
  return 0;
871
}
872
873
uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
874
                              LEX_STRING *base)
875
{
876
  char buff[256];
877
  String tmp(buff, sizeof(buff), &my_charset_latin1);
878
  ulong length;
879
  ulong val= *value;
880
881
  tmp.length(0);
882
  for (uint i= 0; val; val>>= 1, i++)
883
  {
884
    if (val & 1)
885
    {
886
      tmp.append(enum_names->type_names[i],
887
                 enum_names->type_lengths[i]);
888
      tmp.append(',');
889
    }
890
  }
891
892
  if ((length= tmp.length()))
893
    length--;
894
  return (uchar*) thd->strmake(tmp.ptr(), length);
895
}
896
897
void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
898
{
899
  slave_exec_mode_options= 0;
900
  bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
901
}
902
903
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
904
{
905
  bool rc=  sys_var_set::check(thd, var);
906
  if (!rc &&
907
      bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
908
      bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
909
  {
910
    rc= true;
911
    my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
912
  }
913
  return rc;
914
}
915
916
bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
917
{
918
  bool rc;
919
  pthread_mutex_lock(&LOCK_global_system_variables);
920
  rc= sys_var_set::update(thd, var);
921
  pthread_mutex_unlock(&LOCK_global_system_variables);
922
  return rc;
923
}
924
925
void fix_slave_exec_mode(enum_var_type type)
926
{
927
  DBUG_ENTER("fix_slave_exec_mode");
928
  compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT
929
                      > SLAVE_EXEC_MODE_LAST_BIT - 1);
930
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
931
      bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
932
  {
933
    sql_print_error("Ambiguous slave modes combination."
934
                    " STRICT will be used");
935
    bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
936
  }
937
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
938
    bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
939
}
940
941
bool sys_var_thd_binlog_format::is_readonly() const
942
{
943
  /*
944
    Under certain circumstances, the variable is read-only (unchangeable):
945
  */
946
  THD *thd= current_thd;
947
  /*
948
    If RBR and open temporary tables, their CREATE TABLE may not be in the
949
    binlog, so we can't toggle to SBR in this connection.
950
    The test below will also prevent SET GLOBAL, well it was not easy to test
951
    if global or not here.
952
    And this test will also prevent switching from RBR to RBR (a no-op which
953
    should not happen too often).
954
955
    If we don't have row-based replication compiled in, the variable
956
    is always read-only.
957
  */
958
  if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
959
      thd->temporary_tables)
960
  {
961
    my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
962
    return 1;
963
  }
964
  /*
965
    if in a stored function/trigger, it's too late to change mode
966
  */
967
  if (thd->in_sub_stmt)
968
  {
969
    my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
970
    return 1;    
971
  }
972
  return sys_var_thd_enum::is_readonly();
973
}
974
975
976
void fix_binlog_format_after_update(THD *thd, enum_var_type type)
977
{
978
  thd->reset_current_stmt_binlog_row_based();
979
}
980
981
982
static void fix_max_binlog_size(THD *thd, enum_var_type type)
983
{
984
  DBUG_ENTER("fix_max_binlog_size");
985
  DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
986
                     max_binlog_size, max_relay_log_size));
987
  mysql_bin_log.set_max_size(max_binlog_size);
988
#ifdef HAVE_REPLICATION
989
  if (!max_relay_log_size)
990
    active_mi->rli.relay_log.set_max_size(max_binlog_size);
991
#endif
992
  DBUG_VOID_RETURN;
993
}
994
995
static void fix_max_relay_log_size(THD *thd, enum_var_type type)
996
{
997
  DBUG_ENTER("fix_max_relay_log_size");
998
  DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
999
                     max_binlog_size, max_relay_log_size));
1000
#ifdef HAVE_REPLICATION
1001
  active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
1002
                                        max_relay_log_size: max_binlog_size);
1003
#endif
1004
  DBUG_VOID_RETURN;
1005
}
1006
1007
static void fix_max_connections(THD *thd, enum_var_type type)
1008
{
1009
  resize_thr_alarm(max_connections +  10);
1010
}
1011
1012
1013
static void fix_thd_mem_root(THD *thd, enum_var_type type)
1014
{
1015
  if (type != OPT_GLOBAL)
1016
    reset_root_defaults(thd->mem_root,
1017
                        thd->variables.query_alloc_block_size,
1018
                        thd->variables.query_prealloc_size);
1019
}
1020
1021
1022
static void fix_trans_mem_root(THD *thd, enum_var_type type)
1023
{
1024
  if (type != OPT_GLOBAL)
1025
    reset_root_defaults(&thd->transaction.mem_root,
1026
                        thd->variables.trans_alloc_block_size,
1027
                        thd->variables.trans_prealloc_size);
1028
}
1029
1030
1031
static void fix_server_id(THD *thd, enum_var_type type)
1032
{
1033
  server_id_supplied = 1;
1034
  thd->server_id= server_id;
1035
}
1036
1037
1038
bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
1039
                          const char *name, longlong val)
1040
{
1041
  if (fixed)
1042
  {
1043
    char buf[22];
1044
1045
    if (unsignd)
1046
      ullstr((ulonglong) val, buf);
1047
    else
1048
      llstr(val, buf);
1049
1050
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1051
                        ER_TRUNCATED_WRONG_VALUE,
1052
                        ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
1053
  }
1054
  return FALSE;
1055
}
1056
1057
static ulonglong fix_unsigned(THD *thd, ulonglong num,
1058
                              const struct my_option *option_limits)
1059
{
1060
  my_bool fixed= FALSE;
1061
  ulonglong out= getopt_ull_limit_value(num, option_limits, &fixed);
1062
1063
  throw_bounds_warning(thd, fixed, TRUE, option_limits->name, (longlong) num);
1064
  return out;
1065
}
1066
1067
static bool get_unsigned(THD *thd, set_var *var)
1068
{
1069
  if (var->value->unsigned_flag)
1070
    var->save_result.ulonglong_value= (ulonglong) var->value->val_int();
1071
  else
1072
  {
1073
    longlong v= var->value->val_int();
1074
    var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v);
1075
  }
1076
  return 0;
1077
}
1078
1079
1080
sys_var_long_ptr::
1081
sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
1082
                 sys_after_update_func after_update_arg)
1083
  :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
1084
                           &LOCK_global_system_variables, after_update_arg)
1085
{}
1086
1087
1088
bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
1089
{
1090
  return get_unsigned(thd, var);
1091
}
1092
1093
bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
1094
{
1095
  ulonglong tmp= var->save_result.ulonglong_value;
1096
  pthread_mutex_lock(guard);
1097
  if (option_limits)
1098
    *value= (ulong) fix_unsigned(thd, tmp, option_limits);
1099
  else
1100
  {
1101
#if SIZEOF_LONG < SIZEOF_LONG_LONG
1102
    /* Avoid overflows on 32 bit systems */
1103
    if (tmp > ULONG_MAX)
1104
    {
1105
      tmp= ULONG_MAX;
1106
      throw_bounds_warning(thd, TRUE, TRUE, name,
1107
                           (longlong) var->save_result.ulonglong_value);
1108
    }
1109
#endif
1110
    *value= (ulong) tmp;
1111
  }
1112
1113
  pthread_mutex_unlock(guard);
1114
  return 0;
1115
}
1116
1117
1118
void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
1119
{
1120
  my_bool not_used;
1121
  pthread_mutex_lock(guard);
1122
  *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
1123
                                         option_limits, &not_used);
1124
  pthread_mutex_unlock(guard);
1125
}
1126
1127
1128
bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
1129
{
1130
  ulonglong tmp= var->save_result.ulonglong_value;
1131
  pthread_mutex_lock(&LOCK_global_system_variables);
1132
  if (option_limits)
1133
    *value= (ulonglong) fix_unsigned(thd, tmp, option_limits);
1134
  else
1135
    *value= (ulonglong) tmp;
1136
  pthread_mutex_unlock(&LOCK_global_system_variables);
1137
  return 0;
1138
}
1139
1140
1141
void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
1142
{
1143
  my_bool not_used;
1144
  pthread_mutex_lock(&LOCK_global_system_variables);
1145
  *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
1146
                                 option_limits, &not_used);
1147
  pthread_mutex_unlock(&LOCK_global_system_variables);
1148
}
1149
1150
1151
bool sys_var_bool_ptr::update(THD *thd, set_var *var)
1152
{
1153
  *value= (my_bool) var->save_result.ulong_value;
1154
  return 0;
1155
}
1156
1157
1158
void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
1159
{
1160
  *value= (my_bool) option_limits->def_value;
1161
}
1162
1163
1164
bool sys_var_enum::update(THD *thd, set_var *var)
1165
{
1166
  *value= (uint) var->save_result.ulong_value;
1167
  return 0;
1168
}
1169
1170
1171
uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
1172
{
1173
  return (uchar*) enum_names->type_names[*value];
1174
}
1175
1176
1177
uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
1178
                                     LEX_STRING *base)
1179
{
1180
  return (uchar*) enum_names->type_names[global_system_variables.*offset];
1181
}
1182
1183
bool sys_var_thd_ulong::check(THD *thd, set_var *var)
1184
{
1185
  return (get_unsigned(thd, var) ||
1186
          (check_func && (*check_func)(thd, var)));
1187
}
1188
1189
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
1190
{
1191
  ulonglong tmp= var->save_result.ulonglong_value;
1192
1193
  /* Don't use bigger value than given with --maximum-variable-name=.. */
1194
  if ((ulong) tmp > max_system_variables.*offset)
1195
  {
1196
    throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) tmp);
1197
    tmp= max_system_variables.*offset;
1198
  }
1199
1200
  if (option_limits)
1201
    tmp= (ulong) fix_unsigned(thd, tmp, option_limits);
1202
#if SIZEOF_LONG < SIZEOF_LONG_LONG
1203
  else if (tmp > ULONG_MAX)
1204
  {
1205
    tmp= ULONG_MAX;
1206
    throw_bounds_warning(thd, TRUE, TRUE, name, (longlong) var->save_result.ulonglong_value);
1207
  }
1208
#endif
1209
1210
  if (var->type == OPT_GLOBAL)
1211
    global_system_variables.*offset= (ulong) tmp;
1212
  else
1213
    thd->variables.*offset= (ulong) tmp;
1214
1215
  return 0;
1216
}
1217
1218
1219
void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
1220
{
1221
  if (type == OPT_GLOBAL)
1222
  {
1223
    my_bool not_used;
1224
    /* We will not come here if option_limits is not set */
1225
    global_system_variables.*offset=
1226
      (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
1227
                                     option_limits, &not_used);
1228
  }
1229
  else
1230
    thd->variables.*offset= global_system_variables.*offset;
1231
}
1232
1233
1234
uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
1235
				   LEX_STRING *base)
1236
{
1237
  if (type == OPT_GLOBAL)
1238
    return (uchar*) &(global_system_variables.*offset);
1239
  return (uchar*) &(thd->variables.*offset);
1240
}
1241
1242
1243
bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
1244
{
1245
  ulonglong tmp= var->save_result.ulonglong_value;
1246
1247
  /* Don't use bigger value than given with --maximum-variable-name=.. */
1248
  if ((ha_rows) tmp > max_system_variables.*offset)
1249
    tmp= max_system_variables.*offset;
1250
1251
  if (option_limits)
1252
    tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits);
1253
  if (var->type == OPT_GLOBAL)
1254
  {
1255
    /* Lock is needed to make things safe on 32 bit systems */
1256
    pthread_mutex_lock(&LOCK_global_system_variables);    
1257
    global_system_variables.*offset= (ha_rows) tmp;
1258
    pthread_mutex_unlock(&LOCK_global_system_variables);
1259
  }
1260
  else
1261
    thd->variables.*offset= (ha_rows) tmp;
1262
  return 0;
1263
}
1264
1265
1266
void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
1267
{
1268
  if (type == OPT_GLOBAL)
1269
  {
1270
    my_bool not_used;
1271
    /* We will not come here if option_limits is not set */
1272
    pthread_mutex_lock(&LOCK_global_system_variables);
1273
    global_system_variables.*offset=
1274
      (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
1275
                                       option_limits, &not_used);
1276
    pthread_mutex_unlock(&LOCK_global_system_variables);
1277
  }
1278
  else
1279
    thd->variables.*offset= global_system_variables.*offset;
1280
}
1281
1282
1283
uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
1284
				     LEX_STRING *base)
1285
{
1286
  if (type == OPT_GLOBAL)
1287
    return (uchar*) &(global_system_variables.*offset);
1288
  return (uchar*) &(thd->variables.*offset);
1289
}
1290
1291
bool sys_var_thd_ulonglong::check(THD *thd, set_var *var)
1292
{
1293
  return get_unsigned(thd, var);
1294
}
1295
1296
bool sys_var_thd_ulonglong::update(THD *thd,  set_var *var)
1297
{
1298
  ulonglong tmp= var->save_result.ulonglong_value;
1299
1300
  if (tmp > max_system_variables.*offset)
1301
    tmp= max_system_variables.*offset;
1302
1303
  if (option_limits)
1304
    tmp= fix_unsigned(thd, tmp, option_limits);
1305
  if (var->type == OPT_GLOBAL)
1306
  {
1307
    /* Lock is needed to make things safe on 32 bit systems */
1308
    pthread_mutex_lock(&LOCK_global_system_variables);
1309
    global_system_variables.*offset= (ulonglong) tmp;
1310
    pthread_mutex_unlock(&LOCK_global_system_variables);
1311
  }
1312
  else
1313
    thd->variables.*offset= (ulonglong) tmp;
1314
  return 0;
1315
}
1316
1317
1318
void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
1319
{
1320
  if (type == OPT_GLOBAL)
1321
  {
1322
    my_bool not_used;
1323
    pthread_mutex_lock(&LOCK_global_system_variables);
1324
    global_system_variables.*offset=
1325
      getopt_ull_limit_value((ulonglong) option_limits->def_value,
1326
                             option_limits, &not_used);
1327
    pthread_mutex_unlock(&LOCK_global_system_variables);
1328
  }
1329
  else
1330
    thd->variables.*offset= global_system_variables.*offset;
1331
}
1332
1333
1334
uchar *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type,
1335
				       LEX_STRING *base)
1336
{
1337
  if (type == OPT_GLOBAL)
1338
    return (uchar*) &(global_system_variables.*offset);
1339
  return (uchar*) &(thd->variables.*offset);
1340
}
1341
1342
1343
bool sys_var_thd_bool::update(THD *thd,  set_var *var)
1344
{
1345
  if (var->type == OPT_GLOBAL)
1346
    global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
1347
  else
1348
    thd->variables.*offset= (my_bool) var->save_result.ulong_value;
1349
  return 0;
1350
}
1351
1352
1353
void sys_var_thd_bool::set_default(THD *thd,  enum_var_type type)
1354
{
1355
  if (type == OPT_GLOBAL)
1356
    global_system_variables.*offset= (my_bool) option_limits->def_value;
1357
  else
1358
    thd->variables.*offset= global_system_variables.*offset;
1359
}
1360
1361
1362
uchar *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
1363
				  LEX_STRING *base)
1364
{
1365
  if (type == OPT_GLOBAL)
1366
    return (uchar*) &(global_system_variables.*offset);
1367
  return (uchar*) &(thd->variables.*offset);
1368
}
1369
1370
1371
bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
1372
{
1373
  char buff[STRING_BUFFER_USUAL_SIZE];
1374
  const char *value;
1375
  String str(buff, sizeof(buff), system_charset_info), *res;
1376
1377
  if (var->value->result_type() == STRING_RESULT)
1378
  {
1379
    if (!(res=var->value->val_str(&str)) ||
1380
	((long) (var->save_result.ulong_value=
1381
		 (ulong) find_type(enum_names, res->ptr(),
1382
				   res->length(),1)-1)) < 0)
1383
    {
1384
      value= res ? res->c_ptr() : "NULL";
1385
      goto err;
1386
    }
1387
  }
1388
  else
1389
  {
1390
    ulonglong tmp=var->value->val_int();
1391
    if (tmp >= enum_names->count)
1392
    {
1393
      llstr(tmp,buff);
1394
      value=buff;				// Wrong value is here
1395
      goto err;
1396
    }
1397
    var->save_result.ulong_value= (ulong) tmp;	// Save for update
1398
  }
1399
  return 0;
1400
1401
err:
1402
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
1403
  return 1;
1404
}
1405
1406
1407
bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
1408
{
1409
  bool not_used;
1410
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
1411
  uint error_len= 0;
1412
  String str(buff, sizeof(buff), system_charset_info), *res;
1413
1414
  if (var->value->result_type() == STRING_RESULT)
1415
  {
1416
    if (!(res= var->value->val_str(&str)))
1417
    {
1418
      strmov(buff, "NULL");
1419
      goto err;
1420
    }
1421
1422
    if (!m_allow_empty_value &&
1423
        res->length() == 0)
1424
    {
1425
      buff[0]= 0;
1426
      goto err;
1427
    }
1428
1429
    var->save_result.ulong_value= ((ulong)
1430
				   find_set(enum_names, res->c_ptr(),
1431
					    res->length(),
1432
                                            NULL,
1433
                                            &error, &error_len,
1434
					    &not_used));
1435
    if (error_len)
1436
    {
1437
      strmake(buff, error, min(sizeof(buff) - 1, error_len));
1438
      goto err;
1439
    }
1440
  }
1441
  else
1442
  {
1443
    ulonglong tmp= var->value->val_int();
1444
1445
    if (!m_allow_empty_value &&
1446
        tmp == 0)
1447
    {
1448
      buff[0]= '0';
1449
      buff[1]= 0;
1450
      goto err;
1451
    }
1452
1453
    /*
1454
      For when the enum is made to contain 64 elements, as 1ULL<<64 is
1455
      undefined, we guard with a "count<64" test.
1456
    */
80.1.1 by Brian Aker
LL() cleanup
1457
    if (unlikely((tmp >= ((1ULL) << enum_names->count)) &&
1 by brian
clean slate
1458
                 (enum_names->count < 64)))
1459
    {
1460
      llstr(tmp, buff);
1461
      goto err;
1462
    }
1463
    var->save_result.ulong_value= (ulong) tmp;  // Save for update
1464
  }
1465
  return 0;
1466
1467
err:
1468
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
1469
  return 1;
1470
}
1471
1472
1473
/**
1474
  Return an Item for a variable.
1475
1476
  Used with @@[global.]variable_name.
1477
1478
  If type is not given, return local value if exists, else global.
1479
*/
1480
1481
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
1482
{
1483
  if (check_type(var_type))
1484
  {
1485
    if (var_type != OPT_DEFAULT)
1486
    {
1487
      my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
1488
               name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
1489
      return 0;
1490
    }
1491
    /* As there was no local variable, return the global value */
1492
    var_type= OPT_GLOBAL;
1493
  }
1494
  switch (show_type()) {
1495
  case SHOW_INT:
1496
  {
1497
    uint value;
1498
    pthread_mutex_lock(&LOCK_global_system_variables);
1499
    value= *(uint*) value_ptr(thd, var_type, base);
1500
    pthread_mutex_unlock(&LOCK_global_system_variables);
1501
    return new Item_uint((ulonglong) value);
1502
  }
1503
  case SHOW_LONG:
1504
  {
1505
    ulong value;
1506
    pthread_mutex_lock(&LOCK_global_system_variables);
1507
    value= *(ulong*) value_ptr(thd, var_type, base);
1508
    pthread_mutex_unlock(&LOCK_global_system_variables);
1509
    return new Item_uint((ulonglong) value);
1510
  }
1511
  case SHOW_LONGLONG:
1512
  {
1513
    longlong value;
1514
    pthread_mutex_lock(&LOCK_global_system_variables);
1515
    value= *(longlong*) value_ptr(thd, var_type, base);
1516
    pthread_mutex_unlock(&LOCK_global_system_variables);
1517
    return new Item_int(value);
1518
  }
1519
  case SHOW_DOUBLE:
1520
  {
1521
    double value;
1522
    pthread_mutex_lock(&LOCK_global_system_variables);
1523
    value= *(double*) value_ptr(thd, var_type, base);
1524
    pthread_mutex_unlock(&LOCK_global_system_variables);
1525
    /* 6, as this is for now only used with microseconds */
1526
    return new Item_float(value, 6);
1527
  }
1528
  case SHOW_HA_ROWS:
1529
  {
1530
    ha_rows value;
1531
    pthread_mutex_lock(&LOCK_global_system_variables);
1532
    value= *(ha_rows*) value_ptr(thd, var_type, base);
1533
    pthread_mutex_unlock(&LOCK_global_system_variables);
1534
    return new Item_int((ulonglong) value);
1535
  }
1536
  case SHOW_MY_BOOL:
1537
  {
1538
    int32 value;
1539
    pthread_mutex_lock(&LOCK_global_system_variables);
1540
    value= *(my_bool*) value_ptr(thd, var_type, base);
1541
    pthread_mutex_unlock(&LOCK_global_system_variables);
1542
    return new Item_int(value,1);
1543
  }
1544
  case SHOW_CHAR_PTR:
1545
  {
1546
    Item *tmp;
1547
    pthread_mutex_lock(&LOCK_global_system_variables);
1548
    char *str= *(char**) value_ptr(thd, var_type, base);
1549
    if (str)
1550
    {
1551
      uint length= strlen(str);
1552
      tmp= new Item_string(thd->strmake(str, length), length,
1553
                           system_charset_info, DERIVATION_SYSCONST);
1554
    }
1555
    else
1556
    {
1557
      tmp= new Item_null();
1558
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
1559
    }
1560
    pthread_mutex_unlock(&LOCK_global_system_variables);
1561
    return tmp;
1562
  }
1563
  case SHOW_CHAR:
1564
  {
1565
    Item *tmp;
1566
    pthread_mutex_lock(&LOCK_global_system_variables);
1567
    char *str= (char*) value_ptr(thd, var_type, base);
1568
    if (str)
1569
      tmp= new Item_string(str, strlen(str),
1570
                           system_charset_info, DERIVATION_SYSCONST);
1571
    else
1572
    {
1573
      tmp= new Item_null();
1574
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
1575
    }
1576
    pthread_mutex_unlock(&LOCK_global_system_variables);
1577
    return tmp;
1578
  }
1579
  default:
1580
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
1581
  }
1582
  return 0;
1583
}
1584
1585
1586
bool sys_var_thd_enum::update(THD *thd, set_var *var)
1587
{
1588
  if (var->type == OPT_GLOBAL)
1589
    global_system_variables.*offset= var->save_result.ulong_value;
1590
  else
1591
    thd->variables.*offset= var->save_result.ulong_value;
1592
  return 0;
1593
}
1594
1595
1596
void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
1597
{
1598
  if (type == OPT_GLOBAL)
1599
    global_system_variables.*offset= (ulong) option_limits->def_value;
1600
  else
1601
    thd->variables.*offset= global_system_variables.*offset;
1602
}
1603
1604
1605
uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
1606
				  LEX_STRING *base)
1607
{
1608
  ulong tmp= ((type == OPT_GLOBAL) ?
1609
	      global_system_variables.*offset :
1610
	      thd->variables.*offset);
1611
  return (uchar*) enum_names->type_names[tmp];
1612
}
1613
1614
bool sys_var_thd_bit::check(THD *thd, set_var *var)
1615
{
1616
  return (check_enum(thd, var, &bool_typelib) ||
1617
          (check_func && (*check_func)(thd, var)));
1618
}
1619
1620
bool sys_var_thd_bit::update(THD *thd, set_var *var)
1621
{
1622
  int res= (*update_func)(thd, var);
1623
  return res;
1624
}
1625
1626
1627
uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
1628
				 LEX_STRING *base)
1629
{
1630
  /*
1631
    If reverse is 0 (default) return 1 if bit is set.
1632
    If reverse is 1, return 0 if bit is set
1633
  */
1634
  thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
1635
				   !reverse : reverse);
1636
  return (uchar*) &thd->sys_var_tmp.my_bool_value;
1637
}
1638
1639
1640
/** Update a date_time format variable based on given value. */
1641
1642
void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
1643
					   DATE_TIME_FORMAT *new_value)
1644
{
1645
  DATE_TIME_FORMAT *old;
1646
  DBUG_ENTER("sys_var_date_time_format::update2");
1647
  DBUG_DUMP("positions", (uchar*) new_value->positions,
1648
	    sizeof(new_value->positions));
1649
1650
  if (type == OPT_GLOBAL)
1651
  {
1652
    pthread_mutex_lock(&LOCK_global_system_variables);
1653
    old= (global_system_variables.*offset);
1654
    (global_system_variables.*offset)= new_value;
1655
    pthread_mutex_unlock(&LOCK_global_system_variables);
1656
  }
1657
  else
1658
  {
1659
    old= (thd->variables.*offset);
1660
    (thd->variables.*offset)= new_value;
1661
  }
1662
  my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR));
1663
  DBUG_VOID_RETURN;
1664
}
1665
1666
1667
bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
1668
{
1669
  DATE_TIME_FORMAT *new_value;
1670
  /* We must make a copy of the last value to get it into normal memory */
1671
  new_value= date_time_format_copy((THD*) 0,
1672
				   var->save_result.date_time_format);
1673
  if (!new_value)
1674
    return 1;					// Out of memory
1675
  update2(thd, var->type, new_value);		// Can't fail
1676
  return 0;
1677
}
1678
1679
1680
bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
1681
{
1682
  char buff[STRING_BUFFER_USUAL_SIZE];
1683
  String str(buff,sizeof(buff), system_charset_info), *res;
1684
  DATE_TIME_FORMAT *format;
1685
1686
  if (!(res=var->value->val_str(&str)))
1687
    res= &my_empty_string;
1688
1689
  if (!(format= date_time_format_make(date_time_type,
1690
				      res->ptr(), res->length())))
1691
  {
1692
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
1693
    return 1;
1694
  }
1695
  
1696
  /*
1697
    We must copy result to thread space to not get a memory leak if
1698
    update is aborted
1699
  */
1700
  var->save_result.date_time_format= date_time_format_copy(thd, format);
1701
  my_free((char*) format, MYF(0));
1702
  return var->save_result.date_time_format == 0;
1703
}
1704
1705
1706
void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type)
1707
{
1708
  DATE_TIME_FORMAT *res= 0;
1709
1710
  if (type == OPT_GLOBAL)
1711
  {
1712
    const char *format;
1713
    if ((format= opt_date_time_formats[date_time_type]))
1714
      res= date_time_format_make(date_time_type, format, strlen(format));
1715
  }
1716
  else
1717
  {
1718
    /* Make copy with malloc */
1719
    res= date_time_format_copy((THD *) 0, global_system_variables.*offset);
1720
  }
1721
1722
  if (res)					// Should always be true
1723
    update2(thd, type, res);
1724
}
1725
1726
1727
uchar *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type,
1728
					      LEX_STRING *base)
1729
{
1730
  if (type == OPT_GLOBAL)
1731
  {
1732
    char *res;
1733
    /*
1734
      We do a copy here just to be sure things will work even if someone
1735
      is modifying the original string while the copy is accessed
1736
      (Can't happen now in SQL SHOW, but this is a good safety for the future)
1737
    */
1738
    res= thd->strmake((global_system_variables.*offset)->format.str,
1739
		      (global_system_variables.*offset)->format.length);
1740
    return (uchar*) res;
1741
  }
1742
  return (uchar*) (thd->variables.*offset)->format.str;
1743
}
1744
1745
1746
typedef struct old_names_map_st
1747
{
1748
  const char *old_name;
1749
  const char *new_name;
1750
} my_old_conv;
1751
1752
static my_old_conv old_conv[]= 
1753
{
1754
  {	"cp1251_koi8"		,	"cp1251"	},
1755
  {	"cp1250_latin2"		,	"cp1250"	},
1756
  {	"kam_latin2"		,	"keybcs2"	},
1757
  {	"mac_latin2"		,	"MacRoman"	},
1758
  {	"macce_latin2"		,	"MacCE"		},
1759
  {	"pc2_latin2"		,	"pclatin2"	},
1760
  {	"vga_latin2"		,	"pclatin1"	},
1761
  {	"koi8_cp1251"		,	"koi8r"		},
1762
  {	"win1251ukr_koi8_ukr"	,	"win1251ukr"	},
1763
  {	"koi8_ukr_win1251ukr"	,	"koi8u"		},
1764
  {	NULL			,	NULL		}
1765
};
1766
1767
CHARSET_INFO *get_old_charset_by_name(const char *name)
1768
{
1769
  my_old_conv *conv;
1770
 
1771
  for (conv= old_conv; conv->old_name; conv++)
1772
  {
1773
    if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
1774
      return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0));
1775
  }
1776
  return NULL;
1777
}
1778
1779
1780
bool sys_var_collation::check(THD *thd, set_var *var)
1781
{
1782
  CHARSET_INFO *tmp;
1783
1784
  if (var->value->result_type() == STRING_RESULT)
1785
  {
1786
    char buff[STRING_BUFFER_USUAL_SIZE];
1787
    String str(buff,sizeof(buff), system_charset_info), *res;
1788
    if (!(res=var->value->val_str(&str)))
1789
    {
1790
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1791
      return 1;
1792
    }
1793
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
1794
    {
1795
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1796
      return 1;
1797
    }
1798
  }
1799
  else // INT_RESULT
1800
  {
1801
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1802
    {
1803
      char buf[20];
1804
      int10_to_str((int) var->value->val_int(), buf, -10);
1805
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1806
      return 1;
1807
    }
1808
  }
1809
  var->save_result.charset= tmp;	// Save for update
1810
  return 0;
1811
}
1812
1813
1814
bool sys_var_character_set::check(THD *thd, set_var *var)
1815
{
1816
  CHARSET_INFO *tmp;
1817
1818
  if (var->value->result_type() == STRING_RESULT)
1819
  {
1820
    char buff[STRING_BUFFER_USUAL_SIZE];
1821
    String str(buff,sizeof(buff), system_charset_info), *res;
1822
    if (!(res=var->value->val_str(&str)))
1823
    {
1824
      if (!nullable)
1825
      {
1826
        my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1827
        return 1;
1828
      }
1829
      tmp= NULL;
1830
    }
1831
    else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
1832
             !(tmp=get_old_charset_by_name(res->c_ptr())))
1833
    {
1834
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
1835
      return 1;
1836
    }
1837
  }
1838
  else // INT_RESULT
1839
  {
1840
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1841
    {
1842
      char buf[20];
1843
      int10_to_str((int) var->value->val_int(), buf, -10);
1844
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
1845
      return 1;
1846
    }
1847
  }
1848
  var->save_result.charset= tmp;	// Save for update
1849
  return 0;
1850
}
1851
1852
1853
bool sys_var_character_set::update(THD *thd, set_var *var)
1854
{
1855
  ci_ptr(thd,var->type)[0]= var->save_result.charset;
1856
  thd->update_charset();
1857
  return 0;
1858
}
1859
1860
1861
uchar *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
1862
				       LEX_STRING *base)
1863
{
1864
  CHARSET_INFO *cs= ci_ptr(thd,type)[0];
1865
  return cs ? (uchar*) cs->csname : (uchar*) NULL;
1866
}
1867
1868
1869
void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
1870
{
1871
  if (type == OPT_GLOBAL)
1872
    global_system_variables.*offset= *global_default;
1873
  else
1874
  {
1875
    thd->variables.*offset= global_system_variables.*offset;
1876
    thd->update_charset();
1877
  }
1878
}
1879
CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
1880
{
1881
  if (type == OPT_GLOBAL)
1882
    return &(global_system_variables.*offset);
1883
  else
1884
    return &(thd->variables.*offset);
1885
}
1886
1887
1888
bool sys_var_character_set_client::check(THD *thd, set_var *var)
1889
{
1890
  if (sys_var_character_set_sv::check(thd, var))
1891
    return 1;
1892
  /* Currently, UCS-2 cannot be used as a client character set */
1893
  if (var->save_result.charset->mbminlen > 1)
1894
  {
1895
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, 
1896
             var->save_result.charset->csname);
1897
    return 1;
1898
  }
1899
  return 0;
1900
}
1901
1902
1903
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
1904
						       enum_var_type type)
1905
{
1906
  if (type == OPT_GLOBAL)
1907
    return &global_system_variables.collation_database;
1908
  else
1909
    return &thd->variables.collation_database;
1910
}
1911
1912
1913
void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
1914
{
1915
 if (type == OPT_GLOBAL)
1916
    global_system_variables.collation_database= default_charset_info;
1917
  else
1918
  {
1919
    thd->variables.collation_database= thd->db_charset;
1920
    thd->update_charset();
1921
  }
1922
}
1923
1924
1925
bool sys_var_collation_sv::update(THD *thd, set_var *var)
1926
{
1927
  if (var->type == OPT_GLOBAL)
1928
    global_system_variables.*offset= var->save_result.charset;
1929
  else
1930
  {
1931
    thd->variables.*offset= var->save_result.charset;
1932
    thd->update_charset();
1933
  }
1934
  return 0;
1935
}
1936
1937
1938
void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
1939
{
1940
  if (type == OPT_GLOBAL)
1941
    global_system_variables.*offset= *global_default;
1942
  else
1943
  {
1944
    thd->variables.*offset= global_system_variables.*offset;
1945
    thd->update_charset();
1946
  }
1947
}
1948
1949
1950
uchar *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type,
1951
                                       LEX_STRING *base)
1952
{
1953
  CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
1954
		     global_system_variables.*offset : thd->variables.*offset);
1955
  return cs ? (uchar*) cs->name : (uchar*) "NULL";
1956
}
1957
1958
1959
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
1960
1961
static KEY_CACHE zero_key_cache;
1962
1963
KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
1964
{
1965
  safe_mutex_assert_owner(&LOCK_global_system_variables);
1966
  if (!cache_name || ! cache_name->length)
1967
    cache_name= &default_key_cache_base;
1968
  return ((KEY_CACHE*) find_named(&key_caches,
1969
                                      cache_name->str, cache_name->length, 0));
1970
}
1971
1972
1973
uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
1974
					 LEX_STRING *base)
1975
{
1976
  KEY_CACHE *key_cache= get_key_cache(base);
1977
  if (!key_cache)
1978
    key_cache= &zero_key_cache;
1979
  return (uchar*) key_cache + offset ;
1980
}
1981
1982
1983
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
1984
{
1985
  ulonglong tmp= var->save_result.ulonglong_value;
1986
  LEX_STRING *base_name= &var->base;
1987
  KEY_CACHE *key_cache;
1988
  bool error= 0;
1989
1990
  /* If no basename, assume it's for the key cache named 'default' */
1991
  if (!base_name->length)
1992
    base_name= &default_key_cache_base;
1993
1994
  pthread_mutex_lock(&LOCK_global_system_variables);
1995
  key_cache= get_key_cache(base_name);
1996
                            
1997
  if (!key_cache)
1998
  {
1999
    /* Key cache didn't exists */
2000
    if (!tmp)					// Tried to delete cache
2001
      goto end;					// Ok, nothing to do
2002
    if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
2003
    {
2004
      error= 1;
2005
      goto end;
2006
    }
2007
  }
2008
2009
  /*
2010
    Abort if some other thread is changing the key cache
2011
    TODO: This should be changed so that we wait until the previous
2012
    assignment is done and then do the new assign
2013
  */
2014
  if (key_cache->in_init)
2015
    goto end;
2016
2017
  if (!tmp)					// Zero size means delete
2018
  {
2019
    if (key_cache == dflt_key_cache)
2020
    {
2021
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2022
                          ER_WARN_CANT_DROP_DEFAULT_KEYCACHE,
2023
                          ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE));
2024
      goto end;					// Ignore default key cache
2025
    }
2026
2027
    if (key_cache->key_cache_inited)		// If initied
2028
    {
2029
      /*
2030
	Move tables using this key cache to the default key cache
2031
	and clear the old key cache.
2032
      */
2033
      NAMED_LIST *list; 
2034
      key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
2035
					      base_name->length, &list);
2036
      key_cache->in_init= 1;
2037
      pthread_mutex_unlock(&LOCK_global_system_variables);
2038
      error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
2039
      pthread_mutex_lock(&LOCK_global_system_variables);
2040
      key_cache->in_init= 0;
2041
    }
2042
    /*
2043
      We don't delete the key cache as some running threads my still be
2044
      in the key cache code with a pointer to the deleted (empty) key cache
2045
    */
2046
    goto end;
2047
  }
2048
2049
  key_cache->param_buff_size=
2050
    (ulonglong) fix_unsigned(thd, tmp, option_limits);
2051
2052
  /* If key cache didn't existed initialize it, else resize it */
2053
  key_cache->in_init= 1;
2054
  pthread_mutex_unlock(&LOCK_global_system_variables);
2055
2056
  if (!key_cache->key_cache_inited)
2057
    error= (bool) (ha_init_key_cache("", key_cache));
2058
  else
2059
    error= (bool)(ha_resize_key_cache(key_cache));
2060
2061
  pthread_mutex_lock(&LOCK_global_system_variables);
2062
  key_cache->in_init= 0;  
2063
2064
end:
2065
  pthread_mutex_unlock(&LOCK_global_system_variables);
2066
  return error;
2067
}
2068
2069
2070
/**
2071
  @todo
2072
  Abort if some other thread is changing the key cache.
2073
  This should be changed so that we wait until the previous
2074
  assignment is done and then do the new assign
2075
*/
2076
bool sys_var_key_cache_long::update(THD *thd, set_var *var)
2077
{
2078
  ulong tmp= (ulong) var->value->val_int();
2079
  LEX_STRING *base_name= &var->base;
2080
  bool error= 0;
2081
2082
  if (!base_name->length)
2083
    base_name= &default_key_cache_base;
2084
2085
  pthread_mutex_lock(&LOCK_global_system_variables);
2086
  KEY_CACHE *key_cache= get_key_cache(base_name);
2087
2088
  if (!key_cache && !(key_cache= create_key_cache(base_name->str,
2089
				                  base_name->length)))
2090
  {
2091
    error= 1;
2092
    goto end;
2093
  }
2094
2095
  /*
2096
    Abort if some other thread is changing the key cache
2097
    TODO: This should be changed so that we wait until the previous
2098
    assignment is done and then do the new assign
2099
  */
2100
  if (key_cache->in_init)
2101
    goto end;
2102
2103
  *((ulong*) (((char*) key_cache) + offset))=
2104
    (ulong) fix_unsigned(thd, tmp, option_limits);
2105
2106
  /*
2107
    Don't create a new key cache if it didn't exist
2108
    (key_caches are created only when the user sets block_size)
2109
  */
2110
  key_cache->in_init= 1;
2111
2112
  pthread_mutex_unlock(&LOCK_global_system_variables);
2113
2114
  error= (bool) (ha_resize_key_cache(key_cache));
2115
2116
  pthread_mutex_lock(&LOCK_global_system_variables);
2117
  key_cache->in_init= 0;  
2118
2119
end:
2120
  pthread_mutex_unlock(&LOCK_global_system_variables);
2121
  return error;
2122
}
2123
2124
2125
bool sys_var_log_state::update(THD *thd, set_var *var)
2126
{
2127
  bool res;
2128
  pthread_mutex_lock(&LOCK_global_system_variables);
2129
  if (!var->save_result.ulong_value)
2130
  {
2131
    logger.deactivate_log_handler(thd, log_type);
2132
    res= false;
2133
  }
2134
  else
2135
    res= logger.activate_log_handler(thd, log_type);
2136
  pthread_mutex_unlock(&LOCK_global_system_variables);
2137
  return res;
2138
}
2139
2140
void sys_var_log_state::set_default(THD *thd, enum_var_type type)
2141
{
2142
  pthread_mutex_lock(&LOCK_global_system_variables);
2143
  logger.deactivate_log_handler(thd, log_type);
2144
  pthread_mutex_unlock(&LOCK_global_system_variables);
2145
}
2146
2147
2148
static int  sys_check_log_path(THD *thd,  set_var *var)
2149
{
2150
  char path[FN_REFLEN], buff[FN_REFLEN];
15 by brian
Fix for stat, NETWARE removal
2151
  struct stat f_stat;
1 by brian
clean slate
2152
  String str(buff, sizeof(buff), system_charset_info), *res;
2153
  const char *log_file_str;
2154
  size_t path_length;
2155
2156
  if (!(res= var->value->val_str(&str)))
2157
    goto err;
2158
2159
  log_file_str= res->c_ptr();
15 by brian
Fix for stat, NETWARE removal
2160
  bzero(&f_stat, sizeof(struct stat));
1 by brian
clean slate
2161
2162
  path_length= unpack_filename(path, log_file_str);
2163
2164
  if (!path_length)
2165
  {
2166
    /* File name is empty. */
2167
2168
    goto err;
2169
  }
2170
15 by brian
Fix for stat, NETWARE removal
2171
  if (!stat(path, &f_stat))
1 by brian
clean slate
2172
  {
2173
    /*
2174
      A file system object exists. Check if argument is a file and we have
2175
      'write' permission.
2176
    */
2177
2178
    if (!MY_S_ISREG(f_stat.st_mode) ||
2179
        !(f_stat.st_mode & MY_S_IWRITE))
2180
      goto err;
2181
2182
    return 0;
2183
  }
2184
2185
  /* Get dirname of the file path. */
2186
  (void) dirname_part(path, log_file_str, &path_length);
2187
2188
  /* Dirname is empty if file path is relative. */
2189
  if (!path_length)
2190
    return 0;
2191
2192
  /*
2193
    Check if directory exists and we have permission to create file and
2194
    write to file.
2195
  */
2196
  if (my_access(path, (F_OK|W_OK)))
2197
    goto err;
2198
2199
  return 0;
2200
2201
err:
2202
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, 
2203
           res ? log_file_str : "NULL");
2204
  return 1;
2205
}
2206
2207
2208
bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
2209
			     set_var *var, const char *log_ext,
2210
			     bool log_state, uint log_type)
2211
{
2212
  MYSQL_QUERY_LOG *file_log;
2213
  char buff[FN_REFLEN];
2214
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
2215
  bool result= 0;
2216
  uint str_length= (var ? var->value->str_value.length() : 0);
2217
2218
  switch (log_type) {
2219
  case QUERY_LOG_SLOW:
2220
    file_log= logger.get_slow_log_file_handler();
2221
    break;
2222
  case QUERY_LOG_GENERAL:
2223
    file_log= logger.get_log_file_handler();
2224
    break;
2225
  default:
2226
    assert(0);                                  // Impossible
2227
  }
2228
2229
  if (!old_value)
2230
  {
2231
    old_value= make_default_log_name(buff, log_ext);
2232
    str_length= strlen(old_value);
2233
  }
2234
  if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
2235
  {
2236
    result= 1;
2237
    goto err;
2238
  }
2239
2240
  pthread_mutex_lock(&LOCK_global_system_variables);
2241
  logger.lock_exclusive();
2242
2243
  if (file_log && log_state)
2244
    file_log->close(0);
2245
  old_value= var_str->value;
2246
  var_str->value= res;
2247
  var_str->value_length= str_length;
2248
  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
2249
  if (file_log && log_state)
2250
  {
2251
    switch (log_type) {
2252
    case QUERY_LOG_SLOW:
2253
      file_log->open_slow_log(sys_var_slow_log_path.value);
2254
      break;
2255
    case QUERY_LOG_GENERAL:
2256
      file_log->open_query_log(sys_var_general_log_path.value);
2257
      break;
2258
    default:
2259
      DBUG_ASSERT(0);
2260
    }
2261
  }
2262
2263
  logger.unlock();
2264
  pthread_mutex_unlock(&LOCK_global_system_variables);
2265
2266
err:
2267
  return result;
2268
}
2269
2270
2271
static bool sys_update_general_log_path(THD *thd, set_var * var)
2272
{
2273
  return update_sys_var_str_path(thd, &sys_var_general_log_path, 
2274
				 var, ".log", opt_log, QUERY_LOG_GENERAL);
2275
}
2276
2277
2278
static void sys_default_general_log_path(THD *thd, enum_var_type type)
2279
{
2280
  (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
2281
				 0, ".log", opt_log, QUERY_LOG_GENERAL);
2282
}
2283
2284
2285
static bool sys_update_slow_log_path(THD *thd, set_var * var)
2286
{
2287
  return update_sys_var_str_path(thd, &sys_var_slow_log_path,
2288
				 var, "-slow.log", opt_slow_log,
2289
                                 QUERY_LOG_SLOW);
2290
}
2291
2292
2293
static void sys_default_slow_log_path(THD *thd, enum_var_type type)
2294
{
2295
  (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
2296
				 0, "-slow.log", opt_slow_log,
2297
                                 QUERY_LOG_SLOW);
2298
}
2299
2300
2301
bool sys_var_log_output::update(THD *thd, set_var *var)
2302
{
2303
  pthread_mutex_lock(&LOCK_global_system_variables);
2304
  logger.lock_exclusive();
2305
  logger.init_slow_log(var->save_result.ulong_value);
2306
  logger.init_general_log(var->save_result.ulong_value);
2307
  *value= var->save_result.ulong_value;
2308
  logger.unlock();
2309
  pthread_mutex_unlock(&LOCK_global_system_variables);
2310
  return 0;
2311
}
2312
2313
2314
void sys_var_log_output::set_default(THD *thd, enum_var_type type)
2315
{
2316
  pthread_mutex_lock(&LOCK_global_system_variables);
2317
  logger.lock_exclusive();
2318
  logger.init_slow_log(LOG_FILE);
2319
  logger.init_general_log(LOG_FILE);
2320
  *value= LOG_FILE;
2321
  logger.unlock();
2322
  pthread_mutex_unlock(&LOCK_global_system_variables);
2323
}
2324
2325
2326
uchar *sys_var_log_output::value_ptr(THD *thd, enum_var_type type,
2327
                                    LEX_STRING *base)
2328
{
2329
  char buff[256];
2330
  String tmp(buff, sizeof(buff), &my_charset_latin1);
2331
  ulong length;
2332
  ulong val= *value;
2333
2334
  tmp.length(0);
2335
  for (uint i= 0; val; val>>= 1, i++)
2336
  {
2337
    if (val & 1)
2338
    {
2339
      tmp.append(log_output_typelib.type_names[i],
2340
                 log_output_typelib.type_lengths[i]);
2341
      tmp.append(',');
2342
    }
2343
  }
2344
2345
  if ((length= tmp.length()))
2346
    length--;
2347
  return (uchar*) thd->strmake(tmp.ptr(), length);
2348
}
2349
2350
2351
/*****************************************************************************
2352
  Functions to handle SET NAMES and SET CHARACTER SET
2353
*****************************************************************************/
2354
2355
int set_var_collation_client::check(THD *thd)
2356
{
2357
  /* Currently, UCS-2 cannot be used as a client character set */
2358
  if (character_set_client->mbminlen > 1)
2359
  {
2360
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
2361
             character_set_client->csname);
2362
    return 1;
2363
  }
2364
  return 0;
2365
}
2366
2367
int set_var_collation_client::update(THD *thd)
2368
{
2369
  thd->variables.character_set_client= character_set_client;
2370
  thd->variables.character_set_results= character_set_results;
2371
  thd->variables.collation_connection= collation_connection;
2372
  thd->update_charset();
2373
  thd->protocol_text.init(thd);
2374
  return 0;
2375
}
2376
2377
/****************************************************************************/
2378
2379
bool sys_var_timestamp::update(THD *thd,  set_var *var)
2380
{
2381
  thd->set_time((time_t) var->save_result.ulonglong_value);
2382
  return 0;
2383
}
2384
2385
2386
void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
2387
{
2388
  thd->user_time=0;
2389
}
2390
2391
2392
uchar *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
2393
				   LEX_STRING *base)
2394
{
2395
  thd->sys_var_tmp.long_value= (long) thd->start_time;
2396
  return (uchar*) &thd->sys_var_tmp.long_value;
2397
}
2398
2399
2400
bool sys_var_last_insert_id::update(THD *thd, set_var *var)
2401
{
2402
  thd->first_successful_insert_id_in_prev_stmt= 
2403
    var->save_result.ulonglong_value;
2404
  return 0;
2405
}
2406
2407
2408
uchar *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
2409
					LEX_STRING *base)
2410
{
2411
  /*
2412
    this tmp var makes it robust againt change of type of 
2413
    read_first_successful_insert_id_in_prev_stmt().
2414
  */
2415
  thd->sys_var_tmp.ulonglong_value= 
2416
    thd->read_first_successful_insert_id_in_prev_stmt();
2417
  return (uchar*) &thd->sys_var_tmp.ulonglong_value;
2418
}
2419
2420
2421
bool sys_var_insert_id::update(THD *thd, set_var *var)
2422
{
2423
  thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
2424
  return 0;
2425
}
2426
2427
2428
uchar *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
2429
				   LEX_STRING *base)
2430
{
2431
  thd->sys_var_tmp.ulonglong_value= 
2432
    thd->auto_inc_intervals_forced.minimum();
2433
  return (uchar*) &thd->sys_var_tmp.ulonglong_value;
2434
}
2435
2436
2437
bool sys_var_rand_seed1::update(THD *thd, set_var *var)
2438
{
2439
  thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
2440
  return 0;
2441
}
2442
2443
bool sys_var_rand_seed2::update(THD *thd, set_var *var)
2444
{
2445
  thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
2446
  return 0;
2447
}
2448
2449
2450
bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
2451
{
2452
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
2453
  String str(buff, sizeof(buff), &my_charset_latin1);
2454
  String *res= var->value->val_str(&str);
2455
2456
  if (!(var->save_result.time_zone= my_tz_find(thd, res)))
2457
  {
2458
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
2459
    return 1;
2460
  }
2461
  return 0;
2462
}
2463
2464
2465
bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
2466
{
2467
  /* We are using Time_zone object found during check() phase. */
2468
  if (var->type == OPT_GLOBAL)
2469
  {
2470
    pthread_mutex_lock(&LOCK_global_system_variables);
2471
    global_system_variables.time_zone= var->save_result.time_zone;
2472
    pthread_mutex_unlock(&LOCK_global_system_variables);
2473
  }
2474
  else
2475
    thd->variables.time_zone= var->save_result.time_zone;
2476
  return 0;
2477
}
2478
2479
2480
uchar *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
2481
				       LEX_STRING *base)
2482
{
2483
  /* 
2484
    We can use ptr() instead of c_ptr() here because String contaning
2485
    time zone name is guaranteed to be zero ended.
2486
  */
2487
  if (type == OPT_GLOBAL)
2488
    return (uchar *)(global_system_variables.time_zone->get_name()->ptr());
2489
  else
2490
  {
2491
    /*
2492
      This is an ugly fix for replication: we don't replicate properly queries
2493
      invoking system variables' values to update tables; but
2494
      CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
2495
      replicable (i.e. we tell the binlog code to store the session
2496
      timezone). If it's the global value which was used we can't replicate
2497
      (binlog code stores session value only).
2498
    */
2499
    thd->time_zone_used= 1;
2500
    return (uchar *)(thd->variables.time_zone->get_name()->ptr());
2501
  }
2502
}
2503
2504
2505
void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
2506
{
2507
 pthread_mutex_lock(&LOCK_global_system_variables);
2508
 if (type == OPT_GLOBAL)
2509
 {
2510
   if (default_tz_name)
2511
   {
2512
     String str(default_tz_name, &my_charset_latin1);
2513
     /*
2514
       We are guaranteed to find this time zone since its existence
2515
       is checked during start-up.
2516
     */
2517
     global_system_variables.time_zone= my_tz_find(thd, &str);
2518
   }
2519
   else
2520
     global_system_variables.time_zone= my_tz_SYSTEM;
2521
 }
2522
 else
2523
   thd->variables.time_zone= global_system_variables.time_zone;
2524
 pthread_mutex_unlock(&LOCK_global_system_variables);
2525
}
2526
2527
2528
bool sys_var_max_user_conn::check(THD *thd, set_var *var)
2529
{
2530
  if (var->type == OPT_GLOBAL)
2531
    return sys_var_thd::check(thd, var);
2532
  else
2533
  {
2534
    /*
2535
      Per-session values of max_user_connections can't be set directly.
2536
      May be we should have a separate error message for this?
2537
    */
2538
    my_error(ER_GLOBAL_VARIABLE, MYF(0), name);
2539
    return TRUE;
2540
  }
2541
}
2542
2543
bool sys_var_max_user_conn::update(THD *thd, set_var *var)
2544
{
2545
  DBUG_ASSERT(var->type == OPT_GLOBAL);
2546
  pthread_mutex_lock(&LOCK_global_system_variables);
2547
  max_user_connections= (uint)var->save_result.ulonglong_value;
2548
  pthread_mutex_unlock(&LOCK_global_system_variables);
2549
  return 0;
2550
}
2551
2552
2553
void sys_var_max_user_conn::set_default(THD *thd, enum_var_type type)
2554
{
2555
  DBUG_ASSERT(type == OPT_GLOBAL);
2556
  pthread_mutex_lock(&LOCK_global_system_variables);
2557
  max_user_connections= (ulong) option_limits->def_value;
2558
  pthread_mutex_unlock(&LOCK_global_system_variables);
2559
}
2560
2561
2562
uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
2563
                                       LEX_STRING *base)
2564
{
2565
  if (type != OPT_GLOBAL &&
2566
      thd->user_connect && thd->user_connect->user_resources.user_conn)
2567
    return (uchar*) &(thd->user_connect->user_resources.user_conn);
2568
  return (uchar*) &(max_user_connections);
2569
}
2570
2571
2572
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
2573
{
2574
  MY_LOCALE *locale_match;
2575
2576
  if (var->value->result_type() == INT_RESULT)
2577
  {
2578
    if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
2579
    {
2580
      char buf[20];
2581
      int10_to_str((int) var->value->val_int(), buf, -10);
2582
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
2583
      return 1;
2584
    }
2585
  }
2586
  else // STRING_RESULT
2587
  {
2588
    char buff[6]; 
2589
    String str(buff, sizeof(buff), &my_charset_latin1), *res;
2590
    if (!(res=var->value->val_str(&str)))
2591
    {
2592
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
2593
      return 1;
2594
    }
2595
    const char *locale_str= res->c_ptr();
2596
    if (!(locale_match= my_locale_by_name(locale_str)))
2597
    {
2598
      my_printf_error(ER_UNKNOWN_ERROR,
2599
                      "Unknown locale: '%s'", MYF(0), locale_str);
2600
      return 1;
2601
    }
2602
  }
2603
2604
  var->save_result.locale_value= locale_match;
2605
  return 0;
2606
}
2607
2608
2609
bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
2610
{
2611
  if (var->type == OPT_GLOBAL)
2612
    global_system_variables.lc_time_names= var->save_result.locale_value;
2613
  else
2614
    thd->variables.lc_time_names= var->save_result.locale_value;
2615
  return 0;
2616
}
2617
2618
2619
uchar *sys_var_thd_lc_time_names::value_ptr(THD *thd, enum_var_type type,
2620
					  LEX_STRING *base)
2621
{
2622
  return type == OPT_GLOBAL ?
2623
                 (uchar *) global_system_variables.lc_time_names->name :
2624
                 (uchar *) thd->variables.lc_time_names->name;
2625
}
2626
2627
2628
void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
2629
{
2630
  if (type == OPT_GLOBAL)
2631
    global_system_variables.lc_time_names= my_default_lc_time_names;
2632
  else
2633
    thd->variables.lc_time_names= global_system_variables.lc_time_names;
2634
}
2635
2636
/*
2637
  Handling of microseoncds given as seconds.part_seconds
2638
2639
  NOTES
2640
    The argument to long query time is in seconds in decimal
2641
    which is converted to ulonglong integer holding microseconds for storage.
2642
    This is used for handling long_query_time
2643
*/
2644
2645
bool sys_var_microseconds::update(THD *thd, set_var *var)
2646
{
2647
  double num= var->value->val_real();
2648
  longlong microseconds;
2649
  if (num > (double) option_limits->max_value)
2650
    num= (double) option_limits->max_value;
2651
  if (num < (double) option_limits->min_value)
2652
    num= (double) option_limits->min_value;
2653
  microseconds= (longlong) (num * 1000000.0 + 0.5);
2654
  if (var->type == OPT_GLOBAL)
2655
  {
2656
    pthread_mutex_lock(&LOCK_global_system_variables);
2657
    (global_system_variables.*offset)= microseconds;
2658
    pthread_mutex_unlock(&LOCK_global_system_variables);
2659
  }
2660
  else
2661
    thd->variables.*offset= microseconds;
2662
  return 0;
2663
}
2664
2665
2666
void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
2667
{
2668
  longlong microseconds= (longlong) (option_limits->def_value * 1000000.0);
2669
  if (type == OPT_GLOBAL)
2670
  {
2671
    pthread_mutex_lock(&LOCK_global_system_variables);
2672
    global_system_variables.*offset= microseconds;
2673
    pthread_mutex_unlock(&LOCK_global_system_variables);
2674
  }
2675
  else
2676
    thd->variables.*offset= microseconds;
2677
}
2678
2679
2680
uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
2681
                                          LEX_STRING *base)
2682
{
2683
  thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
2684
                                   global_system_variables.*offset :
2685
                                   thd->variables.*offset) / 1000000.0;
2686
  return (uchar*) &thd->tmp_double_value;
2687
}
2688
2689
2690
/*
2691
  Functions to update thd->options bits
2692
*/
2693
2694
static bool set_option_bit(THD *thd, set_var *var)
2695
{
2696
  sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
2697
  if ((var->save_result.ulong_value != 0) == sys_var->reverse)
2698
    thd->options&= ~sys_var->bit_flag;
2699
  else
2700
    thd->options|= sys_var->bit_flag;
2701
  return 0;
2702
}
2703
2704
2705
static bool set_option_autocommit(THD *thd, set_var *var)
2706
{
2707
  /* The test is negative as the flag we use is NOT autocommit */
2708
2709
  ulonglong org_options= thd->options;
2710
2711
  if (var->save_result.ulong_value != 0)
2712
    thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
2713
  else
2714
    thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
2715
2716
  if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
2717
  {
2718
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
2719
    {
2720
      /* We changed to auto_commit mode */
2721
      thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
2722
      thd->transaction.all.modified_non_trans_table= FALSE;
2723
      thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
2724
      if (ha_commit(thd))
2725
	return 1;
2726
    }
2727
    else
2728
    {
2729
      thd->transaction.all.modified_non_trans_table= FALSE;
2730
      thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
2731
    }
2732
  }
2733
  return 0;
2734
}
2735
2736
static int check_log_update(THD *thd, set_var *var)
2737
{
2738
  return 0;
2739
}
2740
2741
static bool set_log_update(THD *thd, set_var *var)
2742
{
2743
  /*
2744
    The update log is not supported anymore since 5.0.
2745
    See sql/mysqld.cc/, comments in function init_server_components() for an
2746
    explaination of the different warnings we send below
2747
  */
2748
2749
  if (opt_sql_bin_update)
2750
  {
2751
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
2752
                 ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
2753
                 ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
2754
  }
2755
  else
2756
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
2757
                 ER_UPDATE_LOG_DEPRECATED_IGNORED,
2758
                 ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
2759
  set_option_bit(thd, var);
2760
  return 0;
2761
}
2762
2763
2764
static int check_pseudo_thread_id(THD *thd, set_var *var)
2765
{
2766
  var->save_result.ulonglong_value= var->value->val_int();
2767
  return 0;
2768
}
2769
2770
static uchar *get_warning_count(THD *thd)
2771
{
2772
  thd->sys_var_tmp.long_value=
2773
    (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
2774
     thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
2775
     thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
2776
  return (uchar*) &thd->sys_var_tmp.long_value;
2777
}
2778
2779
static uchar *get_error_count(THD *thd)
2780
{
2781
  thd->sys_var_tmp.long_value= 
2782
    thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
2783
  return (uchar*) &thd->sys_var_tmp.long_value;
2784
}
2785
2786
2787
/**
2788
  Get the tmpdir that was specified or chosen by default.
2789
2790
  This is necessary because if the user does not specify a temporary
2791
  directory via the command line, one is chosen based on the environment
2792
  or system defaults.  But we can't just always use mysql_tmpdir, because
2793
  that is actually a call to my_tmpdir() which cycles among possible
2794
  temporary directories.
2795
2796
  @param thd		thread handle
2797
2798
  @retval
2799
    ptr		pointer to NUL-terminated string
2800
*/
2801
static uchar *get_tmpdir(THD *thd)
2802
{
2803
  if (opt_mysql_tmpdir)
2804
    return (uchar *)opt_mysql_tmpdir;
2805
  return (uchar*)mysql_tmpdir;
2806
}
2807
2808
/****************************************************************************
2809
  Main handling of variables:
2810
  - Initialisation
2811
  - Searching during parsing
2812
  - Update loop
2813
****************************************************************************/
2814
2815
/**
2816
  Find variable name in option my_getopt structure used for
2817
  command line args.
2818
2819
  @param opt	option structure array to search in
2820
  @param name	variable name
2821
2822
  @retval
2823
    0		Error
2824
  @retval
2825
    ptr		pointer to option structure
2826
*/
2827
2828
static struct my_option *find_option(struct my_option *opt, const char *name) 
2829
{
2830
  uint length=strlen(name);
2831
  for (; opt->name; opt++)
2832
  {
2833
    if (!getopt_compare_strings(opt->name, name, length) &&
2834
	!opt->name[length])
2835
    {
2836
      /*
2837
	Only accept the option if one can set values through it.
2838
	If not, there is no default value or limits in the option.
2839
      */
2840
      return (opt->value) ? opt : 0;
2841
    }
2842
  }
2843
  return 0;
2844
}
2845
2846
2847
/**
2848
  Return variable name and length for hashing of variables.
2849
*/
2850
2851
static uchar *get_sys_var_length(const sys_var *var, size_t *length,
2852
                                 my_bool first)
2853
{
2854
  *length= var->name_length;
2855
  return (uchar*) var->name;
2856
}
2857
2858
2859
/*
2860
  Add variables to the dynamic hash of system variables
2861
  
2862
  SYNOPSIS
2863
    mysql_add_sys_var_chain()
2864
    first       Pointer to first system variable to add
2865
    long_opt    (optional)command line arguments may be tied for limit checks.
2866
  
2867
  RETURN VALUES
2868
    0           SUCCESS
2869
    otherwise   FAILURE
2870
*/
2871
2872
2873
int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
2874
{
2875
  sys_var *var;
2876
  
2877
  /* A write lock should be held on LOCK_system_variables_hash */
2878
  
2879
  for (var= first; var; var= var->next)
2880
  {
2881
    var->name_length= strlen(var->name);
2882
    /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
2883
    if (my_hash_insert(&system_variable_hash, (uchar*) var))
2884
      goto error;
2885
    if (long_options)
2886
      var->option_limits= find_option(long_options, var->name);
2887
  }
2888
  return 0;
2889
2890
error:
2891
  for (; first != var; first= first->next)
2892
    hash_delete(&system_variable_hash, (uchar*) first);
2893
  return 1;
2894
}
2895
 
2896
 
2897
/*
2898
  Remove variables to the dynamic hash of system variables
2899
   
2900
  SYNOPSIS
2901
    mysql_del_sys_var_chain()
2902
    first       Pointer to first system variable to remove
2903
   
2904
  RETURN VALUES
2905
    0           SUCCESS
2906
    otherwise   FAILURE
2907
*/
2908
 
2909
int mysql_del_sys_var_chain(sys_var *first)
2910
{
2911
  int result= 0;
2912
 
2913
  /* A write lock should be held on LOCK_system_variables_hash */
2914
   
2915
  for (sys_var *var= first; var; var= var->next)
2916
    result|= hash_delete(&system_variable_hash, (uchar*) var);
2917
2918
  return result;
2919
}
2920
 
2921
 
2922
static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
2923
{
2924
  return strcmp(a->name, b->name);
2925
}
2926
 
2927
 
2928
/*
2929
  Constructs an array of system variables for display to the user.
2930
  
2931
  SYNOPSIS
2932
    enumerate_sys_vars()
2933
    thd         current thread
2934
    sorted      If TRUE, the system variables should be sorted
2935
  
2936
  RETURN VALUES
2937
    pointer     Array of SHOW_VAR elements for display
2938
    NULL        FAILURE
2939
*/
2940
2941
SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
2942
{
2943
  int count= system_variable_hash.records, i;
2944
  int fixed_count= fixed_show_vars.elements;
2945
  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
2946
  SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size);
2947
2948
  if (result)
2949
  {
2950
    SHOW_VAR *show= result + fixed_count;
2951
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
2952
2953
    for (i= 0; i < count; i++)
2954
    {
2955
      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
2956
      show->name= var->name;
2957
      show->value= (char*) var;
2958
      show->type= SHOW_SYS;
2959
      show++;
2960
    }
2961
2962
    /* sort into order */
2963
    if (sorted)
2964
      my_qsort(result, count + fixed_count, sizeof(SHOW_VAR),
2965
               (qsort_cmp) show_cmp);
2966
    
2967
    /* make last element empty */
2968
    bzero(show, sizeof(SHOW_VAR));
2969
  }
2970
  return result;
2971
}
2972
2973
2974
/*
2975
  Initialize the system variables
2976
  
2977
  SYNOPSIS
2978
    set_var_init()
2979
  
2980
  RETURN VALUES
2981
    0           SUCCESS
2982
    otherwise   FAILURE
2983
*/
2984
2985
int set_var_init()
2986
{
2987
  uint count= 0;
2988
  DBUG_ENTER("set_var_init");
2989
  
2990
  for (sys_var *var=vars.first; var; var= var->next, count++) {};
2991
2992
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR),
2993
                            FIXED_VARS_SIZE + 64, 64))
2994
    goto error;
2995
2996
  fixed_show_vars.elements= FIXED_VARS_SIZE;
2997
  memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
2998
2999
  if (hash_init(&system_variable_hash, system_charset_info, count, 0,
3000
                0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
3001
    goto error;
3002
3003
  vars.last->next= NULL;
3004
  if (mysql_add_sys_var_chain(vars.first, my_long_options))
3005
    goto error;
3006
3007
  /*
3008
    Special cases
3009
    Needed because MySQL can't find the limits for a variable it it has
3010
    a different name than the command line option.
3011
    As these variables are deprecated, this code will disappear soon...
3012
  */
3013
  sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
3014
3015
  DBUG_RETURN(0);
3016
3017
error:
3018
  fprintf(stderr, "failed to initialize system variables");
3019
  DBUG_RETURN(1);
3020
}
3021
3022
3023
void set_var_free()
3024
{
3025
  hash_free(&system_variable_hash);
3026
  delete_dynamic(&fixed_show_vars);
3027
}
3028
3029
3030
/*
3031
  Add elements to the dynamic list of read-only system variables.
3032
  
3033
  SYNOPSIS
3034
    mysql_append_static_vars()
3035
    show_vars	Pointer to start of array
3036
    count       Number of elements
3037
  
3038
  RETURN VALUES
3039
    0           SUCCESS
3040
    otherwise   FAILURE
3041
*/
3042
int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count)
3043
{
3044
  for (; count > 0; count--, show_vars++)
3045
    if (insert_dynamic(&fixed_show_vars, (uchar*) show_vars))
3046
      return 1;
3047
  return 0;
3048
}
3049
3050
3051
/**
3052
  Find a user set-table variable.
3053
3054
  @param str	   Name of system variable to find
3055
  @param length    Length of variable.  zero means that we should use strlen()
3056
                   on the variable
3057
  @param no_error  Refuse to emit an error, even if one occurred.
3058
3059
  @retval
3060
    pointer	pointer to variable definitions
3061
  @retval
3062
    0		Unknown variable (error message is given)
3063
*/
3064
3065
sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
3066
{
3067
  sys_var *var;
3068
3069
  /*
3070
    This function is only called from the sql_plugin.cc.
3071
    A lock on LOCK_system_variable_hash should be held
3072
  */
3073
  var= (sys_var*) hash_search(&system_variable_hash,
3074
			      (uchar*) str, length ? length : strlen(str));
3075
  if (!(var || no_error))
3076
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
3077
3078
  return var;
3079
}
3080
3081
3082
/**
3083
  Execute update of all variables.
3084
3085
  First run a check of all variables that all updates will go ok.
3086
  If yes, then execute all updates, returning an error if any one failed.
3087
3088
  This should ensure that in all normal cases none all or variables are
3089
  updated.
3090
3091
  @param THD		Thread id
3092
  @param var_list       List of variables to update
3093
3094
  @retval
3095
    0	ok
3096
  @retval
3097
    1	ERROR, message sent (normally no variables was updated)
3098
  @retval
3099
    -1  ERROR, message not sent
3100
*/
3101
3102
int sql_set_variables(THD *thd, List<set_var_base> *var_list)
3103
{
3104
  int error;
3105
  List_iterator_fast<set_var_base> it(*var_list);
3106
  DBUG_ENTER("sql_set_variables");
3107
3108
  set_var_base *var;
3109
  while ((var=it++))
3110
  {
3111
    if ((error= var->check(thd)))
3112
      goto err;
3113
  }
3114
  if (!(error= test(thd->is_error())))
3115
  {
3116
    it.rewind();
3117
    while ((var= it++))
3118
      error|= var->update(thd);         // Returns 0, -1 or 1
3119
  }
3120
3121
err:
3122
  free_underlaid_joins(thd, &thd->lex->select_lex);
3123
  DBUG_RETURN(error);
3124
}
3125
3126
3127
/**
3128
  Say if all variables set by a SET support the ONE_SHOT keyword
3129
  (currently, only character set and collation do; later timezones
3130
  will).
3131
3132
  @param var_list	List of variables to update
3133
3134
  @note
3135
    It has a "not_" because it makes faster tests (no need to "!")
3136
3137
  @retval
3138
    0	all variables of the list support ONE_SHOT
3139
  @retval
3140
    1	at least one does not support ONE_SHOT
3141
*/
3142
3143
bool not_all_support_one_shot(List<set_var_base> *var_list)
3144
{
3145
  List_iterator_fast<set_var_base> it(*var_list);
3146
  set_var_base *var;
3147
  while ((var= it++))
3148
  {
3149
    if (var->no_support_one_shot())
3150
      return 1;
3151
  }
3152
  return 0;
3153
}
3154
3155
3156
/*****************************************************************************
3157
  Functions to handle SET mysql_internal_variable=const_expr
3158
*****************************************************************************/
3159
3160
int set_var::check(THD *thd)
3161
{
3162
  if (var->is_readonly())
3163
  {
3164
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
3165
    return -1;
3166
  }
3167
  if (var->check_type(type))
3168
  {
3169
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
3170
    my_error(err, MYF(0), var->name);
3171
    return -1;
3172
  }
3173
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
3174
  if (!value)
3175
  {
3176
    if (var->check_default(type))
3177
    {
3178
      my_error(ER_NO_DEFAULT, MYF(0), var->name);
3179
      return -1;
3180
    }
3181
    return 0;
3182
  }
3183
3184
  if ((!value->fixed &&
3185
       value->fix_fields(thd, &value)) || value->check_cols(1))
3186
    return -1;
3187
  if (var->check_update_type(value->result_type()))
3188
  {
3189
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
3190
    return -1;
3191
  }
3192
  return var->check(thd, this) ? -1 : 0;
3193
}
3194
3195
/**
3196
  Update variable
3197
3198
  @param   thd    thread handler
3199
  @returns 0|1    ok or	ERROR
3200
3201
  @note ERROR can be only due to abnormal operations involving
3202
  the server's execution evironment such as
3203
  out of memory, hard disk failure or the computer blows up.
3204
  Consider set_var::check() method if there is a need to return
3205
  an error due to logics.
3206
*/
3207
int set_var::update(THD *thd)
3208
{
3209
  if (!value)
3210
    var->set_default(thd, type);
3211
  else if (var->update(thd, this))
3212
    return -1;				// should never happen
3213
  if (var->after_update)
3214
    (*var->after_update)(thd, type);
3215
  return 0;
3216
}
3217
3218
3219
/*****************************************************************************
3220
  Functions to handle SET @user_variable=const_expr
3221
*****************************************************************************/
3222
3223
int set_var_user::check(THD *thd)
3224
{
3225
  /*
3226
    Item_func_set_user_var can't substitute something else on its place =>
3227
    0 can be passed as last argument (reference on item)
3228
  */
3229
  return (user_var_item->fix_fields(thd, (Item**) 0) ||
3230
	  user_var_item->check(0)) ? -1 : 0;
3231
}
3232
3233
3234
int set_var_user::update(THD *thd)
3235
{
3236
  if (user_var_item->update())
3237
  {
3238
    /* Give an error if it's not given already */
3239
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
3240
    return -1;
3241
  }
3242
  return 0;
3243
}
3244
3245
/****************************************************************************
3246
 Functions to handle table_type
3247
****************************************************************************/
3248
3249
/* Based upon sys_var::check_enum() */
3250
3251
bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
3252
{
3253
  char buff[STRING_BUFFER_USUAL_SIZE];
3254
  const char *value;
3255
  String str(buff, sizeof(buff), &my_charset_latin1), *res;
3256
3257
  var->save_result.plugin= NULL;
3258
  if (var->value->result_type() == STRING_RESULT)
3259
  {
3260
    LEX_STRING engine_name;
3261
    handlerton *hton;
3262
    if (!(res=var->value->val_str(&str)) ||
3263
        !(engine_name.str= (char *)res->ptr()) ||
3264
        !(engine_name.length= res->length()) ||
3265
	!(var->save_result.plugin= ha_resolve_by_name(thd, &engine_name)) ||
3266
        !(hton= plugin_data(var->save_result.plugin, handlerton *)) ||
3267
        ha_checktype(thd, ha_legacy_type(hton), 1, 0) != hton)
3268
    {
3269
      value= res ? res->c_ptr() : "NULL";
3270
      goto err;
3271
    }
3272
    return 0;
3273
  }
3274
  value= "unknown";
3275
3276
err:
3277
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
3278
  return 1;
3279
}
3280
3281
3282
uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
3283
					    LEX_STRING *base)
3284
{
3285
  uchar* result;
3286
  handlerton *hton;
3287
  LEX_STRING *engine_name;
3288
  plugin_ref plugin= thd->variables.*offset;
3289
  if (type == OPT_GLOBAL)
3290
    plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
3291
  hton= plugin_data(plugin, handlerton*);
3292
  engine_name= &hton2plugin[hton->slot]->name;
3293
  result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
3294
  if (type == OPT_GLOBAL)
3295
    plugin_unlock(thd, plugin);
3296
  return result;
3297
}
3298
3299
3300
void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
3301
{
3302
  plugin_ref old_value, new_value, *value;
3303
  if (type == OPT_GLOBAL)
3304
  {
3305
    value= &(global_system_variables.*offset);
3306
    new_value= ha_lock_engine(NULL, myisam_hton);
3307
  }
3308
  else
3309
  {
3310
    value= &(thd->variables.*offset);
3311
    new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
3312
  }
3313
  DBUG_ASSERT(new_value);
3314
  old_value= *value;
3315
  *value= new_value;
3316
  plugin_unlock(NULL, old_value);
3317
}
3318
3319
3320
bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
3321
{
3322
  plugin_ref *value= &(global_system_variables.*offset), old_value;
3323
   if (var->type != OPT_GLOBAL)
3324
     value= &(thd->variables.*offset);
3325
  old_value= *value;
3326
  if (old_value != var->save_result.plugin)
3327
  {
3328
    *value= my_plugin_lock(NULL, &var->save_result.plugin);
3329
    plugin_unlock(NULL, old_value);
3330
  }
3331
  return 0;
3332
}
3333
3334
bool
3335
sys_var_thd_optimizer_switch::
3336
symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
3337
{
3338
  char buff[STRING_BUFFER_USUAL_SIZE*8];
3339
  String tmp(buff, sizeof(buff), &my_charset_latin1);
3340
3341
  tmp.length(0);
3342
3343
  for (uint i= 0; val; val>>= 1, i++)
3344
  {
3345
    if (val & 1)
3346
    {
3347
      tmp.append(optimizer_switch_typelib.type_names[i],
3348
                 optimizer_switch_typelib.type_lengths[i]);
3349
      tmp.append(',');
3350
    }
3351
  }
3352
3353
  if (tmp.length())
3354
    tmp.length(tmp.length() - 1); /* trim the trailing comma */
3355
3356
  rep->str= thd->strmake(tmp.ptr(), tmp.length());
3357
3358
  rep->length= rep->str ? tmp.length() : 0;
3359
3360
  return rep->length != tmp.length();
3361
}
3362
3363
3364
uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
3365
				               LEX_STRING *base)
3366
{
3367
  LEX_STRING opts;
3368
  ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
3369
                  thd->variables.*offset);
3370
  (void) symbolic_mode_representation(thd, val, &opts);
3371
  return (uchar *) opts.str;
3372
}
3373
3374
3375
void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
3376
{
3377
  if (type == OPT_GLOBAL)
3378
    global_system_variables.*offset= 0;
3379
  else
3380
    thd->variables.*offset= global_system_variables.*offset;
3381
}
3382
3383
3384
/****************************************************************************
3385
  Named list handling
3386
****************************************************************************/
3387
3388
uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
3389
		NAMED_LIST **found)
3390
{
3391
  I_List_iterator<NAMED_LIST> it(*list);
3392
  NAMED_LIST *element;
3393
  while ((element= it++))
3394
  {
3395
    if (element->cmp(name, length))
3396
    {
3397
      if (found)
3398
        *found= element;
3399
      return element->data;
3400
    }
3401
  }
3402
  return 0;
3403
}
3404
3405
3406
void delete_elements(I_List<NAMED_LIST> *list,
3407
		     void (*free_element)(const char *name, uchar*))
3408
{
3409
  NAMED_LIST *element;
3410
  DBUG_ENTER("delete_elements");
3411
  while ((element= list->get()))
3412
  {
3413
    (*free_element)(element->name, element->data);
3414
    delete element;
3415
  }
3416
  DBUG_VOID_RETURN;
3417
}
3418
3419
3420
/* Key cache functions */
3421
3422
static KEY_CACHE *create_key_cache(const char *name, uint length)
3423
{
3424
  KEY_CACHE *key_cache;
3425
  DBUG_ENTER("create_key_cache");
3426
  DBUG_PRINT("enter",("name: %.*s", length, name));
3427
  
3428
  if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
3429
					     MYF(MY_ZEROFILL | MY_WME))))
3430
  {
3431
    if (!new NAMED_LIST(&key_caches, name, length, (uchar*) key_cache))
3432
    {
3433
      my_free((char*) key_cache, MYF(0));
3434
      key_cache= 0;
3435
    }
3436
    else
3437
    {
3438
      /*
3439
	Set default values for a key cache
3440
	The values in dflt_key_cache_var is set by my_getopt() at startup
3441
3442
	We don't set 'buff_size' as this is used to enable the key cache
3443
      */
3444
      key_cache->param_block_size=     dflt_key_cache_var.param_block_size;
3445
      key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
3446
      key_cache->param_age_threshold=  dflt_key_cache_var.param_age_threshold;
3447
    }
3448
  }
3449
  DBUG_RETURN(key_cache);
3450
}
3451
3452
3453
KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
3454
{
3455
  LEX_STRING key_cache_name;
3456
  KEY_CACHE *key_cache;
3457
3458
  key_cache_name.str= (char *) name;
3459
  key_cache_name.length= length;
3460
  pthread_mutex_lock(&LOCK_global_system_variables);
3461
  if (!(key_cache= get_key_cache(&key_cache_name)))
3462
    key_cache= create_key_cache(name, length);
3463
  pthread_mutex_unlock(&LOCK_global_system_variables);
3464
  return key_cache;
3465
}
3466
3467
3468
void free_key_cache(const char *name, KEY_CACHE *key_cache)
3469
{
3470
  ha_end_key_cache(key_cache);
3471
  my_free((char*) key_cache, MYF(0));
3472
}
3473
3474
3475
bool process_key_caches(process_key_cache_t func)
3476
{
3477
  I_List_iterator<NAMED_LIST> it(key_caches);
3478
  NAMED_LIST *element;
3479
3480
  while ((element= it++))
3481
  {
3482
    KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
3483
    func(element->name, key_cache);
3484
  }
3485
  return 0;
3486
}
3487
3488
3489
bool sys_var_opt_readonly::update(THD *thd, set_var *var)
3490
{
3491
  bool result;
3492
3493
  DBUG_ENTER("sys_var_opt_readonly::update");
3494
3495
  /* Prevent self dead-lock */
3496
  if (thd->locked_tables || thd->active_transaction())
3497
  {
3498
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
3499
    DBUG_RETURN(true);
3500
  }
3501
3502
  if (thd->global_read_lock)
3503
  {
3504
    /*
3505
      This connection already holds the global read lock.
3506
      This can be the case with:
3507
      - FLUSH TABLES WITH READ LOCK
3508
      - SET GLOBAL READ_ONLY = 1
3509
    */
3510
    result= sys_var_bool_ptr::update(thd, var);
3511
    DBUG_RETURN(result);
3512
  }
3513
3514
  /*
3515
    Perform a 'FLUSH TABLES WITH READ LOCK'.
3516
    This is a 3 step process:
3517
    - [1] lock_global_read_lock()
3518
    - [2] close_cached_tables()
3519
    - [3] make_global_read_lock_block_commit()
3520
    [1] prevents new connections from obtaining tables locked for write.
3521
    [2] waits until all existing connections close their tables.
3522
    [3] prevents transactions from being committed.
3523
  */
3524
3525
  if (lock_global_read_lock(thd))
3526
    DBUG_RETURN(true);
3527
3528
  /*
3529
    This call will be blocked by any connection holding a READ or WRITE lock.
3530
    Ideally, we want to wait only for pending WRITE locks, but since:
3531
    con 1> LOCK TABLE T FOR READ;
3532
    con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
3533
    con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
3534
    can cause to wait on a read lock, it's required for the client application
3535
    to unlock everything, and acceptable for the server to wait on all locks.
3536
  */
3537
  if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)) == true)
3538
    goto end_with_read_lock;
3539
3540
  if ((result= make_global_read_lock_block_commit(thd)) == true)
3541
    goto end_with_read_lock;
3542
3543
  /* Change the opt_readonly system variable, safe because the lock is held */
3544
  result= sys_var_bool_ptr::update(thd, var);
3545
3546
end_with_read_lock:
3547
  /* Release the lock */
3548
  unlock_global_read_lock(thd);
3549
  DBUG_RETURN(result);
3550
}
3551
3552
bool sys_var_thd_dbug::update(THD *thd, set_var *var)
3553
{
3554
  if (var->type == OPT_GLOBAL)
3555
  {
3556
    DBUG_SET_INITIAL(var ? var->value->str_value.c_ptr() : "");
3557
  }
3558
  else
3559
  {
3560
    DBUG_SET(var ? var->value->str_value.c_ptr() : "");
3561
  }
3562
3563
  return 0;
3564
}
3565
3566
3567
uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
3568
{
3569
  char buf[256];
3570
  if (type == OPT_GLOBAL)
3571
  {
3572
    DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
3573
  }
3574
  else
3575
  {
3576
    DBUG_EXPLAIN(buf, sizeof(buf));
3577
  }
3578
  return (uchar*) thd->strdup(buf);
3579
}
3580
3581
/****************************************************************************
3582
  Used templates
3583
****************************************************************************/
3584
3585
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3586
template class List<set_var_base>;
3587
template class List_iterator_fast<set_var_base>;
3588
template class I_List_iterator<NAMED_LIST>;
3589
#endif