~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Brian Aker
  • Date: 2008-12-04 19:04:01 UTC
  • Revision ID: brian@tangent.org-20081204190401-0aatrta3mo36swbk
Next pass through attribute.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
/**
21
 
  @file Handling of MySQL SQL variables
 
21
  @file
 
22
 
 
23
  @brief
 
24
  Handling of MySQL SQL variables
22
25
 
23
26
  @details
24
27
  To add a new variable, one has to do the following:
29
32
  - If the variable is thread specific, add it to 'system_variables' struct.
30
33
    If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
31
34
  - If the variable should be changed from the command line, add a definition
32
 
    of it in the option structure list in mysqld.cc
 
35
    of it in the my_option structure list in mysqld.cc
33
36
  - Don't forget to initialize new fields in global_system_variables and
34
37
    max_system_variables!
35
38
 
36
39
  @todo
37
40
    Add full support for the variable character_set (for 4.1)
38
41
 
 
42
  @todo
 
43
    When updating myisam_delay_key_write, we should do a 'flush tables'
 
44
    of all MyISAM tables to ensure that they are reopen with the
 
45
    new attribute.
 
46
 
39
47
  @note
40
48
    Be careful with var->save_result: sys_var::check() only updates
41
49
    uint64_t_value; so other members of the union are garbage then; to use
43
51
    example).
44
52
*/
45
53
 
46
 
#include "config.h"
47
 
#include "drizzled/option.h"
 
54
#include <drizzled/server_includes.h>
 
55
#include <drizzled/replication/mi.h>
 
56
#include <mysys/my_getopt.h>
 
57
#include <mysys/thr_alarm.h>
 
58
#include <storage/myisam/myisam.h>
48
59
#include <drizzled/error.h>
49
60
#include <drizzled/gettext.h>
50
61
#include <drizzled/tztime.h>
 
62
#include <drizzled/slave.h>
51
63
#include <drizzled/data_home.h>
52
64
#include <drizzled/set_var.h>
53
65
#include <drizzled/session.h>
54
66
#include <drizzled/sql_base.h>
55
 
#include <drizzled/lock.h>
56
 
#include <drizzled/item/uint.h>
57
 
#include <drizzled/item/null.h>
58
 
#include <drizzled/item/float.h>
59
 
#include <drizzled/plugin.h>
60
 
#include "drizzled/version.h"
61
 
#include "drizzled/strfunc.h"
62
 
#include "drizzled/internal/m_string.h"
63
 
#include "drizzled/pthread_globals.h"
64
 
#include "drizzled/charset.h"
65
 
#include "drizzled/transaction_services.h"
66
 
 
67
 
#include <map>
68
 
#include <algorithm>
69
 
 
70
 
using namespace std;
71
 
 
72
 
namespace drizzled
73
 
{
74
 
 
75
 
namespace internal
76
 
{
77
 
extern bool timed_mutexes;
78
 
}
79
 
 
80
 
extern plugin::StorageEngine *myisam_engine;
81
 
extern bool timed_mutexes;
82
 
 
83
 
extern struct option my_long_options[];
 
67
 
84
68
extern const CHARSET_INFO *character_set_filesystem;
 
69
extern I_List<NAMED_LIST> key_caches;
85
70
extern size_t my_thread_stack_size;
86
71
 
87
 
class sys_var_pluginvar;
88
72
static DYNAMIC_ARRAY fixed_show_vars;
89
 
typedef map<string, sys_var *> SystemVariableMap;
90
 
static SystemVariableMap system_variable_map;
91
 
extern char *opt_drizzle_tmpdir;
92
 
 
93
 
extern TYPELIB tx_isolation_typelib;
 
73
static HASH system_variable_hash;
94
74
 
95
75
const char *bool_type_names[]= { "OFF", "ON", NULL };
96
76
TYPELIB bool_typelib=
98
78
  array_elements(bool_type_names)-1, "", bool_type_names, NULL
99
79
};
100
80
 
 
81
const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NULL };
 
82
TYPELIB delay_key_write_typelib=
 
83
{
 
84
  array_elements(delay_key_write_type_names)-1, "",
 
85
  delay_key_write_type_names, NULL
 
86
};
 
87
 
 
88
const char *slave_exec_mode_names[]=
 
89
{ "STRICT", "IDEMPOTENT", NULL };
 
90
static const unsigned int slave_exec_mode_names_len[]=
 
91
{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 };
 
92
TYPELIB slave_exec_mode_typelib=
 
93
{
 
94
  array_elements(slave_exec_mode_names)-1, "",
 
95
  slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len
 
96
};
 
97
 
 
98
static bool sys_update_init_connect(Session*, set_var*);
 
99
static void sys_default_init_connect(Session*, enum_var_type type);
 
100
static bool sys_update_init_slave(Session*, set_var*);
 
101
static void sys_default_init_slave(Session*, enum_var_type type);
101
102
static bool set_option_bit(Session *session, set_var *var);
102
103
static bool set_option_autocommit(Session *session, set_var *var);
 
104
static int  check_log_update(Session *session, set_var *var);
103
105
static int  check_pseudo_thread_id(Session *session, set_var *var);
 
106
static void fix_low_priority_updates(Session *session, enum_var_type type);
104
107
static int check_tx_isolation(Session *session, set_var *var);
105
 
static void fix_tx_isolation(Session *session, sql_var_t type);
 
108
static void fix_tx_isolation(Session *session, enum_var_type type);
106
109
static int check_completion_type(Session *session, set_var *var);
107
 
static void fix_completion_type(Session *session, sql_var_t type);
108
 
static void fix_max_join_size(Session *session, sql_var_t type);
109
 
static void fix_session_mem_root(Session *session, sql_var_t type);
110
 
static void fix_server_id(Session *session, sql_var_t type);
111
 
static bool get_unsigned32(Session *session, set_var *var);
112
 
static bool get_unsigned64(Session *session, set_var *var);
 
110
static void fix_completion_type(Session *session, enum_var_type type);
 
111
static void fix_net_read_timeout(Session *session, enum_var_type type);
 
112
static void fix_net_write_timeout(Session *session, enum_var_type type);
 
113
static void fix_net_retry_count(Session *session, enum_var_type type);
 
114
static void fix_max_join_size(Session *session, enum_var_type type);
 
115
static void fix_myisam_max_sort_file_size(Session *session, enum_var_type type);
 
116
static void fix_max_binlog_size(Session *session, enum_var_type type);
 
117
static void fix_max_relay_log_size(Session *session, enum_var_type type);
 
118
static void fix_max_connections(Session *session, enum_var_type type);
 
119
static void fix_session_mem_root(Session *session, enum_var_type type);
 
120
static void fix_trans_mem_root(Session *session, enum_var_type type);
 
121
static void fix_server_id(Session *session, enum_var_type type);
 
122
static uint64_t fix_unsigned(Session *, uint64_t, const struct my_option *);
 
123
static bool get_unsigned(Session *session, set_var *var);
113
124
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
114
 
                          const std::string &name, int64_t val);
 
125
                          const char *name, int64_t val);
 
126
static KEY_CACHE *create_key_cache(const char *name, uint32_t length);
115
127
static unsigned char *get_error_count(Session *session);
116
128
static unsigned char *get_warning_count(Session *session);
117
129
static unsigned char *get_tmpdir(Session *session);
125
137
  The variables are linked into the list. A variable is added to
126
138
  it in the constructor (see sys_var class for details).
127
139
*/
 
140
 
128
141
static sys_var_chain vars = { NULL, NULL };
129
142
 
130
 
static sys_var_session_uint64_t
 
143
static sys_var_session_uint32_t
131
144
sys_auto_increment_increment(&vars, "auto_increment_increment",
132
 
                             &system_variables::auto_increment_increment);
133
 
static sys_var_session_uint64_t
 
145
                             &SV::auto_increment_increment, NULL, NULL,
 
146
                             sys_var::SESSION_VARIABLE_IN_BINLOG);
 
147
static sys_var_session_uint32_t
134
148
sys_auto_increment_offset(&vars, "auto_increment_offset",
135
 
                          &system_variables::auto_increment_offset);
 
149
                          &SV::auto_increment_offset, NULL, NULL,
 
150
                          sys_var::SESSION_VARIABLE_IN_BINLOG);
136
151
 
137
152
static sys_var_const_str       sys_basedir(&vars, "basedir", drizzle_home);
 
153
static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
 
154
                                              &binlog_cache_size);
138
155
static sys_var_session_uint64_t sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
139
 
                                                          &system_variables::bulk_insert_buff_size);
 
156
                                                          &SV::bulk_insert_buff_size);
140
157
static sys_var_session_uint32_t sys_completion_type(&vars, "completion_type",
141
 
                                                    &system_variables::completion_type,
 
158
                                                    &SV::completion_type,
142
159
                                                    check_completion_type,
143
160
                                                    fix_completion_type);
144
161
static sys_var_collation_sv
145
 
sys_collation_server(&vars, "collation_server", &system_variables::collation_server, &default_charset_info);
146
 
static sys_var_const_str       sys_datadir(&vars, "datadir", data_home_real);
 
162
sys_collation_connection(&vars, "collation_connection",
 
163
                         &SV::collation_connection, &default_charset_info,
 
164
                         sys_var::SESSION_VARIABLE_IN_BINLOG);
 
165
static sys_var_collation_sv
 
166
sys_collation_database(&vars, "collation_database", &SV::collation_database,
 
167
                       &default_charset_info,
 
168
                       sys_var::SESSION_VARIABLE_IN_BINLOG);
 
169
static sys_var_collation_sv
 
170
sys_collation_server(&vars, "collation_server", &SV::collation_server,
 
171
                     &default_charset_info,
 
172
                     sys_var::SESSION_VARIABLE_IN_BINLOG);
 
173
static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
 
174
                                            &connect_timeout);
 
175
static sys_var_const_str       sys_datadir(&vars, "datadir", drizzle_real_data_home);
 
176
static sys_var_enum             sys_delay_key_write(&vars, "delay_key_write",
 
177
                                            &delay_key_write_options,
 
178
                                            &delay_key_write_typelib,
 
179
                                            fix_delay_key_write);
147
180
 
 
181
static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
 
182
                                             &expire_logs_days);
 
183
static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
 
184
sys_var_str             sys_init_connect(&vars, "init_connect", 0,
 
185
                                         sys_update_init_connect,
 
186
                                         sys_default_init_connect,0);
 
187
sys_var_str             sys_init_slave(&vars, "init_slave", 0,
 
188
                                       sys_update_init_slave,
 
189
                                       sys_default_init_slave,0);
 
190
static sys_var_session_uint32_t sys_interactive_timeout(&vars, "interactive_timeout",
 
191
                                                        &SV::net_interactive_timeout);
148
192
static sys_var_session_uint64_t sys_join_buffer_size(&vars, "join_buffer_size",
149
 
                                                     &system_variables::join_buff_size);
 
193
                                                     &SV::join_buff_size);
 
194
static sys_var_key_buffer_size  sys_key_buffer_size(&vars, "key_buffer_size");
 
195
static sys_var_key_cache_long  sys_key_cache_block_size(&vars, "key_cache_block_size",
 
196
                                                        offsetof(KEY_CACHE,
 
197
                                                                 param_block_size));
 
198
static sys_var_key_cache_long   sys_key_cache_division_limit(&vars, "key_cache_division_limit",
 
199
                                                           offsetof(KEY_CACHE,
 
200
                                                                    param_division_limit));
 
201
static sys_var_key_cache_long  sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
 
202
                                                           offsetof(KEY_CACHE,
 
203
                                                                    param_age_threshold));
 
204
static sys_var_bool_ptr sys_local_infile(&vars, "local_infile",
 
205
                                         &opt_local_infile);
 
206
static sys_var_session_bool     sys_low_priority_updates(&vars, "low_priority_updates",
 
207
                                                     &SV::low_priority_updates,
 
208
                                                     fix_low_priority_updates);
 
209
#ifndef TO_BE_DELETED   /* Alias for the low_priority_updates */
 
210
static sys_var_session_bool     sys_sql_low_priority_updates(&vars, "sql_low_priority_updates",
 
211
                                                         &SV::low_priority_updates,
 
212
                                                         fix_low_priority_updates);
 
213
#endif
150
214
static sys_var_session_uint32_t sys_max_allowed_packet(&vars, "max_allowed_packet",
151
 
                                                       &system_variables::max_allowed_packet);
152
 
static sys_var_uint64_t_ptr     sys_max_connect_errors(&vars, "max_connect_errors",
 
215
                                                       &SV::max_allowed_packet);
 
216
static sys_var_long_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size",
 
217
                                                  &max_binlog_cache_size);
 
218
static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size",
 
219
                                            &max_binlog_size,
 
220
                                            fix_max_binlog_size);
 
221
static sys_var_long_ptr sys_max_connections(&vars, "max_connections",
 
222
                                            &max_connections,
 
223
                                            fix_max_connections);
 
224
static sys_var_long_ptr sys_max_connect_errors(&vars, "max_connect_errors",
153
225
                                               &max_connect_errors);
154
226
static sys_var_session_uint64_t sys_max_error_count(&vars, "max_error_count",
155
 
                                                  &system_variables::max_error_count);
 
227
                                                  &SV::max_error_count);
156
228
static sys_var_session_uint64_t sys_max_heap_table_size(&vars, "max_heap_table_size",
157
 
                                                        &system_variables::max_heap_table_size);
 
229
                                                        &SV::max_heap_table_size);
158
230
static sys_var_session_uint64_t sys_pseudo_thread_id(&vars, "pseudo_thread_id",
159
 
                                              &system_variables::pseudo_thread_id,
160
 
                                              0, check_pseudo_thread_id);
 
231
                                              &SV::pseudo_thread_id,
 
232
                                              0, check_pseudo_thread_id,
 
233
                                              sys_var::SESSION_VARIABLE_IN_BINLOG);
161
234
static sys_var_session_ha_rows  sys_max_join_size(&vars, "max_join_size",
162
 
                                                  &system_variables::max_join_size,
 
235
                                                  &SV::max_join_size,
163
236
                                                  fix_max_join_size);
164
237
static sys_var_session_uint64_t sys_max_seeks_for_key(&vars, "max_seeks_for_key",
165
 
                                                      &system_variables::max_seeks_for_key);
 
238
                                                      &SV::max_seeks_for_key);
166
239
static sys_var_session_uint64_t   sys_max_length_for_sort_data(&vars, "max_length_for_sort_data",
167
 
                                                               &system_variables::max_length_for_sort_data);
168
 
static sys_var_session_size_t   sys_max_sort_length(&vars, "max_sort_length",
169
 
                                                    &system_variables::max_sort_length);
