~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/set_var.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

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