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