170
 
static sys_var_uint64_t_ptr     sys_max_write_lock_count(&vars, "max_write_lock_count",
 
240
                                                               &SV::max_length_for_sort_data);
 
241
static sys_var_long_ptr sys_max_relay_log_size(&vars, "max_relay_log_size",
 
242
                                               &max_relay_log_size,
 
243
                                               fix_max_relay_log_size);
 
244
static sys_var_session_uint64_t sys_max_sort_length(&vars, "max_sort_length",
 
245
                                                    &SV::max_sort_length);
 
246
static sys_var_session_uint64_t sys_max_tmp_tables(&vars, "max_tmp_tables",
 
247
                                                   &SV::max_tmp_tables);
 
248
static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
171
249
                                                 &max_write_lock_count);
172
250
static sys_var_session_uint64_t sys_min_examined_row_limit(&vars, "min_examined_row_limit",
173
 
                                                           &system_variables::min_examined_row_limit);
 
251
                                                           &SV::min_examined_row_limit);
 
252
static sys_var_session_uint64_t sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
 
253
static sys_var_session_uint32_t       sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads);
 
254
static sys_var_session_size_t   sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
174
255
 
 
256
static sys_var_session_enum         sys_myisam_stats_method(&vars, "myisam_stats_method",
 
257
                                                            &SV::myisam_stats_method,
 
258
                                                            &myisam_stats_method_typelib,
 
259
                                                            NULL);
 
260
static sys_var_session_uint32_t sys_net_buffer_length(&vars, "net_buffer_length",
 
261
                                                      &SV::net_buffer_length);
 
262
static sys_var_session_uint32_t sys_net_read_timeout(&vars, "net_read_timeout",
 
263
                                                     &SV::net_read_timeout,
 
264
                                                     0, fix_net_read_timeout);
 
265
static sys_var_session_uint32_t sys_net_write_timeout(&vars, "net_write_timeout",
 
266
                                                      &SV::net_write_timeout,
 
267
                                                      0, fix_net_write_timeout);
 
268
static sys_var_session_uint32_t sys_net_retry_count(&vars, "net_retry_count",
 
269
                                                    &SV::net_retry_count,
 
270
                                                    0, fix_net_retry_count);
 
271
static sys_var_session_bool     sys_new_mode(&vars, "new", &SV::new_mode);
 
272
static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
 
273
                                              &global_system_variables.old_mode);
175
274
/* these two cannot be static */
 
275
sys_var_session_bool sys_old_alter_table(&vars, "old_alter_table",
 
276
                                         &SV::old_alter_table);
176
277
static sys_var_session_bool sys_optimizer_prune_level(&vars, "optimizer_prune_level",
177
 
                                                      &system_variables::optimizer_prune_level);
 
278
                                                      &SV::optimizer_prune_level);
178
279
static sys_var_session_uint32_t sys_optimizer_search_depth(&vars, "optimizer_search_depth",
179
 
                                                           &system_variables::optimizer_search_depth);
 
280
                                                           &SV::optimizer_search_depth);
 
281
 
 
282
const char *optimizer_use_mrr_names[] = {"auto", "force", "disable", NULL};
 
283
TYPELIB optimizer_use_mrr_typelib= {
 
284
  array_elements(optimizer_use_mrr_names) - 1, "",
 
285
  optimizer_use_mrr_names, NULL
 
286
};
 
287
 
 
288
static sys_var_session_enum sys_optimizer_use_mrr(&vars, "optimizer_use_mrr",
 
289
                                                  &SV::optimizer_use_mrr,
 
290
                                                  &optimizer_use_mrr_typelib,
 
291
                                                  NULL);
180
292
 
181
293
static sys_var_session_uint64_t sys_preload_buff_size(&vars, "preload_buffer_size",
182
 
                                                      &system_variables::preload_buff_size);
 
294
                                                      &SV::preload_buff_size);
183
295
static sys_var_session_uint32_t sys_read_buff_size(&vars, "read_buffer_size",
184
 
                                                   &system_variables::read_buff_size);
 
296
                                                   &SV::read_buff_size);
 
297
static sys_var_opt_readonly     sys_readonly(&vars, "read_only", &opt_readonly);
185
298
static sys_var_session_uint32_t sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
186
 
                                                       &system_variables::read_rnd_buff_size);
 
299
                                                       &SV::read_rnd_buff_size);
187
300
static sys_var_session_uint32_t sys_div_precincrement(&vars, "div_precision_increment",
188
 
                                                      &system_variables::div_precincrement);
 
301
                                                      &SV::div_precincrement);
189
302
 
190
303
static sys_var_session_size_t   sys_range_alloc_block_size(&vars, "range_alloc_block_size",
191
 
                                                           &system_variables::range_alloc_block_size);
 
304
                                                           &SV::range_alloc_block_size);
192
305
static sys_var_session_uint32_t sys_query_alloc_block_size(&vars, "query_alloc_block_size",
193
 
                                                           &system_variables::query_alloc_block_size,
 
306
                                                           &SV::query_alloc_block_size,
194
307
                                                           false, fix_session_mem_root);
195
308
static sys_var_session_uint32_t sys_query_prealloc_size(&vars, "query_prealloc_size",
196
 
                                                        &system_variables::query_prealloc_size,
 
309
                                                        &SV::query_prealloc_size,
197
310
                                                        false, fix_session_mem_root);
198
311
static sys_var_readonly sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
 
312
static sys_var_session_uint32_t sys_trans_alloc_block_size(&vars, "transaction_alloc_block_size",
 
313
                                                           &SV::trans_alloc_block_size,
 
314
                                                           false, fix_trans_mem_root);
 
315
static sys_var_session_uint32_t sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
 
316
                                                        &SV::trans_prealloc_size,
 
317
                                                        false, fix_trans_mem_root);
199
318
 
200
319
static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
201
320
                                             &opt_secure_file_priv);
202
321
static sys_var_uint32_t_ptr  sys_server_id(&vars, "server_id", &server_id,
203
322
                                           fix_server_id);
204
323
 
 
324
static sys_var_bool_ptr sys_slave_compressed_protocol(&vars, "slave_compressed_protocol",
 
325
                                                      &opt_slave_compressed_protocol);
 
326
static sys_var_bool_ptr         sys_slave_allow_batching(&vars, "slave_allow_batching",
 
327
                                                         &slave_allow_batching);
 
328
static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
 
329
                                             &slow_launch_time);
205
330
static sys_var_session_size_t   sys_sort_buffer(&vars, "sort_buffer_size",
206
 
                                                &system_variables::sortbuff_size);
 
331
                                                &SV::sortbuff_size);
 
332
/*
 
333
  sql_mode should *not* have binlog_mode=SESSION_VARIABLE_IN_BINLOG:
 
334
  even though it is written to the binlog, the slave ignores the
 
335
  MODE_NO_DIR_IN_CREATE variable, so slave's value differs from
 
336
  master's (see log_event.cc: Query_log_event::do_apply_event()).
 
337
*/
 
338
static sys_var_session_optimizer_switch   sys_optimizer_switch(&vars, "optimizer_switch",
 
339
                                                               &SV::optimizer_switch);
207
340
 
208
341
static sys_var_session_storage_engine sys_storage_engine(&vars, "storage_engine",
209
 
                                       &system_variables::storage_engine);
 
342
                                       &SV::table_plugin);
210
343
static sys_var_const_str        sys_system_time_zone(&vars, "system_time_zone",
211
344
                                             system_time_zone);
212
 
static sys_var_size_t_ptr       sys_table_def_size(&vars, "table_definition_cache",
213
 
                                             &table_def_size);
214
 
static sys_var_uint64_t_ptr     sys_table_cache_size(&vars, "table_open_cache",
 
345
static sys_var_long_ptr sys_table_def_size(&vars, "table_definition_cache",
 
346
                                           &table_def_size);
 
347
static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
215
348
                                             &table_cache_size);
216
 
static sys_var_uint64_t_ptr     sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
 
349
static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
217
350
                                                    &table_lock_wait_timeout);
 
351
sys_var_long_ptr        sys_thread_pool_size(&vars, "thread_pool_size",
 
352
                                       &thread_pool_size);
218
353
static sys_var_session_enum     sys_tx_isolation(&vars, "tx_isolation",
219
 
                                             &system_variables::tx_isolation,
 
354
                                             &SV::tx_isolation,
220
355
                                             &tx_isolation_typelib,
221
356
                                             fix_tx_isolation,
222
357
                                             check_tx_isolation);
223
358
static sys_var_session_uint64_t sys_tmp_table_size(&vars, "tmp_table_size",
224
 
                                           &system_variables::tmp_table_size);
225
 
static sys_var_bool_ptr  sys_timed_mutexes(&vars, "timed_mutexes", &internal::timed_mutexes);
226
 
static sys_var_const_str  sys_version(&vars, "version", version().c_str());
227
 
 
 
359
                                           &SV::tmp_table_size);
 
360
static sys_var_bool_ptr  sys_timed_mutexes(&vars, "timed_mutexes", &timed_mutexes);
 
361
static sys_var_const_str        sys_version(&vars, "version", server_version);
228
362
static sys_var_const_str        sys_version_comment(&vars, "version_comment",
229
363
                                            COMPILATION_COMMENT);
230
364
static sys_var_const_str        sys_version_compile_machine(&vars, "version_compile_machine",
231
 
                                                      HOST_CPU);
 
365
                                                    MACHINE_TYPE);
232
366
static sys_var_const_str        sys_version_compile_os(&vars, "version_compile_os",
233
 
                                                 HOST_OS);
234
 
static sys_var_const_str        sys_version_compile_vendor(&vars, "version_compile_vendor",
235
 
                                                 HOST_VENDOR);
 
367
                                               SYSTEM_TYPE);
 
368
static sys_var_session_uint32_t sys_net_wait_timeout(&vars, "wait_timeout",
 
369
                                                     &SV::net_wait_timeout);
 
370
 
 
371
/* Condition pushdown to storage engine */
 
372
static sys_var_session_bool
 
373
sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
 
374
                              &SV::engine_condition_pushdown);
 
375
 
 
376
/* Time/date/datetime formats */
 
377
 
 
378
static sys_var_session_date_time_format sys_time_format(&vars, "time_format",
 
379
                                             &SV::time_format,
 
380
                                             DRIZZLE_TIMESTAMP_TIME);
 
381
static sys_var_session_date_time_format sys_date_format(&vars, "date_format",
 
382
                                             &SV::date_format,
 
383
                                             DRIZZLE_TIMESTAMP_DATE);
 
384
static sys_var_session_date_time_format sys_datetime_format(&vars, "datetime_format",
 
385
                                                 &SV::datetime_format,
 
386
                                                 DRIZZLE_TIMESTAMP_DATETIME);
236
387
 
237
388
/* Variables that are bits in Session */
238
389
 
243
394
static sys_var_session_bit      sys_big_selects(&vars, "sql_big_selects", 0,
244
395
                                        set_option_bit,
245
396
                                        OPTION_BIG_SELECTS);
 
397
static sys_var_session_bit      sys_log_binlog(&vars, "sql_log_bin",
 
398
                                       check_log_update,
 
399
                                       set_option_bit,
 
400
                                       OPTION_BIN_LOG);
246
401
static sys_var_session_bit      sys_sql_warnings(&vars, "sql_warnings", 0,
247
402
                                         set_option_bit,
248
403
                                         OPTION_WARNINGS);
249
404
static sys_var_session_bit      sys_sql_notes(&vars, "sql_notes", 0,
250
405
                                         set_option_bit,
251
406
                                         OPTION_SQL_NOTES);
 
407
static sys_var_session_bit      sys_safe_updates(&vars, "sql_safe_updates", 0,
 
408
                                         set_option_bit,
 
409
                                         OPTION_SAFE_UPDATES);
252
410
static sys_var_session_bit      sys_buffer_results(&vars, "sql_buffer_result", 0,
253
411
                                           set_option_bit,
254
412
                                           OPTION_BUFFER_RESULT);
 
413
static sys_var_session_bit      sys_quote_show_create(&vars, "sql_quote_show_create", 0,
 
414
                                              set_option_bit,
 
415
                                              OPTION_QUOTE_SHOW_CREATE);
255
416
static sys_var_session_bit      sys_foreign_key_checks(&vars, "foreign_key_checks", 0,
256
417
                                               set_option_bit,
257
 
                                               OPTION_NO_FOREIGN_KEY_CHECKS, 1);
 
418
                                               OPTION_NO_FOREIGN_KEY_CHECKS,
 
419
                                               1, sys_var::SESSION_VARIABLE_IN_BINLOG);
258
420
static sys_var_session_bit      sys_unique_checks(&vars, "unique_checks", 0,
259
421
                                          set_option_bit,
260
 
                                          OPTION_RELAXED_UNIQUE_CHECKS, 1);
 
422
                                          OPTION_RELAXED_UNIQUE_CHECKS,
 
423
                                          1,
 
424
                                          sys_var::SESSION_VARIABLE_IN_BINLOG);
261
425
/* Local state variables */
262
426
 
263
427
static sys_var_session_ha_rows  sys_select_limit(&vars, "sql_select_limit",
264
 
                                                 &system_variables::select_limit);
265
 
static sys_var_timestamp sys_timestamp(&vars, "timestamp");
 
428
                                                 &SV::select_limit);
 
429
static sys_var_timestamp sys_timestamp(&vars, "timestamp",
 
430
                                       sys_var::SESSION_VARIABLE_IN_BINLOG);
266
431
static sys_var_last_insert_id
267
 
sys_last_insert_id(&vars, "last_insert_id");
 
432
sys_last_insert_id(&vars, "last_insert_id",
 
433
                   sys_var::SESSION_VARIABLE_IN_BINLOG);
268
434
/*
269
435
  identity is an alias for last_insert_id(), so that we are compatible
270
436
  with Sybase
271
437
*/
272
 
static sys_var_last_insert_id sys_identity(&vars, "identity");
 
438
static sys_var_last_insert_id
 
439
sys_identity(&vars, "identity", sys_var::SESSION_VARIABLE_IN_BINLOG);
273
440
 
274
 
static sys_var_session_lc_time_names sys_lc_time_names(&vars, "lc_time_names");
 
441
static sys_var_session_lc_time_names
 
442
sys_lc_time_names(&vars, "lc_time_names", sys_var::SESSION_VARIABLE_IN_BINLOG);
275
443
 
276
444
/*
 
445
  insert_id should *not* be marked as written to the binlog (i.e., it
 
446
  should *not* have binlog_status==SESSION_VARIABLE_IN_BINLOG),
 
447
  because we want any statement that refers to insert_id explicitly to
 
448
  be unsafe.  (By "explicitly", we mean using @@session.insert_id,
 
449
  whereas insert_id is used "implicitly" when NULL value is inserted
 
450
  into an auto_increment column).
 
451
 
277
452
  We want statements referring explicitly to @@session.insert_id to be
278
453
  unsafe, because insert_id is modified internally by the slave sql
279
454
  thread when NULL values are inserted in an AUTO_INCREMENT column.
285
460
  statement-based logging mode: t will be different on master and
286
461
  slave).
287
462
*/
 
463
static sys_var_insert_id sys_insert_id(&vars, "insert_id");
288
464
static sys_var_readonly sys_error_count(&vars, "error_count",
289
465
                                        OPT_SESSION,
290
 
                                        SHOW_INT,
 
466
                                        SHOW_LONG,
291
467
                                        get_error_count);
292
468
static sys_var_readonly sys_warning_count(&vars, "warning_count",
293
469
                                          OPT_SESSION,
294
 
                                          SHOW_INT,
 
470
                                          SHOW_LONG,
295
471
                                          get_warning_count);
296
472
 
 
473
static sys_var_session_uint32_t sys_default_week_format(&vars, "default_week_format",
 
474
                                                        &SV::default_week_format);
 
475
 
297
476
sys_var_session_uint64_t sys_group_concat_max_len(&vars, "group_concat_max_len",
298
 
                                                  &system_variables::group_concat_max_len);
 
477
                                                  &SV::group_concat_max_len);
299
478
 
300
 
sys_var_session_time_zone sys_time_zone(&vars, "time_zone");
 
479
sys_var_session_time_zone sys_time_zone(&vars, "time_zone",
 
480
                                    sys_var::SESSION_VARIABLE_IN_BINLOG);
301
481
 
302
482
/* Global read-only variable containing hostname */
303
483
static sys_var_const_str        sys_hostname(&vars, "hostname", glob_hostname);
304
484
 
 
485
static sys_var_const_str_ptr    sys_repl_report_host(&vars, "report_host", &report_host);
 
486
 
 
487
sys_var_session_bool  sys_keep_files_on_create(&vars, "keep_files_on_create", 
 
488
                                           &SV::keep_files_on_create);
 
489
/* Read only variables */
 
490
 
 
491
static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
 
492
static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
305
493
/*
306
494
  Additional variables (not derived from sys_var class, not accessible as
307
495
  @@varname in SELECT or SET). Sorted in alphabetical order to facilitate
309
497
  TODO: remove this list completely
310
498
*/
311
499
 
312
 
#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(drizzle_show_var))
313
 
static drizzle_show_var fixed_vars[]= {
314
 
  {"back_log",                (char*) &back_log,                SHOW_INT},
315
 
  {"language",                language,                         SHOW_CHAR},
316
 
  {"pid_file",                (char*) pidfile_name,             SHOW_CHAR},
317
 
  {"plugin_dir",              (char*) opt_plugin_dir,           SHOW_CHAR},
318
 
  {"thread_stack",            (char*) &my_thread_stack_size,    SHOW_INT},
 
500
#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR))
 
501
static SHOW_VAR fixed_vars[]= {
 
502
  {"back_log",                (char*) &back_log,                    SHOW_INT},
 
503
  {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
 
504
  {"language",                language,                             SHOW_CHAR},
 
505
#ifdef HAVE_MLOCKALL
 
506
  {"locked_in_memory",        (char*) &locked_in_memory,            SHOW_MY_BOOL},
 
507
#endif
 
508
  {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
 
509
  {"log_error",               (char*) log_error_file,               SHOW_CHAR},
 
510
  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
 
511
  {"open_files_limit",        (char*) &open_files_limit,                  SHOW_LONGLONG},
 
512
  {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
 
513
  {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
 
514
  {"port",                    (char*) &drizzled_port,               SHOW_INT},
 
515
  {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
 
516
  {"thread_stack",            (char*) &my_thread_stack_size,        SHOW_INT},
319
517
};
320
518
 
 
519
 
321
520
bool sys_var::check(Session *, set_var *var)
322
521
{
323
522
  var->save_result.uint64_t_value= var->value->val_int();
331
530
    return 0;
332
531
 
333
532
  if ((res=(*check_func)(session, var)) < 0)
334
 
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
 
533
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
 
534
             name, var->value->str_value.ptr());
335
535
  return res;
336
536
}
337
537
 
340
540
*/
341
541
 
342
542
 
 
543
/*
 
544
  Update variables 'init_connect, init_slave'.
 
545
 
 
546
  In case of 'DEFAULT' value
 
547
  (for example: 'set GLOBAL init_connect=DEFAULT')
 
548
  'var' parameter is NULL pointer.
 
549
*/
 
550
 
 
551
bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
 
552
                        set_var *var)
 
553
{
 
554
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
 
555
  uint32_t new_length= (var ? var->value->str_value.length() : 0);
 
556
  if (!old_value)
 
557
    old_value= (char*) "";
 
558
  if (!(res= my_strndup(old_value, new_length, MYF(0))))
 
559
    return 1;
 
560
  /*
 
561
    Replace the old value in such a way that the any thread using
 
562
    the value will work.
 
563
  */
 
564
  rw_wrlock(var_mutex);
 
565
  old_value= var_str->value;
 
566
  var_str->value= res;
 
567
  var_str->value_length= new_length;
 
568
  rw_unlock(var_mutex);
 
569
  free(old_value);
 
570
  return 0;
 
571
}
 
572
 
 
573
 
 
574
static bool sys_update_init_connect(Session *, set_var *var)
 
575
{
 
576
  return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
 
577
}
 
578
 
 
579
 
 
580
static void sys_default_init_connect(Session *, enum_var_type)
 
581
{
 
582
  update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
 
583
}
 
584
 
 
585
 
 
586
static bool sys_update_init_slave(Session *, set_var *var)
 
587
{
 
588
  return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
 
589
}
 
590
 
 
591
 
 
592
static void sys_default_init_slave(Session *, enum_var_type)
 
593
{
 
594
  update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
 
595
}
 
596
 
 
597
 
 
598
/**
 
599
  If one sets the LOW_PRIORIY UPDATES flag, we also must change the
 
600
  used lock type.
 
601
*/
 
602
 
 
603
static void fix_low_priority_updates(Session *session, enum_var_type type)
 
604
{
 
605
  if (type == OPT_GLOBAL)
 
606
    thr_upgraded_concurrent_insert_lock= 
 
607
      (global_system_variables.low_priority_updates ?
 
608
       TL_WRITE_LOW_PRIORITY : TL_WRITE);
 
609
  else
 
610
    session->update_lock_default= (session->variables.low_priority_updates ?
 
611
                               TL_WRITE_LOW_PRIORITY : TL_WRITE);
 
612
}
 
613
 
 
614
 
 
615
static void
 
616
fix_myisam_max_sort_file_size(Session *, enum_var_type)
 
617
{
 
618
  myisam_max_temp_length=
 
619
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
 
620
}
 
621
 
343
622
/**
344
623
  Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
345
624
*/
346
625
 
347
 
static void fix_max_join_size(Session *session, sql_var_t type)
 
626
static void fix_max_join_size(Session *session, enum_var_type type)
348
627
{
349
628
  if (type != OPT_GLOBAL)
350
629
  {
374
653
  If one doesn't use the SESSION modifier, the isolation level
375
654
  is only active for the next command.
376
655
*/
377
 
static void fix_tx_isolation(Session *session, sql_var_t type)
 
656
static void fix_tx_isolation(Session *session, enum_var_type type)
378
657
{
379
658
  if (type == OPT_SESSION)
380
659
    session->session_tx_isolation= ((enum_tx_isolation)
381
660
                                    session->variables.tx_isolation);
382
661
}
383
662
 
384
 
static void fix_completion_type(Session *, sql_var_t) {}
 
663
static void fix_completion_type(Session *, enum_var_type) {}
385
664
 
386
665
static int check_completion_type(Session *, set_var *var)
387
666
{
389
668
  if (val < 0 || val > 2)
390
669
  {
391
670
    char buf[64];
392
 
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->getName().c_str(), internal::llstr(val, buf));
 
671
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
393
672
    return 1;
394
673
  }
395
674
  return 0;
396
675
}
397
676
 
398
677
 
399
 
static void fix_session_mem_root(Session *session, sql_var_t type)
400
 
{
401
 
  if (type != OPT_GLOBAL)
402
 
    session->mem_root->reset_root_defaults(session->variables.query_alloc_block_size,
403
 
                                           session->variables.query_prealloc_size);
404
 
}
405
 
 
406
 
 
407
 
static void fix_server_id(Session *, sql_var_t)
408
 
{
 
678
/*
 
679
  If we are changing the thread variable, we have to copy it to NET too
 
680
*/
 
681
 
 
682
static void fix_net_read_timeout(Session *session, enum_var_type type)
 
683
{
 
684
  if (type != OPT_GLOBAL)
 
685
    my_net_set_read_timeout(&session->net, session->variables.net_read_timeout);
 
686
}
 
687
 
 
688
 
 
689
static void fix_net_write_timeout(Session *session, enum_var_type type)
 
690
{
 
691
  if (type != OPT_GLOBAL)
 
692
    my_net_set_write_timeout(&session->net, session->variables.net_write_timeout);
 
693
}
 
694
 
 
695
static void fix_net_retry_count(Session *session, enum_var_type type)
 
696
{
 
697
  if (type != OPT_GLOBAL)
 
698
    session->net.retry_count=session->variables.net_retry_count;
 
699
}
 
700
 
 
701
 
 
702
extern void fix_delay_key_write(Session *, enum_var_type)
 
703
{
 
704
  switch ((enum_delay_key_write) delay_key_write_options) {
 
705
  case DELAY_KEY_WRITE_NONE:
 
706
    myisam_delay_key_write=0;
 
707
    break;
 
708
  case DELAY_KEY_WRITE_ON:
 
709
    myisam_delay_key_write=1;
 
710
    break;
 
711
  case DELAY_KEY_WRITE_ALL:
 
712
    myisam_delay_key_write=1;
 
713
    ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
 
714
    break;
 
715
  }
 
716
}
 
717
 
 
718
void fix_slave_exec_mode(enum_var_type)
 
719
{
 
720
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
 
721
      bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
722
  {
 
723
    sql_print_error(_("Ambiguous slave modes combination."
 
724
                    " STRICT will be used"));
 
725
    bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
 
726
  }
 
727
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
 
728
    bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
 
729
}
 
730
 
 
731
 
 
732
static void fix_max_binlog_size(Session *, enum_var_type)
 
733
{
 
734
  drizzle_bin_log.set_max_size(max_binlog_size);
 
735
  if (!max_relay_log_size)
 
736
    active_mi->rli.relay_log.set_max_size(max_binlog_size);
 
737
  return;
 
738
}
 
739
 
 
740
static void fix_max_relay_log_size(Session *, enum_var_type)
 
741
{
 
742
  active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
 
743
                                        max_relay_log_size: max_binlog_size);
 
744
  return;
 
745
}
 
746
 
 
747
static void fix_max_connections(Session *, enum_var_type)
 
748
{
 
749
  resize_thr_alarm(max_connections +  10);
 
750
}
 
751
 
 
752
 
 
753
static void fix_session_mem_root(Session *session, enum_var_type type)
 
754
{
 
755
  if (type != OPT_GLOBAL)
 
756
    reset_root_defaults(session->mem_root,
 
757
                        session->variables.query_alloc_block_size,
 
758
                        session->variables.query_prealloc_size);
 
759
}
 
760
 
 
761
 
 
762
static void fix_trans_mem_root(Session *session, enum_var_type type)
 
763
{
 
764
  if (type != OPT_GLOBAL)
 
765
    reset_root_defaults(&session->transaction.mem_root,
 
766
                        session->variables.trans_alloc_block_size,
 
767
                        session->variables.trans_prealloc_size);
 
768
}
 
769
 
 
770
 
 
771
static void fix_server_id(Session *session, enum_var_type)
 
772
{
 
773
  server_id_supplied = 1;
 
774
  session->server_id= server_id;
409
775
}
410
776
 
411
777
 
412
778
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
413
 
                          const std::string &name, int64_t val)
 
779
                          const char *name, int64_t val)
414
780
{
415
781
  if (fixed)
416
782
  {
417
783
    char buf[22];
418
784
 
419
785
    if (unsignd)
420
 
      internal::ullstr((uint64_t) val, buf);
 
786
      ullstr((uint64_t) val, buf);
421
787
    else
422
 
      internal::llstr(val, buf);
 
788
      llstr(val, buf);
423
789
 
424
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
790
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
425
791
                        ER_TRUNCATED_WRONG_VALUE,
426
 
                        ER(ER_TRUNCATED_WRONG_VALUE), name.c_str(), buf);
 
792
                        ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
427
793
  }
428
794
  return false;
429
795
}
430
796
 
431
 
uint64_t fix_unsigned(Session *session, uint64_t num,
432
 
                              const struct option *option_limits)
 
797
static uint64_t fix_unsigned(Session *session, uint64_t num,
 
798
                              const struct my_option *option_limits)
433
799
{
434
800
  bool fixed= false;
435
801
  uint64_t out= getopt_ull_limit_value(num, option_limits, &fixed);
440
806
 
441
807
 
442
808
static size_t fix_size_t(Session *session, size_t num,
443
 
                           const struct option *option_limits)
 
809
                           const struct my_option *option_limits)
444
810
{
445
811
  bool fixed= false;
446
812
  size_t out= (size_t)getopt_ull_limit_value(num, option_limits, &fixed);
449
815
  return out;
450
816
}
451
817
 
452
 
static bool get_unsigned32(Session *session, set_var *var)
453
 
{
454
 
  if (var->value->unsigned_flag)
455
 
    var->save_result.uint32_t_value= 
456
 
      static_cast<uint32_t>(var->value->val_int());
457
 
  else
458
 
  {
459
 
    int64_t v= var->value->val_int();
460
 
    if (v > UINT32_MAX)
461
 
      throw_bounds_warning(session, true, true,var->var->getName().c_str(), v);
462
 
    
463
 
    var->save_result.uint32_t_value= 
464
 
      static_cast<uint32_t>((v > UINT32_MAX) ? UINT32_MAX : (v < 0) ? 0 : v);
465
 
  }
466
 
  return false;
467
 
}
468
 
 
469
 
static bool get_unsigned64(Session *, set_var *var)
470
 
{
471
 
  if (var->value->unsigned_flag)
472
 
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
473
 
  else
474
 
  {
475
 
    int64_t v= var->value->val_int();
476
 
      var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
 
818
static bool get_unsigned(Session *, set_var *var)
 
819
{
 
820
  if (var->value->unsigned_flag)
 
821
    var->save_result.uint64_t_value= (uint64_t) var->value->val_int();
 
822
  else
 
823
  {
 
824
    int64_t v= var->value->val_int();
 
825
    var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
477
826
  }
478
827
  return 0;
479
828
}
481
830
static bool get_size_t(Session *, set_var *var)
482
831
{
483
832
  if (var->value->unsigned_flag)
484
 
    var->save_result.size_t_value= (size_t) var->value->val_int();
485
 
  else
486
 
  {
487
 
    ssize_t v= (ssize_t)var->value->val_int();
488
 
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
489
 
  }
490
 
  return 0;
491
 
}
492
 
 
493
 
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
494
 
{
495
 
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
496
 
  return 0;
 
833
    var->save_result.uint64_t_value= (size_t) var->value->val_int();
 
834
  else
 
835
  {
 
836
    ssize_t v= var->value->val_int();
 
837
    var->save_result.uint64_t_value= (size_t) ((v < 0) ? 0 : v);
 
838
  }
 
839
  return 0;
 
840
}
 
841
 
 
842
 
 
843
sys_var_long_ptr::
 
844
sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, uint64_t *value_ptr_arg,
 
845
                 sys_after_update_func after_update_arg)
 
846
  :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
 
847
                           &LOCK_global_system_variables, after_update_arg)
 
848
{}
 
849
 
 
850
 
 
851
bool sys_var_long_ptr_global::check(Session *session, set_var *var)
 
852
{
 
853
  return get_unsigned(session, var);
 
854
}
 
855
 
 
856
bool sys_var_long_ptr_global::update(Session *session, set_var *var)
 
857
{
 
858
  uint64_t tmp= var->save_result.uint64_t_value;
 
859
  pthread_mutex_lock(guard);
 
860
  if (option_limits)
 
861
    *value= (uint64_t) fix_unsigned(session, tmp, option_limits);
 
862
  else
 
863
  {
 
864
    if (tmp > UINT32_MAX)
 
865
    {
 
866
      tmp= UINT32_MAX;
 
867
      throw_bounds_warning(session, true, true, name,
 
868
                           (int64_t) var->save_result.uint64_t_value);
 
869
    }
 
870
    *value= (uint64_t) tmp;
 
871
  }
 
872
 
 
873
  pthread_mutex_unlock(guard);
 
874
  return 0;
 
875
}
 
876
 
 
877
 
 
878
void sys_var_long_ptr_global::set_default(Session *, enum_var_type)
 
879
{
 
880
  bool not_used;
 
881
  pthread_mutex_lock(guard);
 
882
  *value= (uint64_t) getopt_ull_limit_value((uint64_t) option_limits->def_value,
 
883
                                         option_limits, &not_used);
 
884
  pthread_mutex_unlock(guard);
497
885
}
498
886
 
499
887
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
501
889
  uint32_t tmp= var->save_result.uint32_t_value;
502
890
  pthread_mutex_lock(&LOCK_global_system_variables);
503
891
  if (option_limits)
504
 
  {
505
 
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
506
 
    if(newvalue==tmp)
507
 
      *value= newvalue;
508
 
  }
 
892
    *value= (uint32_t) fix_unsigned(session, tmp, option_limits);
509
893
  else
510
894
    *value= (uint32_t) tmp;
511
895
  pthread_mutex_unlock(&LOCK_global_system_variables);
513
897
}
514
898
 
515
899
 
516
 
void sys_var_uint32_t_ptr::set_default(Session *, sql_var_t)
 
900
void sys_var_uint32_t_ptr::set_default(Session *, enum_var_type)
517
901
{
518
902
  bool not_used;
519
903
  pthread_mutex_lock(&LOCK_global_system_variables);
520
 
  *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value,
521
 
                                           option_limits, &not_used);
 
904
  *value= getopt_ull_limit_value((uint32_t) option_limits->def_value,
 
905
                                 option_limits, &not_used);
522
906
  pthread_mutex_unlock(&LOCK_global_system_variables);
523
907
}
524
908
 
528
912
  uint64_t tmp= var->save_result.uint64_t_value;
529
913
  pthread_mutex_lock(&LOCK_global_system_variables);
530
914
  if (option_limits)
531
 
  {
532
 
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
533
 
    if(newvalue==tmp)
534
 
      *value= newvalue;
535
 
  }
 
915
    *value= (uint64_t) fix_unsigned(session, tmp, option_limits);
536
916
  else
537
917
    *value= (uint64_t) tmp;
538
918
  pthread_mutex_unlock(&LOCK_global_system_variables);
540
920
}
541
921
 
542
922
 
543
 
void sys_var_uint64_t_ptr::set_default(Session *, sql_var_t)
 
923
void sys_var_uint64_t_ptr::set_default(Session *, enum_var_type)
544
924
{
545
925
  bool not_used;
546
926
  pthread_mutex_lock(&LOCK_global_system_variables);
563
943
}
564
944
 
565
945
 
566
 
void sys_var_size_t_ptr::set_default(Session *, sql_var_t)
 
946
void sys_var_size_t_ptr::set_default(Session *, enum_var_type)
567
947
{
568
948
  bool not_used;
569
949
  pthread_mutex_lock(&LOCK_global_system_variables);
579
959
}
580
960
 
581
961
 
582
 
void sys_var_bool_ptr::set_default(Session *, sql_var_t)
 
962
void sys_var_bool_ptr::set_default(Session *, enum_var_type)
583
963
{
584
964
  *value= (bool) option_limits->def_value;
585
965
}
586
966
 
587
967
 
 
968
bool sys_var_enum::update(Session *, set_var *var)
 
969
{
 
970
  *value= (uint) var->save_result.uint32_t_value;
 
971
  return 0;
 
972
}
 
973
 
 
974
 
 
975
unsigned char *sys_var_enum::value_ptr(Session *, enum_var_type, LEX_STRING *)
 
976
{
 
977
  return (unsigned char*) enum_names->type_names[*value];
 
978
}
 
979
 
 
980
 
 
981
unsigned char *sys_var_enum_const::value_ptr(Session *, enum_var_type,
 
982
                                             LEX_STRING *)
 
983
{
 
984
  return (unsigned char*) enum_names->type_names[global_system_variables.*offset];
 
985
}
 
986
 
588
987
/*
589
 
  32 bit types for session variables
 
988
  32 bit types for session variables 
590
989
*/
591
990
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
592
991
{
593
 
  return (get_unsigned32(session, var) ||
 
992
  return (get_unsigned(session, var) ||
594
993
          (check_func && (*check_func)(session, var)));
595
994
}
596
995
 
597
996
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
598
997
{
599
 
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
600
 
 
 
998
  uint64_t tmp= var->save_result.uint64_t_value;
 
999
  
601
1000
  /* Don't use bigger value than given with --maximum-variable-name=.. */
602
1001
  if ((uint32_t) tmp > max_system_variables.*offset)
603
1002
  {
604
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
 
1003
    throw_bounds_warning(session, true, true, name, (int64_t) tmp);
605
1004
    tmp= max_system_variables.*offset;
606
1005
  }
607
 
 
 
1006
  
608
1007
  if (option_limits)
609
1008
    tmp= (uint32_t) fix_unsigned(session, tmp, option_limits);
610
1009
  else if (tmp > UINT32_MAX)
611
1010
  {
612
1011
    tmp= UINT32_MAX;
613
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) var->save_result.uint64_t_value);
 
1012
    throw_bounds_warning(session, true, true, name, (int64_t) var->save_result.uint64_t_value);
614
1013
  }
615
 
 
 
1014
  
616
1015
  if (var->type == OPT_GLOBAL)
617
1016
     global_system_variables.*offset= (uint32_t) tmp;
618
1017
   else
622
1021
 }
623
1022
 
624
1023
 
625
 
 void sys_var_session_uint32_t::set_default(Session *session, sql_var_t type)
 
1024
 void sys_var_session_uint32_t::set_default(Session *session, enum_var_type type)
626
1025
 {
627
1026
   if (type == OPT_GLOBAL)
628
1027
   {
638
1037
 
639
1038
 
640
1039
unsigned char *sys_var_session_uint32_t::value_ptr(Session *session,
641
 
                                                sql_var_t type,
642
 
                                                const LEX_STRING *)
 
1040
                                                enum_var_type type,
 
1041
                                                LEX_STRING *)
643
1042
{
644
1043
  if (type == OPT_GLOBAL)
645
1044
    return (unsigned char*) &(global_system_variables.*offset);
660
1059
  if (var->type == OPT_GLOBAL)
661
1060
  {
662
1061
    /* Lock is needed to make things safe on 32 bit systems */
663
 
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1062
    pthread_mutex_lock(&LOCK_global_system_variables);    
664
1063
    global_system_variables.*offset= (ha_rows) tmp;
665
1064
    pthread_mutex_unlock(&LOCK_global_system_variables);
666
1065
  }
670
1069
}
671
1070
 
672
1071
 
673
 
void sys_var_session_ha_rows::set_default(Session *session, sql_var_t type)
 
1072
void sys_var_session_ha_rows::set_default(Session *session, enum_var_type type)
674
1073
{
675
1074
  if (type == OPT_GLOBAL)
676
1075
  {
688
1087
 
689
1088
 
690
1089
unsigned char *sys_var_session_ha_rows::value_ptr(Session *session,
691
 
                                                  sql_var_t type,
692
 
                                                  const LEX_STRING *)
 
1090
                                                  enum_var_type type,
 
1091
                                                  LEX_STRING *)
693
1092
{
694
1093
  if (type == OPT_GLOBAL)
695
1094
    return (unsigned char*) &(global_system_variables.*offset);
698
1097
 
699
1098
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
700
1099
{
701
 
  return (get_unsigned64(session, var) ||
 
1100
  return (get_unsigned(session, var) ||
702
1101
          (check_func && (*check_func)(session, var)));
703
1102
}
704
1103
 
707
1106
  uint64_t tmp= var->save_result.uint64_t_value;
708
1107
 
709
1108
  if (tmp > max_system_variables.*offset)
710
 
  {
711
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
712
1109
    tmp= max_system_variables.*offset;
713
 
  }
714
1110
 
715
1111
  if (option_limits)
716
1112
    tmp= fix_unsigned(session, tmp, option_limits);
727
1123
}
728
1124
 
729
1125
 
730
 
void sys_var_session_uint64_t::set_default(Session *session, sql_var_t type)
 
1126
void sys_var_session_uint64_t::set_default(Session *session, enum_var_type type)
731
1127
{
732
1128
  if (type == OPT_GLOBAL)
733
1129
  {
744
1140
 
745
1141
 
746
1142
unsigned char *sys_var_session_uint64_t::value_ptr(Session *session,
747
 
                                                   sql_var_t type,
748
 
                                                   const LEX_STRING *)
 
1143
                                                   enum_var_type type,
 
1144
                                                   LEX_STRING *)
749
1145
{
750
1146
  if (type == OPT_GLOBAL)
751
1147
    return (unsigned char*) &(global_system_variables.*offset);
780
1176
}
781
1177
 
782
1178
 
783
 
void sys_var_session_size_t::set_default(Session *session, sql_var_t type)
 
1179
void sys_var_session_size_t::set_default(Session *session, enum_var_type type)
784
1180
{
785
1181
  if (type == OPT_GLOBAL)
786
1182
  {
787
1183
    bool not_used;
788
1184
    pthread_mutex_lock(&LOCK_global_system_variables);
789
1185
    global_system_variables.*offset=
790
 
      (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
791
 
                                     option_limits, &not_used);
 
1186
      getopt_ull_limit_value((size_t) option_limits->def_value,
 
1187
                             option_limits, &not_used);
792
1188
    pthread_mutex_unlock(&LOCK_global_system_variables);
793
1189
  }
794
1190
  else
797
1193
 
798
1194
 
799
1195
unsigned char *sys_var_session_size_t::value_ptr(Session *session,
800
 
                                                 sql_var_t type,
801
 
                                                 const LEX_STRING *)
 
1196
                                                 enum_var_type type,
 
1197
                                                 LEX_STRING *)
802
1198
{
803
1199
  if (type == OPT_GLOBAL)
804
1200
    return (unsigned char*) &(global_system_variables.*offset);
816
1212
}
817
1213
 
818
1214
 
819
 
void sys_var_session_bool::set_default(Session *session,  sql_var_t type)
 
1215
void sys_var_session_bool::set_default(Session *session,  enum_var_type type)
820
1216
{
821
1217
  if (type == OPT_GLOBAL)
822
1218
    global_system_variables.*offset= (bool) option_limits->def_value;
826
1222
 
827
1223
 
828
1224
unsigned char *sys_var_session_bool::value_ptr(Session *session,
829
 
                                               sql_var_t type,
830
 
                                               const LEX_STRING *)
 
1225
                                               enum_var_type type,
 
1226
                                               LEX_STRING *)
831
1227
{
832
1228
  if (type == OPT_GLOBAL)
833
1229
    return (unsigned char*) &(global_system_variables.*offset);
844
1240
 
845
1241
  if (var->value->result_type() == STRING_RESULT)
846
1242
  {
847
 
    if (!(res=var->value->val_str(&str)) ||
848
 
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
849
 
                                                    res->length(),1)) == 0)
 
1243
    if (!(res=var->value->val_str(&str)))
850
1244
    {
851
1245
      value= res ? res->c_ptr() : "NULL";
852
1246
      goto err;
853
1247
    }
854
 
 
855
 
    var->save_result.uint32_t_value--;
856
1248
  }
857
1249
  else
858
1250
  {
859
1251
    uint64_t tmp=var->value->val_int();
860
1252
    if (tmp >= enum_names->count)
861
1253
    {
862
 
      internal::llstr(tmp,buff);
 
1254
      llstr(tmp,buff);
863
1255
      value=buff;                               // Wrong value is here
864
1256
      goto err;
865
1257
    }
868
1260
  return 0;
869
1261
 
870
1262
err:
871
 
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), value);
 
1263
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
 
1264
  return 1;
 
1265
}
 
1266
 
 
1267
 
 
1268
bool sys_var::check_set(Session *, set_var *var, TYPELIB *enum_names)
 
1269
{
 
1270
  bool not_used;
 
1271
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
 
1272
  uint32_t error_len= 0;
 
1273
  String str(buff, sizeof(buff), system_charset_info), *res;
 
1274
 
 
1275
  if (var->value->result_type() == STRING_RESULT)
 
1276
  {
 
1277
    if (!(res= var->value->val_str(&str)))
 
1278
    {
 
1279
      my_stpcpy(buff, "NULL");
 
1280
      goto err;
 
1281
    }
 
1282
 
 
1283
    if (!m_allow_empty_value &&
 
1284
        res->length() == 0)
 
1285
    {
 
1286
      buff[0]= 0;
 
1287
      goto err;
 
1288
    }
 
1289
 
 
1290
    var->save_result.uint32_t_value= ((uint32_t)
 
1291
                                   find_set(enum_names, res->c_ptr(),
 
1292
                                            res->length(),
 
1293
                                            NULL,
 
1294
                                            &error, &error_len,
 
1295
                                            &not_used));
 
1296
    if (error_len)
 
1297
    {
 
1298
      size_t len = cmin(sizeof(buff) - 1, error_len);
 
1299
      strncpy(buff, error, len);
 
1300
      buff[len]= '\0';
 
1301
      goto err;
 
1302
    }
 
1303
  }
 
1304
  else
 
1305
  {
 
1306
    uint64_t tmp= var->value->val_int();
 
1307
 
 
1308
    if (!m_allow_empty_value &&
 
1309
        tmp == 0)
 
1310
    {
 
1311
      buff[0]= '0';
 
1312
      buff[1]= 0;
 
1313
      goto err;
 
1314
    }
 
1315
 
 
1316
    /*
 
1317
      For when the enum is made to contain 64 elements, as 1ULL<<64 is
 
1318
      undefined, we guard with a "count<64" test.
 
1319
    */
 
1320
    if (unlikely((tmp >= ((1UL) << enum_names->count)) &&
 
1321
                 (enum_names->count < 64)))
 
1322
    {
 
1323
      llstr(tmp, buff);
 
1324
      goto err;
 
1325
    }
 
1326
    var->save_result.uint32_t_value= (uint32_t) tmp;  // Save for update
 
1327
  }
 
1328
  return 0;
 
1329
 
 
1330
err:
 
1331
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
872
1332
  return 1;
873
1333
}
874
1334
 
881
1341
  If type is not given, return local value if exists, else global.
882
1342
*/
883
1343
 
884
 
Item *sys_var::item(Session *session, sql_var_t var_type, const LEX_STRING *base)
 
1344
Item *sys_var::item(Session *session, enum_var_type var_type, LEX_STRING *base)
885
1345
{
886
1346
  if (check_type(var_type))
887
1347
  {
888
1348
    if (var_type != OPT_DEFAULT)
889
1349
    {
890
1350
      my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
891
 
               name.c_str(), var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
 
1351
               name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
892
1352
      return 0;
893
1353
    }
894
1354
    /* As there was no local variable, return the global value */
929
1389
    pthread_mutex_unlock(&LOCK_global_system_variables);
930
1390
    return new Item_int((uint64_t) value);
931
1391
  }
932
 
  case SHOW_SIZE:
933
 
  {
934
 
    size_t value;
935
 
    pthread_mutex_lock(&LOCK_global_system_variables);
936
 
    value= *(size_t*) value_ptr(session, var_type, base);
937
 
    pthread_mutex_unlock(&LOCK_global_system_variables);
938
 
    return new Item_int((uint64_t) value);
939
 
  }
940
1392
  case SHOW_MY_BOOL:
941
1393
  {
942
1394
    int32_t value;
981
1433
    return tmp;
982
1434
  }
983
1435
  default:
984
 
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name.c_str());
 
1436
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
985
1437
  }
986
1438
  return 0;
987
1439
}
997
1449
}
998
1450
 
999
1451
 
1000
 
void sys_var_session_enum::set_default(Session *session, sql_var_t type)
 
1452
void sys_var_session_enum::set_default(Session *session, enum_var_type type)
1001
1453
{
1002
1454
  if (type == OPT_GLOBAL)
1003
1455
    global_system_variables.*offset= (uint32_t) option_limits->def_value;
1007
1459
 
1008
1460
 
1009
1461
unsigned char *sys_var_session_enum::value_ptr(Session *session,
1010
 
                                               sql_var_t type,
1011
 
                                               const LEX_STRING *)
 
1462
                                               enum_var_type type,
 
1463
                                               LEX_STRING *)
1012
1464
{
1013
1465
  uint32_t tmp= ((type == OPT_GLOBAL) ?
1014
1466
              global_system_variables.*offset :
1029
1481
}
1030
1482
 
1031
1483
 
1032
 
unsigned char *sys_var_session_bit::value_ptr(Session *session, sql_var_t,
1033
 
                                              const LEX_STRING *)
 
1484
unsigned char *sys_var_session_bit::value_ptr(Session *session, enum_var_type,
 
1485
                                              LEX_STRING *)
1034
1486
{
1035
1487
  /*
1036
1488
    If reverse is 0 (default) return 1 if bit is set.
1042
1494
}
1043
1495
 
1044
1496
 
 
1497
/** Update a date_time format variable based on given value. */
 
1498
 
 
1499
void sys_var_session_date_time_format::update2(Session *session, enum_var_type type,
 
1500
                                           DATE_TIME_FORMAT *new_value)
 
1501
{
 
1502
  DATE_TIME_FORMAT *old;
 
1503
 
 
1504
  if (type == OPT_GLOBAL)
 
1505
  {
 
1506
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1507
    old= (global_system_variables.*offset);
 
1508
    (global_system_variables.*offset)= new_value;
 
1509
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
1510
  }
 
1511
  else
 
1512
  {
 
1513
    old= (session->variables.*offset);
 
1514
    (session->variables.*offset)= new_value;
 
1515
  }
 
1516
  free((char*) old);
 
1517
  return;
 
1518
}
 
1519
 
 
1520
 
 
1521
bool sys_var_session_date_time_format::update(Session *session, set_var *var)
 
1522
{
 
1523
  DATE_TIME_FORMAT *new_value;
 
1524
  /* We must make a copy of the last value to get it into normal memory */
 
1525
  new_value= date_time_format_copy((Session*) 0,
 
1526
                                   var->save_result.date_time_format);
 
1527
  if (!new_value)
 
1528
    return 1;                                   // Out of memory
 
1529
  update2(session, var->type, new_value);               // Can't fail
 
1530
  return 0;
 
1531
}
 
1532
 
 
1533
 
 
1534
bool sys_var_session_date_time_format::check(Session *session, set_var *var)
 
1535
{
 
1536
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1537
  String str(buff,sizeof(buff), system_charset_info), *res;
 
1538
  DATE_TIME_FORMAT *format;
 
1539
 
 
1540
  if (!(res=var->value->val_str(&str)))
 
1541
    res= &my_empty_string;
 
1542
 
 
1543
  if (!(format= date_time_format_make(date_time_type,
 
1544
                                      res->ptr(), res->length())))
 
1545
  {
 
1546
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
 
1547
    return 1;
 
1548
  }
 
1549
  
 
1550
  /*
 
1551
    We must copy result to thread space to not get a memory leak if
 
1552
    update is aborted
 
1553
  */
 
1554
  var->save_result.date_time_format= date_time_format_copy(session, format);
 
1555
  free((char*) format);
 
1556
  return var->save_result.date_time_format == 0;
 
1557
}
 
1558
 
 
1559
 
 
1560
void sys_var_session_date_time_format::set_default(Session *session, enum_var_type type)
 
1561
{
 
1562
  DATE_TIME_FORMAT *res= 0;
 
1563
 
 
1564
  if (type == OPT_GLOBAL)
 
1565
  {
 
1566
    const char *format;
 
1567
    if ((format= opt_date_time_formats[date_time_type]))
 
1568
      res= date_time_format_make(date_time_type, format, strlen(format));
 
1569
  }
 
1570
  else
 
1571
  {
 
1572
    /* Make copy with malloc */
 
1573
    res= date_time_format_copy((Session *) 0, global_system_variables.*offset);
 
1574
  }
 
1575
 
 
1576
  if (res)                                      // Should always be true
 
1577
    update2(session, type, res);
 
1578
}
 
1579
 
 
1580
 
 
1581
unsigned char *sys_var_session_date_time_format::value_ptr(Session *session,
 
1582
                                                           enum_var_type type,
 
1583
                                                           LEX_STRING *)
 
1584
{
 
1585
  if (type == OPT_GLOBAL)
 
1586
  {
 
1587
    char *res;
 
1588
    /*
 
1589
      We do a copy here just to be sure things will work even if someone
 
1590
      is modifying the original string while the copy is accessed
 
1591
      (Can't happen now in SQL SHOW, but this is a good safety for the future)
 
1592
    */
 
1593
    res= session->strmake((global_system_variables.*offset)->format.str,
 
1594
                      (global_system_variables.*offset)->format.length);
 
1595
    return (unsigned char*) res;
 
1596
  }
 
1597
  return (unsigned char*) (session->variables.*offset)->format.str;
 
1598
}
 
1599
 
 
1600
 
1045
1601
typedef struct old_names_map_st
1046
1602
{
1047
1603
  const char *old_name;
1058
1614
    String str(buff,sizeof(buff), system_charset_info), *res;
1059
1615
    if (!(res=var->value->val_str(&str)))
1060
1616
    {
1061
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
1617
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1062
1618
      return 1;
1063
1619
    }
1064
 
    if (!(tmp=get_charset_by_name(res->c_ptr())))
 
1620
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
1065
1621
    {
1066
1622
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1067
1623
      return 1;
1069
1625
  }
1070
1626
  else // INT_RESULT
1071
1627
  {
1072
 
    if (!(tmp=get_charset((int) var->value->val_int())))
 
1628
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1073
1629
    {
1074
1630
      char buf[20];
1075
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
1631
      int10_to_str((int) var->value->val_int(), buf, -10);
1076
1632
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1077
1633
      return 1;
1078
1634
    }
1082
1638
}
1083
1639
 
1084
1640
 
 
1641
bool sys_var_character_set::check(Session *, set_var *var)
 
1642
{
 
1643
  const CHARSET_INFO *tmp;
 
1644
 
 
1645
  if (var->value->result_type() == STRING_RESULT)
 
1646
  {
 
1647
    char buff[STRING_BUFFER_USUAL_SIZE];
 
1648
    String str(buff,sizeof(buff), system_charset_info), *res;
 
1649
    if (!(res=var->value->val_str(&str)))
 
1650
    {
 
1651
      if (!nullable)
 
1652
      {
 
1653
        my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
 
1654
        return 1;
 
1655
      }
 
1656
      tmp= NULL;
 
1657
    }
 
1658
    else if (!(tmp= get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))))
 
1659
    {
 
1660
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
 
1661
      return 1;
 
1662
    }
 
1663
  }
 
1664
  else // INT_RESULT
 
1665
  {
 
1666
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
 
1667
    {
 
1668
      char buf[20];
 
1669
      int10_to_str((int) var->value->val_int(), buf, -10);
 
1670
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
 
1671
      return 1;
 
1672
    }
 
1673
  }
 
1674
  var->save_result.charset= tmp;        // Save for update
 
1675
  return 0;
 
1676
}
 
1677
 
 
1678
 
 
1679
bool sys_var_character_set::update(Session *session, set_var *var)
 
1680
{
 
1681
  ci_ptr(session,var->type)[0]= var->save_result.charset;
 
1682
  session->update_charset();
 
1683
  return 0;
 
1684
}
 
1685
 
 
1686
 
 
1687
unsigned char *sys_var_character_set::value_ptr(Session *session,
 
1688
                                                enum_var_type type,
 
1689
                                                LEX_STRING *)
 
1690
{
 
1691
  const CHARSET_INFO * const cs= ci_ptr(session,type)[0];
 
1692
  return cs ? (unsigned char*) cs->csname : (unsigned char*) NULL;
 
1693
}
 
1694
 
 
1695
 
1085
1696
bool sys_var_collation_sv::update(Session *session, set_var *var)
1086
1697
{
1087
1698
  if (var->type == OPT_GLOBAL)
1089
1700
  else
1090
1701
  {
1091
1702
    session->variables.*offset= var->save_result.charset;
 
1703
    session->update_charset();
1092
1704
  }
1093
1705
  return 0;
1094
1706
}
1095
1707
 
1096
1708
 
1097
 
void sys_var_collation_sv::set_default(Session *session, sql_var_t type)
 
1709
void sys_var_collation_sv::set_default(Session *session, enum_var_type type)
1098
1710
{
1099
1711
  if (type == OPT_GLOBAL)
1100
1712
    global_system_variables.*offset= *global_default;
1101
1713
  else
1102
1714
  {
1103
1715
    session->variables.*offset= global_system_variables.*offset;
 
1716
    session->update_charset();
1104
1717
  }
1105
1718
}
1106
1719
 
1107
1720
 
1108
1721
unsigned char *sys_var_collation_sv::value_ptr(Session *session,
1109
 
                                               sql_var_t type,
1110
 
                                               const LEX_STRING *)
 
1722
                                               enum_var_type type,
 
1723
                                               LEX_STRING *)
1111
1724
{
1112
1725
  const CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
1113
1726
                           global_system_variables.*offset :
1115
1728
  return cs ? (unsigned char*) cs->name : (unsigned char*) "NULL";
1116
1729
}
1117
1730
 
 
1731
 
 
1732
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
 
1733
 
 
1734
static KEY_CACHE zero_key_cache;
 
1735
 
 
1736
KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
 
1737
{
 
1738
  safe_mutex_assert_owner(&LOCK_global_system_variables);
 
1739
  if (!cache_name || ! cache_name->length)
 
1740
    cache_name= &default_key_cache_base;
 
1741
  return ((KEY_CACHE*) find_named(&key_caches,
 
1742
                                      cache_name->str, cache_name->length, 0));
 
1743
}
 
1744
 
 
1745
 
 
1746
unsigned char *sys_var_key_cache_param::value_ptr(Session *, enum_var_type,
 
1747
                                                  LEX_STRING *base)
 
1748
{
 
1749
  KEY_CACHE *key_cache= get_key_cache(base);
 
1750
  if (!key_cache)
 
1751
    key_cache= &zero_key_cache;
 
1752
  return (unsigned char*) key_cache + offset ;
 
1753
}
 
1754
 
 
1755
 
 
1756
bool sys_var_key_buffer_size::update(Session *session, set_var *var)
 
1757
{
 
1758
  uint64_t tmp= var->save_result.uint64_t_value;
 
1759
  LEX_STRING *base_name= &var->base;
 
1760
  KEY_CACHE *key_cache;
 
1761
  bool error= 0;
 
1762
 
 
1763
  /* If no basename, assume it's for the key cache named 'default' */
 
1764
  if (!base_name->length)
 
1765
    base_name= &default_key_cache_base;
 
1766
 
 
1767
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1768
  key_cache= get_key_cache(base_name);
 
1769
                            
 
1770
  if (!key_cache)
 
1771
  {
 
1772
    /* Key cache didn't exists */
 
1773
    if (!tmp)                                   // Tried to delete cache
 
1774
      goto end;                                 // Ok, nothing to do
 
1775
    if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
 
1776
    {
 
1777
      error= 1;
 
1778
      goto end;
 
1779
    }
 
1780
  }
 
1781
 
 
1782
  /*
 
1783
    Abort if some other thread is changing the key cache
 
1784
    TODO: This should be changed so that we wait until the previous
 
1785
    assignment is done and then do the new assign
 
1786
  */
 
1787
  if (key_cache->in_init)
 
1788
    goto end;
 
1789
 
 
1790
  if (!tmp)                                     // Zero size means delete
 
1791
  {
 
1792
    if (key_cache == dflt_key_cache)
 
1793
    {
 
1794
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1795
                          ER_WARN_CANT_DROP_DEFAULT_KEYCACHE,
 
1796
                          ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE));
 
1797
      goto end;                                 // Ignore default key cache
 
1798
    }
 
1799
 
 
1800
    if (key_cache->key_cache_inited)            // If initied
 
1801
    {
 
1802
      /*
 
1803
        Move tables using this key cache to the default key cache
 
1804
        and clear the old key cache.
 
1805
      */
 
1806
      NAMED_LIST *list; 
 
1807
      key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
 
1808
                                              base_name->length, &list);
 
1809
      key_cache->in_init= 1;
 
1810
      pthread_mutex_unlock(&LOCK_global_system_variables);
 
1811
      error= reassign_keycache_tables(session, key_cache, dflt_key_cache);
 
1812
      pthread_mutex_lock(&LOCK_global_system_variables);
 
1813
      key_cache->in_init= 0;
 
1814
    }
 
1815
    /*
 
1816
      We don't delete the key cache as some running threads my still be
 
1817
      in the key cache code with a pointer to the deleted (empty) key cache
 
1818
    */
 
1819
    goto end;
 
1820
  }
 
1821
 
 
1822
  key_cache->param_buff_size=
 
1823
    (uint64_t) fix_unsigned(session, tmp, option_limits);
 
1824
 
 
1825
  /* If key cache didn't existed initialize it, else resize it */
 
1826
  key_cache->in_init= 1;
 
1827
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1828
 
 
1829
  if (!key_cache->key_cache_inited)
 
1830
    error= (bool) (ha_init_key_cache("", key_cache));
 
1831
  else
 
1832
    error= (bool)(ha_resize_key_cache(key_cache));
 
1833
 
 
1834
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1835
  key_cache->in_init= 0;  
 
1836
 
 
1837
end:
 
1838
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1839
  return error;
 
1840
}
 
1841
 
 
1842
 
 
1843
/**
 
1844
  @todo
 
1845
  Abort if some other thread is changing the key cache.
 
1846
  This should be changed so that we wait until the previous
 
1847
  assignment is done and then do the new assign
 
1848
*/
 
1849
bool sys_var_key_cache_long::update(Session *session, set_var *var)
 
1850
{
 
1851
  uint64_t tmp= (uint64_t) var->value->val_int();
 
1852
  LEX_STRING *base_name= &var->base;
 
1853
  bool error= 0;
 
1854
 
 
1855
  if (!base_name->length)
 
1856
    base_name= &default_key_cache_base;
 
1857
 
 
1858
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1859
  KEY_CACHE *key_cache= get_key_cache(base_name);
 
1860
 
 
1861
  if (!key_cache && !(key_cache= create_key_cache(base_name->str,
 
1862
                                                  base_name->length)))
 
1863
  {
 
1864
    error= 1;
 
1865
    goto end;
 
1866
  }
 
1867
 
 
1868
  /*
 
1869
    Abort if some other thread is changing the key cache
 
1870
    TODO: This should be changed so that we wait until the previous
 
1871
    assignment is done and then do the new assign
 
1872
  */
 
1873
  if (key_cache->in_init)
 
1874
    goto end;
 
1875
 
 
1876
  *((uint64_t*) (((char*) key_cache) + offset))=
 
1877
    (uint64_t) fix_unsigned(session, tmp, option_limits);
 
1878
 
 
1879
  /*
 
1880
    Don't create a new key cache if it didn't exist
 
1881
    (key_caches are created only when the user sets block_size)
 
1882
  */
 
1883
  key_cache->in_init= 1;
 
1884
 
 
1885
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1886
 
 
1887
  error= (bool) (ha_resize_key_cache(key_cache));
 
1888
 
 
1889
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1890
  key_cache->in_init= 0;
 
1891
 
 
1892
end:
 
1893
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1894
  return error;
 
1895
}
 
1896
 
 
1897
 
 
1898
bool sys_var_log_state::update(Session *, set_var *var)
 
1899
{
 
1900
  bool res;
 
1901
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1902
  if (!var->save_result.uint32_t_value)
 
1903
    res= false;
 
1904
  else
 
1905
    res= true;
 
1906
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1907
  return res;
 
1908
}
 
1909
 
 
1910
void sys_var_log_state::set_default(Session *, enum_var_type)
 
1911
{
 
1912
}
 
1913
 
 
1914
 
 
1915
bool update_sys_var_str_path(Session *, sys_var_str *var_str,
 
1916
                             set_var *var, const char *log_ext,
 
1917
                             bool log_state, uint32_t log_type)
 
1918
{
 
1919
  char buff[FN_REFLEN];
 
1920
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
 
1921
  bool result= 0;
 
1922
  uint32_t str_length= (var ? var->value->str_value.length() : 0);
 
1923
 
 
1924
  switch (log_type) {
 
1925
  default:
 
1926
    assert(0);                                  // Impossible
 
1927
  }
 
1928
 
 
1929
  if (!old_value)
 
1930
  {
 
1931
    old_value= make_default_log_name(buff, log_ext);
 
1932
    str_length= strlen(old_value);
 
1933
  }
 
1934
  if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
 
1935
  {
 
1936
    result= 1;
 
1937
    goto err;
 
1938
  }
 
1939
 
 
1940
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1941
  logger.lock_exclusive();
 
1942
 
 
1943
  old_value= var_str->value;
 
1944
  var_str->value= res;
 
1945
  var_str->value_length= str_length;
 
1946
  free(old_value);
 
1947
  if (log_state)
 
1948
  {
 
1949
    switch (log_type) {
 
1950
    default:
 
1951
      assert(0);
 
1952
    }
 
1953
  }
 
1954
 
 
1955
  logger.unlock();
 
1956
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1957
 
 
1958
err:
 
1959
  return result;
 
1960
}
 
1961
 
 
1962
 
 
1963
/*****************************************************************************
 
1964
  Functions to handle SET NAMES and SET CHARACTER SET
 
1965
*****************************************************************************/
 
1966
 
 
1967
int set_var_collation_client::check(Session *)
 
1968
{
 
1969
  /* Currently, UCS-2 cannot be used as a client character set */
 
1970
  if (character_set_client->mbminlen > 1)
 
1971
  {
 
1972
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
 
1973
             character_set_client->csname);
 
1974
    return 1;
 
1975
  }
 
1976
  return 0;
 
1977
}
 
1978
 
 
1979
int set_var_collation_client::update(Session *session)
 
1980
{
 
1981
  session->variables.character_set_client= character_set_client;
 
1982
  session->variables.character_set_results= character_set_results;
 
1983
  session->variables.collation_connection= collation_connection;
 
1984
  session->update_charset();
 
1985
  session->protocol_text.init(session);
 
1986
  return 0;
 
1987
}
 
1988
 
1118
1989
/****************************************************************************/
1119
1990
 
1120
1991
bool sys_var_timestamp::update(Session *session,  set_var *var)
1124
1995
}
1125
1996
 
1126
1997
 
1127
 
void sys_var_timestamp::set_default(Session *session, sql_var_t)
 
1998
void sys_var_timestamp::set_default(Session *session, enum_var_type)
1128
1999
{
1129
2000
  session->user_time=0;
1130
2001
}
1131
2002
 
1132
2003
 
1133
 
unsigned char *sys_var_timestamp::value_ptr(Session *session, sql_var_t,
1134
 
                                            const LEX_STRING *)
 
2004
unsigned char *sys_var_timestamp::value_ptr(Session *session, enum_var_type,
 
2005
                                            LEX_STRING *)
1135
2006
{
1136
 
  session->sys_var_tmp.int32_t_value= (int32_t) session->start_time;
1137
 
  return (unsigned char*) &session->sys_var_tmp.int32_t_value;
 
2007
  session->sys_var_tmp.long_value= (long) session->start_time;
 
2008
  return (unsigned char*) &session->sys_var_tmp.long_value;
1138
2009
}
1139
2010
 
1140
2011
 
1147
2018
 
1148
2019
 
1149
2020
unsigned char *sys_var_last_insert_id::value_ptr(Session *session,
1150
 
                                                 sql_var_t,
1151
 
                                                 const LEX_STRING *)
 
2021
                                                 enum_var_type,
 
2022
                                                 LEX_STRING *)
1152
2023
{
1153
2024
  /*
1154
2025
    this tmp var makes it robust againt change of type of
1160
2031
}
1161
2032
 
1162
2033
 
 
2034
bool sys_var_insert_id::update(Session *session, set_var *var)
 
2035
{
 
2036
  session->force_one_auto_inc_interval(var->save_result.uint64_t_value);
 
2037
  return 0;
 
2038
}
 
2039
 
 
2040
 
 
2041
unsigned char *sys_var_insert_id::value_ptr(Session *session, enum_var_type,
 
2042
                                            LEX_STRING *)
 
2043
{
 
2044
  session->sys_var_tmp.uint64_t_value=
 
2045
    session->auto_inc_intervals_forced.minimum();
 
2046
  return (unsigned char*) &session->sys_var_tmp.uint64_t_value;
 
2047
}
 
2048
 
 
2049
 
1163
2050
bool sys_var_session_time_zone::check(Session *session, set_var *var)
1164
2051
{
1165
2052
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
1191
2078
 
1192
2079
 
1193
2080
unsigned char *sys_var_session_time_zone::value_ptr(Session *session,
1194
 
                                                    sql_var_t type,
1195
 
                                                    const LEX_STRING *)
 
2081
                                                    enum_var_type type,
 
2082
                                                    LEX_STRING *)
1196
2083
{
1197
2084
  /*
1198
2085
    We can use ptr() instead of c_ptr() here because String contaning
1215
2102
}
1216
2103
 
1217
2104
 
1218
 
void sys_var_session_time_zone::set_default(Session *session, sql_var_t type)
 
2105
void sys_var_session_time_zone::set_default(Session *session, enum_var_type type)
1219
2106
{
1220
2107
 pthread_mutex_lock(&LOCK_global_system_variables);
1221
2108
 if (type == OPT_GLOBAL)
1244
2131
 
1245
2132
  if (var->value->result_type() == INT_RESULT)
1246
2133
  {
1247
 
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
 
2134
    if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
1248
2135
    {
1249
2136
      char buf[20];
1250
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
2137
      int10_to_str((int) var->value->val_int(), buf, -10);
1251
2138
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
1252
2139
      return 1;
1253
2140
    }
1254
2141
  }
1255
2142
  else // STRING_RESULT
1256
2143
  {
1257
 
    char buff[6];
 
2144
    char buff[6]; 
1258
2145
    String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1259
2146
    if (!(res=var->value->val_str(&str)))
1260
2147
    {
1261
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
2148
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1262
2149
      return 1;
1263
2150
    }
1264
2151
    const char *locale_str= res->c_ptr();
1286
2173
 
1287
2174
 
1288
2175
unsigned char *sys_var_session_lc_time_names::value_ptr(Session *session,
1289
 
                                                        sql_var_t type,
1290
 
                                                        const LEX_STRING *)
 
2176
                                                        enum_var_type type,
 
2177
                                                        LEX_STRING *)
1291
2178
{
1292
2179
  return type == OPT_GLOBAL ?
1293
2180
                 (unsigned char *) global_system_variables.lc_time_names->name :
1295
2182
}
1296
2183
 
1297
2184
 
1298
 
void sys_var_session_lc_time_names::set_default(Session *session, sql_var_t type)
 
2185
void sys_var_session_lc_time_names::set_default(Session *session, enum_var_type type)
1299
2186
{
1300
2187
  if (type == OPT_GLOBAL)
1301
2188
    global_system_variables.lc_time_names= my_default_lc_time_names;
1333
2220
}
1334
2221
 
1335
2222
 
1336
 
void sys_var_microseconds::set_default(Session *session, sql_var_t type)
 
2223
void sys_var_microseconds::set_default(Session *session, enum_var_type type)
1337
2224
{
1338
2225
  int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
1339
2226
  if (type == OPT_GLOBAL)
1346
2233
    session->variables.*offset= microseconds;
1347
2234
}
1348
2235
 
 
2236
 
 
2237
unsigned char *sys_var_microseconds::value_ptr(Session *session,
 
2238
                                               enum_var_type type,
 
2239
                                               LEX_STRING *)
 
2240
{
 
2241
  session->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
 
2242
                                   global_system_variables.*offset :
 
2243
                                   session->variables.*offset) / 1000000.0;
 
2244
  return (unsigned char*) &session->tmp_double_value;
 
2245
}
 
2246
 
 
2247
 
1349
2248
/*
1350
2249
  Functions to update session->options bits
1351
2250
*/
1377
2276
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
1378
2277
    {
1379
2278
      /* We changed to auto_commit mode */
1380
 
      session->options&= ~(uint64_t) (OPTION_BEGIN);
 
2279
      session->options&= ~(uint64_t) (OPTION_BEGIN | OPTION_KEEP_LOG);
 
2280
      session->transaction.all.modified_non_trans_table= false;
1381
2281
      session->server_status|= SERVER_STATUS_AUTOCOMMIT;
1382
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1383
 
      if (transaction_services.commitTransaction(session, true))
1384
 
        return 1;
 
2282
      if (ha_commit(session))
 
2283
        return 1;
1385
2284
    }
1386
2285
    else
1387
2286
    {
 
2287
      session->transaction.all.modified_non_trans_table= false;
1388
2288
      session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
1389
2289
    }
1390
2290
  }
1391
2291
  return 0;
1392
2292
}
1393
2293
 
 
2294
static int check_log_update(Session *, set_var *)
 
2295
{
 
2296
  return 0;
 
2297
}
 
2298
 
 
2299
 
1394
2300
static int check_pseudo_thread_id(Session *, set_var *var)
1395
2301
{
1396
2302
  var->save_result.uint64_t_value= var->value->val_int();
1399
2305
 
1400
2306
static unsigned char *get_warning_count(Session *session)
1401
2307
{
1402
 
  session->sys_var_tmp.uint32_t_value=
 
2308
  session->sys_var_tmp.long_value=
1403
2309
    (session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE] +
1404
2310
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR] +
1405
2311
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN]);
1406
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2312
  return (unsigned char*) &session->sys_var_tmp.long_value;
1407
2313
}
1408
2314
 
1409
2315
static unsigned char *get_error_count(Session *session)
1410
2316
{
1411
 
  session->sys_var_tmp.uint32_t_value=
 
2317
  session->sys_var_tmp.long_value= 
1412
2318
    session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR];
1413
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2319
  return (unsigned char*) &session->sys_var_tmp.long_value;
1414
2320
}
1415
2321
 
1416
2322
 
1430
2336
*/
1431
2337
static unsigned char *get_tmpdir(Session *)
1432
2338
{
1433
 
  assert(drizzle_tmpdir);
 
2339
  if (opt_drizzle_tmpdir)
 
2340
    return (unsigned char *)opt_drizzle_tmpdir;
1434
2341
  return (unsigned char*)drizzle_tmpdir;
1435
2342
}
1436
2343
 
1454
2361
    ptr         pointer to option structure
1455
2362
*/
1456
2363
 
1457
 
static struct option *find_option(struct option *opt, const char *name)
 
2364
static struct my_option *find_option(struct my_option *opt, const char *name) 
1458
2365
{
1459
2366
  uint32_t length=strlen(name);
1460
2367
  for (; opt->name; opt++)
1473
2380
}
1474
2381
 
1475
2382
 
 
2383
/**
 
2384
  Return variable name and length for hashing of variables.
 
2385
*/
 
2386
 
 
2387
static unsigned char *get_sys_var_length(const sys_var *var, size_t *length,
 
2388
                                         bool)
 
2389
{
 
2390
  *length= var->name_length;
 
2391
  return (unsigned char*) var->name;
 
2392
}
 
2393
 
 
2394
 
1476
2395
/*
1477
2396
  Add variables to the dynamic hash of system variables
1478
 
 
 
2397
  
1479
2398
  SYNOPSIS
1480
2399
    mysql_add_sys_var_chain()
1481
2400
    first       Pointer to first system variable to add
1482
2401
    long_opt    (optional)command line arguments may be tied for limit checks.
1483
 
 
 
2402
  
1484
2403
  RETURN VALUES
1485
2404
    0           SUCCESS
1486
2405
    otherwise   FAILURE
1487
2406
*/
1488
2407
 
1489
2408
 
1490
 
int mysql_add_sys_var_chain(sys_var *first, struct option *long_options)
 
2409
int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
1491
2410
{
1492
2411
  sys_var *var;
 
2412
  
1493
2413
  /* A write lock should be held on LOCK_system_variables_hash */
1494
 
 
1495
 
  for (var= first; var; var= var->getNext())
 
2414
  
 
2415
  for (var= first; var; var= var->next)
1496
2416
  {
1497
 
 
1498
 
    string lower_name(var->getName());
1499
 
    transform(lower_name.begin(), lower_name.end(),
1500
 
              lower_name.begin(), ::tolower);
1501
 
 
1502
 
    /* this fails if there is a conflicting variable name. */
1503
 
    if (system_variable_map.find(lower_name) != system_variable_map.end())
1504
 
    {
1505
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Variable named %s already exists!\n"),
1506
 
                    var->getName().c_str());
1507
 
      return 1;
1508
 
    } 
1509
 
 
1510
 
    pair<SystemVariableMap::iterator, bool> ret= 
1511
 
      system_variable_map.insert(make_pair(lower_name, var));
1512
 
    if (ret.second == false)
1513
 
    {
1514
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Could not add Variable: %s\n"),
1515
 
                    var->getName().c_str());
1516
 
      return 1;
1517
 
    }
1518
 
 
 
2417
    var->name_length= strlen(var->name);
 
2418
    /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
 
2419
    if (my_hash_insert(&system_variable_hash, (unsigned char*) var))
 
2420
      goto error;
1519
2421
    if (long_options)
1520
 
      var->setOptionLimits(find_option(long_options, var->getName().c_str()));
 
2422
      var->option_limits= find_option(long_options, var->name);
1521
2423
  }
1522
2424
  return 0;
1523
2425
 
 
2426
error:
 
2427
  for (; first != var; first= first->next)
 
2428
    hash_delete(&system_variable_hash, (unsigned char*) first);
 
2429
  return 1;
1524
2430
}
1525
 
 
1526
 
 
 
2431
 
 
2432
 
1527
2433
/*
1528
2434
  Remove variables to the dynamic hash of system variables
1529
 
 
 
2435
   
1530
2436
  SYNOPSIS
1531
2437
    mysql_del_sys_var_chain()
1532
2438
    first       Pointer to first system variable to remove
1533
 
 
 
2439
   
1534
2440
  RETURN VALUES
1535
2441
    0           SUCCESS
1536
2442
    otherwise   FAILURE
1537
2443
*/
1538
 
 
 
2444
 
1539
2445
int mysql_del_sys_var_chain(sys_var *first)
1540
2446
{
1541
 
 
 
2447
  int result= 0;
 
2448
 
1542
2449
  /* A write lock should be held on LOCK_system_variables_hash */
1543
 
  for (sys_var *var= first; var; var= var->getNext())
1544
 
  {
1545
 
    string lower_name(var->getName());
1546
 
    transform(lower_name.begin(), lower_name.end(),
1547
 
              lower_name.begin(), ::tolower);
1548
 
    system_variable_map.erase(lower_name);
1549
 
  }
1550
 
  return 0;
1551
 
}
1552
 
 
1553
 
 
1554
 
 
 
2450
   
 
2451
  for (sys_var *var= first; var; var= var->next)
 
2452
    result|= hash_delete(&system_variable_hash, (unsigned char*) var);
 
2453
 
 
2454
  return result;
 
2455
}
 
2456
 
 
2457
 
 
2458
static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
 
2459
{
 
2460
  return strcmp(a->name, b->name);
 
2461
}
 
2462
 
 
2463
 
1555
2464
/*
1556
2465
  Constructs an array of system variables for display to the user.
1557
 
 
 
2466
  
1558
2467
  SYNOPSIS
1559
2468
    enumerate_sys_vars()
1560
2469
    session         current thread
1561
2470
    sorted      If TRUE, the system variables should be sorted
1562
 
 
 
2471
  
1563
2472
  RETURN VALUES
1564
 
    pointer     Array of drizzle_show_var elements for display
 
2473
    pointer     Array of SHOW_VAR elements for display
1565
2474
    NULL        FAILURE
1566
2475
*/
1567
2476
 
1568
 
drizzle_show_var* enumerate_sys_vars(Session *session, bool)
 
2477
SHOW_VAR* enumerate_sys_vars(Session *session, bool sorted)
1569
2478
{
 
2479
  int count= system_variable_hash.records, i;
1570
2480
  int fixed_count= fixed_show_vars.elements;
1571
 
  int size= sizeof(drizzle_show_var) * (system_variable_map.size() + fixed_count + 1);
1572
 
  drizzle_show_var *result= (drizzle_show_var*) session->alloc(size);
 
2481
  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
 
2482
  SHOW_VAR *result= (SHOW_VAR*) session->alloc(size);
1573
2483
 
1574
2484
  if (result)
1575
2485
  {
1576
 
    drizzle_show_var *show= result + fixed_count;
1577
 
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(drizzle_show_var));
 
2486
    SHOW_VAR *show= result + fixed_count;
 
2487
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
1578
2488
 
1579
 
    SystemVariableMap::const_iterator iter= system_variable_map.begin();
1580
 
    while (iter != system_variable_map.end())
 
2489
    for (i= 0; i < count; i++)
1581
2490
    {
1582
 
      sys_var *var= (*iter).second;
1583
 
      show->name= var->getName().c_str();
 
2491
      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
 
2492
      show->name= var->name;
1584
2493
      show->value= (char*) var;
1585
2494
      show->type= SHOW_SYS;
1586
2495
      show++;
1587
 
      ++iter;
1588
2496
    }
1589
2497
 
 
2498
    /* sort into order */
 
2499
    if (sorted)
 
2500
      my_qsort(result, count + fixed_count, sizeof(SHOW_VAR),
 
2501
               (qsort_cmp) show_cmp);
 
2502
    
1590
2503
    /* make last element empty */
1591
 
    memset(show, 0, sizeof(drizzle_show_var));
 
2504
    memset(show, 0, sizeof(SHOW_VAR));
1592
2505
  }
1593
2506
  return result;
1594
2507
}
1596
2509
 
1597
2510
/*
1598
2511
  Initialize the system variables
1599
 
 
 
2512
  
1600
2513
  SYNOPSIS
1601
2514
    set_var_init()
1602
 
 
 
2515
  
1603
2516
  RETURN VALUES
1604
2517
    0           SUCCESS
1605
2518
    otherwise   FAILURE
1608
2521
int set_var_init()
1609
2522
{
1610
2523
  uint32_t count= 0;
1611
 
 
1612
 
  for (sys_var *var= vars.first; var; var= var->getNext(), count++) {};
1613
 
 
1614
 
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(drizzle_show_var),
 
2524
  
 
2525
  for (sys_var *var=vars.first; var; var= var->next, count++) {};
 
2526
 
 
2527
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR),
1615
2528
                            FIXED_VARS_SIZE + 64, 64))
1616
2529
    goto error;
1617
2530
 
1618
2531
  fixed_show_vars.elements= FIXED_VARS_SIZE;
1619
2532
  memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
1620
2533
 
1621
 
  vars.last->setNext(NULL);
 
2534
  if (hash_init(&system_variable_hash, system_charset_info, count, 0,
 
2535
                0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
 
2536
    goto error;
 
2537
 
 
2538
  vars.last->next= NULL;
1622
2539
  if (mysql_add_sys_var_chain(vars.first, my_long_options))
1623
2540
    goto error;
1624
2541
 
1632
2549
 
1633
2550
void set_var_free()
1634
2551
{
 
2552
  hash_free(&system_variable_hash);
1635
2553
  delete_dynamic(&fixed_show_vars);
1636
2554
}
1637
2555
 
1638
2556
 
 
2557
/*
 
2558
  Add elements to the dynamic list of read-only system variables.
 
2559
  
 
2560
  SYNOPSIS
 
2561
    mysql_append_static_vars()
 
2562
    show_vars   Pointer to start of array
 
2563
    count       Number of elements
 
2564
  
 
2565
  RETURN VALUES
 
2566
    0           SUCCESS
 
2567
    otherwise   FAILURE
 
2568
*/
 
2569
int mysql_append_static_vars(const SHOW_VAR *show_vars, uint32_t count)
 
2570
{
 
2571
  for (; count > 0; count--, show_vars++)
 
2572
    if (insert_dynamic(&fixed_show_vars, (unsigned char*) show_vars))
 
2573
      return 1;
 
2574
  return 0;
 
2575
}
 
2576
 
 
2577
 
1639
2578
/**
1640
2579
  Find a user set-table variable.
1641
2580
 
1650
2589
    0           Unknown variable (error message is given)
1651
2590
*/
1652
2591
 
1653
 
sys_var *intern_find_sys_var(const char *str, uint32_t, bool no_error)
 
2592
sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error)
1654
2593
{
1655
 
  string lower_name(str);
1656
 
  transform(lower_name.begin(), lower_name.end(),
1657
 
            lower_name.begin(), ::tolower);
1658
 
 
1659
 
  sys_var *result= NULL;
1660
 
 
1661
 
  SystemVariableMap::iterator iter= system_variable_map.find(lower_name);
1662
 
  if (iter != system_variable_map.end())
1663
 
  {
1664
 
    result= (*iter).second;
1665
 
  } 
 
2594
  sys_var *var;
1666
2595
 
1667
2596
  /*
1668
2597
    This function is only called from the sql_plugin.cc.
1669
2598
    A lock on LOCK_system_variable_hash should be held
1670
2599
  */
1671
 
  if (result == NULL)
1672
 
  {
1673
 
    if (no_error)
1674
 
    {
1675
 
      return NULL;
1676
 
    }
1677
 
    else
1678
 
    {
1679
 
      my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
1680
 
      return NULL;
1681
 
    }
1682
 
  }
 
2600
  var= (sys_var*) hash_search(&system_variable_hash,
 
2601
                              (unsigned char*) str, length ? length : strlen(str));
 
2602
  if (!(var || no_error))
 
2603
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
1683
2604
 
1684
 
  return result;
 
2605
  return var;
1685
2606
}
1686
2607
 
1687
2608
 
1729
2650
}
1730
2651
 
1731
2652
 
 
2653
/**
 
2654
  Say if all variables set by a SET support the ONE_SHOT keyword
 
2655
  (currently, only character set and collation do; later timezones
 
2656
  will).
 
2657
 
 
2658
  @param var_list       List of variables to update
 
2659
 
 
2660
  @note
 
2661
    It has a "not_" because it makes faster tests (no need to "!")
 
2662
 
 
2663
  @retval
 
2664
    0   all variables of the list support ONE_SHOT
 
2665
  @retval
 
2666
    1   at least one does not support ONE_SHOT
 
2667
*/
 
2668
 
 
2669
bool not_all_support_one_shot(List<set_var_base> *var_list)
 
2670
{
 
2671
  List_iterator_fast<set_var_base> it(*var_list);
 
2672
  set_var_base *var;
 
2673
  while ((var= it++))
 
2674
  {
 
2675
    if (var->no_support_one_shot())
 
2676
      return 1;
 
2677
  }
 
2678
  return 0;
 
2679
}
 
2680
 
 
2681
 
1732
2682
/*****************************************************************************
1733
2683
  Functions to handle SET mysql_internal_variable=const_expr
1734
2684
*****************************************************************************/
1737
2687
{
1738
2688
  if (var->is_readonly())
1739
2689
  {
1740
 
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
 
2690
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
1741
2691
    return -1;
1742
2692
  }
1743
2693
  if (var->check_type(type))
1744
2694
  {
1745
2695
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
1746
 
    my_error(err, MYF(0), var->getName().c_str());
 
2696
    my_error(err, MYF(0), var->name);
1747
2697
    return -1;
1748
2698
  }
1749
2699
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
1751
2701
  {
1752
2702
    if (var->check_default(type))
1753
2703
    {
1754
 
      my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
 
2704
      my_error(ER_NO_DEFAULT, MYF(0), var->name);
1755
2705
      return -1;
1756
2706
    }
1757
2707
    return 0;
1762
2712
    return -1;
1763
2713
  if (var->check_update_type(value->result_type()))
1764
2714
  {
1765
 
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
 
2715
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
1766
2716
    return -1;
1767
2717
  }
1768
2718
  return var->check(session, this) ? -1 : 0;
1782
2732
*/
1783
2733
int set_var::update(Session *session)
1784
2734
{
1785
 
  if (! value)
 
2735
  if (!value)
1786
2736
    var->set_default(session, type);
1787
2737
  else if (var->update(session, this))
1788
2738
    return -1;                          // should never happen
1789
 
  if (var->getAfterUpdateTrigger())
1790
 
    (*var->getAfterUpdateTrigger())(session, type);
 
2739
  if (var->after_update)
 
2740
    (*var->after_update)(session, type);
1791
2741
  return 0;
1792
2742
}
1793
2743
 
 
2744
 
1794
2745
/*****************************************************************************
1795
2746
  Functions to handle SET @user_variable=const_expr
1796
2747
*****************************************************************************/
1829
2780
  const char *value;
1830
2781
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1831
2782
 
1832
 
  var->save_result.storage_engine= NULL;
 
2783
  var->save_result.plugin= NULL;
1833
2784
  if (var->value->result_type() == STRING_RESULT)
1834
2785
  {
1835
 
    res= var->value->val_str(&str);
1836
 
    if (res == NULL || res->ptr() == NULL)
 
2786
    LEX_STRING engine_name;
 
2787
    handlerton *hton;
 
2788
    if (!(res=var->value->val_str(&str)) ||
 
2789
        !(engine_name.str= (char *)res->ptr()) ||
 
2790
        !(engine_name.length= res->length()) ||
 
2791
        !(var->save_result.plugin= ha_resolve_by_name(session, &engine_name)) ||
 
2792
        !(hton= plugin_data(var->save_result.plugin, handlerton *)))
1837
2793
    {
1838
 
      value= "NULL";
 
2794
      value= res ? res->c_ptr() : "NULL";
1839
2795
      goto err;
1840
2796
    }
1841
 
    else
1842
 
    {
1843
 
      const std::string engine_name(res->ptr());
1844
 
      plugin::StorageEngine *engine;
1845
 
      var->save_result.storage_engine= plugin::StorageEngine::findByName(*session, engine_name);
1846
 
      if (var->save_result.storage_engine == NULL)
1847
 
      {
1848
 
        value= res->c_ptr();
1849
 
        goto err;
1850
 
      }
1851
 
      engine= var->save_result.storage_engine;
1852
 
    }
1853
2797
    return 0;
1854
2798
  }
1855
2799
  value= "unknown";
1861
2805
 
1862
2806
 
1863
2807
unsigned char *sys_var_session_storage_engine::value_ptr(Session *session,
1864
 
                                                         sql_var_t type,
1865
 
                                                         const LEX_STRING *)
 
2808
                                                         enum_var_type type,
 
2809
                                                         LEX_STRING *)
1866
2810
{
1867
2811
  unsigned char* result;
1868
 
  string engine_name;
1869
 
  plugin::StorageEngine *engine= session->variables.*offset;
1870
 
  if (type == OPT_GLOBAL)
1871
 
    engine= global_system_variables.*offset;
1872
 
  engine_name= engine->getName();
1873
 
  result= (unsigned char *) session->strmake(engine_name.c_str(),
1874
 
                                             engine_name.size());
 
2812
  handlerton *hton;
 
2813
  LEX_STRING *engine_name;
 
2814
  plugin_ref plugin= session->variables.*offset;
 
2815
  if (type == OPT_GLOBAL)
 
2816
    plugin= my_plugin_lock(session, &(global_system_variables.*offset));
 
2817
  hton= plugin_data(plugin, handlerton*);
 
2818
  engine_name= ha_storage_engine_name(hton);
 
2819
  result= (unsigned char *) session->strmake(engine_name->str, engine_name->length);
 
2820
  if (type == OPT_GLOBAL)
 
2821
    plugin_unlock(session, plugin);
1875
2822
  return result;
1876
2823
}
1877
2824
 
1878
2825
 
1879
 
void sys_var_session_storage_engine::set_default(Session *session, sql_var_t type)
 
2826
void sys_var_session_storage_engine::set_default(Session *session, enum_var_type type)
1880
2827
{
1881
 
  plugin::StorageEngine *old_value, *new_value, **value;
 
2828
  plugin_ref old_value, new_value, *value;
1882
2829
  if (type == OPT_GLOBAL)
1883
2830
  {
1884
2831
    value= &(global_system_variables.*offset);
1885
 
    new_value= myisam_engine;
 
2832
    new_value= ha_lock_engine(NULL, myisam_hton);
1886
2833
  }
1887
2834
  else
1888
2835
  {
1889
2836
    value= &(session->variables.*offset);
1890
 
    new_value= global_system_variables.*offset;
 
2837
    new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
1891
2838
  }
1892
2839
  assert(new_value);
1893
2840
  old_value= *value;
1894
2841
  *value= new_value;
 
2842
  plugin_unlock(NULL, old_value);
1895
2843
}
1896
2844
 
1897
2845
 
1898
2846
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
1899
2847
{
1900
 
  plugin::StorageEngine **value= &(global_system_variables.*offset), *old_value;
 
2848
  plugin_ref *value= &(global_system_variables.*offset), old_value;
1901
2849
   if (var->type != OPT_GLOBAL)
1902
2850
     value= &(session->variables.*offset);
1903
2851
  old_value= *value;
1904
 
  if (old_value != var->save_result.storage_engine)
1905
 
  {
1906
 
    *value= var->save_result.storage_engine;
1907
 
  }
1908
 
  return 0;
1909
 
}
1910
 
 
1911
 
} /* namespace drizzled */
 
2852
  if (old_value != var->save_result.plugin)
 
2853
  {
 
2854
    *value= my_plugin_lock(NULL, &var->save_result.plugin);
 
2855
    plugin_unlock(NULL, old_value);
 
2856
  }
 
2857
  return 0;
 
2858
}
 
2859
 
 
2860
bool
 
2861
sys_var_session_optimizer_switch::
 
2862
symbolic_mode_representation(Session *session, uint32_t val, LEX_STRING *rep)
 
2863
{
 
2864
  char buff[STRING_BUFFER_USUAL_SIZE*8];
 
2865
  String tmp(buff, sizeof(buff), &my_charset_utf8_general_ci);
 
2866
 
 
2867
  tmp.length(0);
 
2868
 
 
2869
  for (uint32_t i= 0; val; val>>= 1, i++)
 
2870
  {
 
2871
    if (val & 1)
 
2872
    {
 
2873
      tmp.append(optimizer_switch_typelib.type_names[i],
 
2874
                 optimizer_switch_typelib.type_lengths[i]);
 
2875
      tmp.append(',');
 
2876
    }
 
2877
  }
 
2878
 
 
2879
  if (tmp.length())
 
2880
    tmp.length(tmp.length() - 1); /* trim the trailing comma */
 
2881
 
 
2882
  rep->str= session->strmake(tmp.ptr(), tmp.length());
 
2883
 
 
2884
  rep->length= rep->str ? tmp.length() : 0;
 
2885
 
 
2886
  return rep->length != tmp.length();
 
2887
}
 
2888
 
 
2889
 
 
2890
unsigned char *sys_var_session_optimizer_switch::value_ptr(Session *session,
 
2891
                                                           enum_var_type type,
 
2892
                                                           LEX_STRING *)
 
2893
{
 
2894
  LEX_STRING opts;
 
2895
  uint64_t val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
 
2896
                  session->variables.*offset);
 
2897
  (void) symbolic_mode_representation(session, val, &opts);
 
2898
  return (unsigned char *) opts.str;
 
2899
}
 
2900
 
 
2901
 
 
2902
void sys_var_session_optimizer_switch::set_default(Session *session, enum_var_type type)
 
2903
{
 
2904
  if (type == OPT_GLOBAL)
 
2905
    global_system_variables.*offset= 0;
 
2906
  else
 
2907
    session->variables.*offset= global_system_variables.*offset;
 
2908
}
 
2909
 
 
2910
 
 
2911
/****************************************************************************
 
2912
  Named list handling
 
2913
****************************************************************************/
 
2914
 
 
2915
unsigned char* find_named(I_List<NAMED_LIST> *list, const char *name, uint32_t length,
 
2916
                NAMED_LIST **found)
 
2917
{
 
2918
  I_List_iterator<NAMED_LIST> it(*list);
 
2919
  NAMED_LIST *element;
 
2920
  while ((element= it++))
 
2921
  {
 
2922
    if (element->cmp(name, length))
 
2923
    {
 
2924
      if (found)
 
2925
        *found= element;
 
2926
      return element->data;
 
2927
    }
 
2928
  }
 
2929
  return 0;
 
2930
}
 
2931
 
 
2932
 
 
2933
void delete_elements(I_List<NAMED_LIST> *list,
 
2934
                     void (*free_element)(const char *name, unsigned char*))
 
2935
{
 
2936
  NAMED_LIST *element;
 
2937
  while ((element= list->get()))
 
2938
  {
 
2939
    (*free_element)(element->name, element->data);
 
2940
    delete element;
 
2941
  }
 
2942
  return;
 
2943
}
 
2944
 
 
2945
 
 
2946
/* Key cache functions */
 
2947
 
 
2948
static KEY_CACHE *create_key_cache(const char *name, uint32_t length)
 
2949
{
 
2950
  KEY_CACHE *key_cache;
 
2951
  
 
2952
  if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
 
2953
                                             MYF(MY_ZEROFILL | MY_WME))))
 
2954
  {
 
2955
    if (!new NAMED_LIST(&key_caches, name, length, (unsigned char*) key_cache))
 
2956
    {
 
2957
      free((char*) key_cache);
 
2958
      key_cache= 0;
 
2959
    }
 
2960
    else
 
2961
    {
 
2962
      /*
 
2963
        Set default values for a key cache
 
2964
        The values in dflt_key_cache_var is set by my_getopt() at startup
 
2965
 
 
2966
        We don't set 'buff_size' as this is used to enable the key cache
 
2967
      */
 
2968
      key_cache->param_block_size=     dflt_key_cache_var.param_block_size;
 
2969
      key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
 
2970
      key_cache->param_age_threshold=  dflt_key_cache_var.param_age_threshold;
 
2971
    }
 
2972
  }
 
2973
  return(key_cache);
 
2974
}
 
2975
 
 
2976
 
 
2977
KEY_CACHE *get_or_create_key_cache(const char *name, uint32_t length)
 
2978
{
 
2979
  LEX_STRING key_cache_name;
 
2980
  KEY_CACHE *key_cache;
 
2981
 
 
2982
  key_cache_name.str= (char *) name;
 
2983
  key_cache_name.length= length;
 
2984
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2985
  if (!(key_cache= get_key_cache(&key_cache_name)))
 
2986
    key_cache= create_key_cache(name, length);
 
2987
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2988
  return key_cache;
 
2989
}
 
2990
 
 
2991
 
 
2992
void free_key_cache(const char *, KEY_CACHE *key_cache)
 
2993
{
 
2994
  ha_end_key_cache(key_cache);
 
2995
  free((char*) key_cache);
 
2996
}
 
2997
 
 
2998
 
 
2999
bool process_key_caches(process_key_cache_t func)
 
3000
{
 
3001
  I_List_iterator<NAMED_LIST> it(key_caches);
 
3002
  NAMED_LIST *element;
 
3003
 
 
3004
  while ((element= it++))
 
3005
  {
 
3006
    KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
 
3007
    func(element->name, key_cache);
 
3008
  }
 
3009
  return 0;
 
3010
}
 
3011
 
 
3012
 
 
3013
bool sys_var_opt_readonly::update(Session *session, set_var *var)
 
3014
{
 
3015
  bool result;
 
3016
 
 
3017
  /* Prevent self dead-lock */
 
3018
  if (session->locked_tables || session->active_transaction())
 
3019
  {
 
3020
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
3021
    return(true);
 
3022
  }
 
3023
 
 
3024
  if (session->global_read_lock)
 
3025
  {
 
3026
    /*
 
3027
      This connection already holds the global read lock.
 
3028
      This can be the case with:
 
3029
      - FLUSH TABLES WITH READ LOCK
 
3030
      - SET GLOBAL READ_ONLY = 1
 
3031
    */
 
3032
    result= sys_var_bool_ptr::update(session, var);
 
3033
    return(result);
 
3034
  }
 
3035
 
 
3036
  /*
 
3037
    Perform a 'FLUSH TABLES WITH READ LOCK'.
 
3038
    This is a 3 step process:
 
3039
    - [1] lock_global_read_lock()
 
3040
    - [2] close_cached_tables()
 
3041
    - [3] make_global_read_lock_block_commit()
 
3042
    [1] prevents new connections from obtaining tables locked for write.
 
3043
    [2] waits until all existing connections close their tables.
 
3044
    [3] prevents transactions from being committed.
 
3045
  */
 
3046
 
 
3047
  if (lock_global_read_lock(session))
 
3048
    return(true);
 
3049
 
 
3050
  /*
 
3051
    This call will be blocked by any connection holding a READ or WRITE lock.
 
3052
    Ideally, we want to wait only for pending WRITE locks, but since:
 
3053
    con 1> LOCK TABLE T FOR READ;
 
3054
    con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
 
3055
    con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
 
3056
    can cause to wait on a read lock, it's required for the client application
 
3057
    to unlock everything, and acceptable for the server to wait on all locks.
 
3058
  */
 
3059
  if ((result= close_cached_tables(session, NULL, false, true, true)) == true)
 
3060
    goto end_with_read_lock;
 
3061
 
 
3062
  if ((result= make_global_read_lock_block_commit(session)) == true)
 
3063
    goto end_with_read_lock;
 
3064
 
 
3065
  /* Change the opt_readonly system variable, safe because the lock is held */
 
3066
  result= sys_var_bool_ptr::update(session, var);
 
3067
 
 
3068
end_with_read_lock:
 
3069
  /* Release the lock */
 
3070
  unlock_global_read_lock(session);
 
3071
  return(result);
 
3072
}
 
3073
 
 
3074
/****************************************************************************
 
3075
  Used templates
 
3076
****************************************************************************/
 
3077
 
 
3078
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3079
template class List<set_var_base>;
 
3080
template class List_iterator_fast<set_var_base>;
 
3081
template class I_List_iterator<NAMED_LIST>;
 
3082
#endif