~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Eric Herman
  • Date: 2008-12-07 15:29:44 UTC
  • mto: (656.1.14 devel)
  • mto: This revision was merged to the branch mainline in revision 670.
  • Revision ID: eric@mysql.com-20081207152944-cq1nx1cyi0huqj0f
Added pointer to online version of the FAQ

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:
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/my_getopt.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 my_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);
 
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);
146
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, pthread_rwlock_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
  pthread_rwlock_wrlock(var_mutex);
 
565
  old_value= var_str->value;
 
566
  var_str->value= res;
 
567
  var_str->value_length= new_length;
 
568
  pthread_rwlock_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)
 
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)
400
754
{
401
755
  if (type != OPT_GLOBAL)
402
756
    reset_root_defaults(session->mem_root,
405
759
}
406
760
 
407
761
 
408
 
static void fix_server_id(Session *, sql_var_t)
409
 
{
 
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;
410
775
}
411
776
 
412
777
 
413
778
bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
414
 
                          const std::string &name, int64_t val)
 
779
                          const char *name, int64_t val)
415
780
{
416
781
  if (fixed)
417
782
  {
418
783
    char buf[22];
419
784
 
420
785
    if (unsignd)
421
 
      internal::ullstr((uint64_t) val, buf);
 
786
      ullstr((uint64_t) val, buf);
422
787
    else
423
 
      internal::llstr(val, buf);
 
788
      llstr(val, buf);
424
789
 
425
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
790
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
426
791
                        ER_TRUNCATED_WRONG_VALUE,
427
 
                        ER(ER_TRUNCATED_WRONG_VALUE), name.c_str(), buf);
 
792
                        ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
428
793
  }
429
794
  return false;
430
795
}
431
796
 
432
 
uint64_t fix_unsigned(Session *session, uint64_t num,
 
797
static uint64_t fix_unsigned(Session *session, uint64_t num,
433
798
                              const struct my_option *option_limits)
434
799
{
435
800
  bool fixed= false;
450
815
  return out;
451
816
}
452
817
 
453
 
static bool get_unsigned32(Session *session, set_var *var)
454
 
{
455
 
  if (var->value->unsigned_flag)
456
 
    var->save_result.uint32_t_value= 
457
 
      static_cast<uint32_t>(var->value->val_int());
458
 
  else
459
 
  {
460
 
    int64_t v= var->value->val_int();
461
 
    if (v > UINT32_MAX)
462
 
      throw_bounds_warning(session, true, true,var->var->getName().c_str(), v);
463
 
    
464
 
    var->save_result.uint32_t_value= 
465
 
      static_cast<uint32_t>((v > UINT32_MAX) ? UINT32_MAX : (v < 0) ? 0 : v);
466
 
  }
467
 
  return false;
468
 
}
469
 
 
470
 
static bool get_unsigned64(Session *, set_var *var)
471
 
{
472
 
  if (var->value->unsigned_flag)
473
 
      var->save_result.uint64_t_value=(uint64_t) var->value->val_int();
474
 
  else
475
 
  {
476
 
    int64_t v= var->value->val_int();
477
 
      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);
478
826
  }
479
827
  return 0;
480
828
}
482
830
static bool get_size_t(Session *, set_var *var)
483
831
{
484
832
  if (var->value->unsigned_flag)
485
 
    var->save_result.size_t_value= (size_t) var->value->val_int();
486
 
  else
487
 
  {
488
 
    ssize_t v= (ssize_t)var->value->val_int();
489
 
    var->save_result.size_t_value= (size_t) ((v < 0) ? 0 : v);
490
 
  }
491
 
  return 0;
492
 
}
493
 
 
494
 
bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
495
 
{
496
 
  var->save_result.uint32_t_value= (uint32_t)var->value->val_int();
497
 
  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);
498
885
}
499
886
 
500
887
bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
502
889
  uint32_t tmp= var->save_result.uint32_t_value;
503
890
  pthread_mutex_lock(&LOCK_global_system_variables);
504
891
  if (option_limits)
505
 
  {
506
 
    uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, option_limits);
507
 
    if(newvalue==tmp)
508
 
      *value= newvalue;
509
 
  }
 
892
    *value= (uint32_t) fix_unsigned(session, tmp, option_limits);
510
893
  else
511
894
    *value= (uint32_t) tmp;
512
895
  pthread_mutex_unlock(&LOCK_global_system_variables);
514
897
}
515
898
 
516
899
 
517
 
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)
518
901
{
519
902
  bool not_used;
520
903
  pthread_mutex_lock(&LOCK_global_system_variables);
521
 
  *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value,
522
 
                                           option_limits, &not_used);
 
904
  *value= getopt_ull_limit_value((uint32_t) option_limits->def_value,
 
905
                                 option_limits, &not_used);
523
906
  pthread_mutex_unlock(&LOCK_global_system_variables);
524
907
}
525
908
 
529
912
  uint64_t tmp= var->save_result.uint64_t_value;
530
913
  pthread_mutex_lock(&LOCK_global_system_variables);
531
914
  if (option_limits)
532
 
  {
533
 
    uint64_t newvalue= (uint64_t) fix_unsigned(session, tmp, option_limits);
534
 
    if(newvalue==tmp)
535
 
      *value= newvalue;
536
 
  }
 
915
    *value= (uint64_t) fix_unsigned(session, tmp, option_limits);
537
916
  else
538
917
    *value= (uint64_t) tmp;
539
918
  pthread_mutex_unlock(&LOCK_global_system_variables);
541
920
}
542
921
 
543
922
 
544
 
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)
545
924
{
546
925
  bool not_used;
547
926
  pthread_mutex_lock(&LOCK_global_system_variables);
564
943
}
565
944
 
566
945
 
567
 
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)
568
947
{
569
948
  bool not_used;
570
949
  pthread_mutex_lock(&LOCK_global_system_variables);
580
959
}
581
960
 
582
961
 
583
 
void sys_var_bool_ptr::set_default(Session *, sql_var_t)
 
962
void sys_var_bool_ptr::set_default(Session *, enum_var_type)
584
963
{
585
964
  *value= (bool) option_limits->def_value;
586
965
}
587
966
 
588
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
 
589
987
/*
590
988
  32 bit types for session variables
591
989
*/
592
990
bool sys_var_session_uint32_t::check(Session *session, set_var *var)
593
991
{
594
 
  return (get_unsigned32(session, var) ||
 
992
  return (get_unsigned(session, var) ||
595
993
          (check_func && (*check_func)(session, var)));
596
994
}
597
995
 
598
996
bool sys_var_session_uint32_t::update(Session *session, set_var *var)
599
997
{
600
 
  uint64_t tmp= (uint64_t) var->save_result.uint32_t_value;
 
998
  uint64_t tmp= var->save_result.uint64_t_value;
601
999
 
602
1000
  /* Don't use bigger value than given with --maximum-variable-name=.. */
603
1001
  if ((uint32_t) tmp > max_system_variables.*offset)
604
1002
  {
605
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
 
1003
    throw_bounds_warning(session, true, true, name, (int64_t) tmp);
606
1004
    tmp= max_system_variables.*offset;
607
1005
  }
608
1006
 
611
1009
  else if (tmp > UINT32_MAX)
612
1010
  {
613
1011
    tmp= UINT32_MAX;
614
 
    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);
615
1013
  }
616
1014
 
617
1015
  if (var->type == OPT_GLOBAL)
623
1021
 }
624
1022
 
625
1023
 
626
 
 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)
627
1025
 {
628
1026
   if (type == OPT_GLOBAL)
629
1027
   {
639
1037
 
640
1038
 
641
1039
unsigned char *sys_var_session_uint32_t::value_ptr(Session *session,
642
 
                                                sql_var_t type,
643
 
                                                const LEX_STRING *)
 
1040
                                                enum_var_type type,
 
1041
                                                LEX_STRING *)
644
1042
{
645
1043
  if (type == OPT_GLOBAL)
646
1044
    return (unsigned char*) &(global_system_variables.*offset);
671
1069
}
672
1070
 
673
1071
 
674
 
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)
675
1073
{
676
1074
  if (type == OPT_GLOBAL)
677
1075
  {
689
1087
 
690
1088
 
691
1089
unsigned char *sys_var_session_ha_rows::value_ptr(Session *session,
692
 
                                                  sql_var_t type,
693
 
                                                  const LEX_STRING *)
 
1090
                                                  enum_var_type type,
 
1091
                                                  LEX_STRING *)
694
1092
{
695
1093
  if (type == OPT_GLOBAL)
696
1094
    return (unsigned char*) &(global_system_variables.*offset);
699
1097
 
700
1098
bool sys_var_session_uint64_t::check(Session *session, set_var *var)
701
1099
{
702
 
  return (get_unsigned64(session, var) ||
 
1100
  return (get_unsigned(session, var) ||
703
1101
          (check_func && (*check_func)(session, var)));
704
1102
}
705
1103
 
708
1106
  uint64_t tmp= var->save_result.uint64_t_value;
709
1107
 
710
1108
  if (tmp > max_system_variables.*offset)
711
 
  {
712
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
713
1109
    tmp= max_system_variables.*offset;
714
 
  }
715
1110
 
716
1111
  if (option_limits)
717
1112
    tmp= fix_unsigned(session, tmp, option_limits);
728
1123
}
729
1124
 
730
1125
 
731
 
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)
732
1127
{
733
1128
  if (type == OPT_GLOBAL)
734
1129
  {
745
1140
 
746
1141
 
747
1142
unsigned char *sys_var_session_uint64_t::value_ptr(Session *session,
748
 
                                                   sql_var_t type,
749
 
                                                   const LEX_STRING *)
 
1143
                                                   enum_var_type type,
 
1144
                                                   LEX_STRING *)
750
1145
{
751
1146
  if (type == OPT_GLOBAL)
752
1147
    return (unsigned char*) &(global_system_variables.*offset);
781
1176
}
782
1177
 
783
1178
 
784
 
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)
785
1180
{
786
1181
  if (type == OPT_GLOBAL)
787
1182
  {
788
1183
    bool not_used;
789
1184
    pthread_mutex_lock(&LOCK_global_system_variables);
790
1185
    global_system_variables.*offset=
791
 
      (size_t)getopt_ull_limit_value((size_t) option_limits->def_value,
792
 
                                     option_limits, &not_used);
 
1186
      getopt_ull_limit_value((size_t) option_limits->def_value,
 
1187
                             option_limits, &not_used);
793
1188
    pthread_mutex_unlock(&LOCK_global_system_variables);
794
1189
  }
795
1190
  else
798
1193
 
799
1194
 
800
1195
unsigned char *sys_var_session_size_t::value_ptr(Session *session,
801
 
                                                 sql_var_t type,
802
 
                                                 const LEX_STRING *)
 
1196
                                                 enum_var_type type,
 
1197
                                                 LEX_STRING *)
803
1198
{
804
1199
  if (type == OPT_GLOBAL)
805
1200
    return (unsigned char*) &(global_system_variables.*offset);
817
1212
}
818
1213
 
819
1214
 
820
 
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)
821
1216
{
822
1217
  if (type == OPT_GLOBAL)
823
1218
    global_system_variables.*offset= (bool) option_limits->def_value;
827
1222
 
828
1223
 
829
1224
unsigned char *sys_var_session_bool::value_ptr(Session *session,
830
 
                                               sql_var_t type,
831
 
                                               const LEX_STRING *)
 
1225
                                               enum_var_type type,
 
1226
                                               LEX_STRING *)
832
1227
{
833
1228
  if (type == OPT_GLOBAL)
834
1229
    return (unsigned char*) &(global_system_variables.*offset);
845
1240
 
846
1241
  if (var->value->result_type() == STRING_RESULT)
847
1242
  {
848
 
    if (!(res=var->value->val_str(&str)) ||
849
 
        (var->save_result.uint32_t_value= find_type(enum_names, res->ptr(),
850
 
                                                    res->length(),1)) == 0)
 
1243
    if (!(res=var->value->val_str(&str)))
851
1244
    {
852
1245
      value= res ? res->c_ptr() : "NULL";
853
1246
      goto err;
854
1247
    }
855
 
 
856
 
    var->save_result.uint32_t_value--;
857
1248
  }
858
1249
  else
859
1250
  {
860
1251
    uint64_t tmp=var->value->val_int();
861
1252
    if (tmp >= enum_names->count)
862
1253
    {
863
 
      internal::llstr(tmp,buff);
 
1254
      llstr(tmp,buff);
864
1255
      value=buff;                               // Wrong value is here
865
1256
      goto err;
866
1257
    }
869
1260
  return 0;
870
1261
 
871
1262
err:
872
 
  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
      strcpy(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);
873
1332
  return 1;
874
1333
}
875
1334
 
882
1341
  If type is not given, return local value if exists, else global.
883
1342
*/
884
1343
 
885
 
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)
886
1345
{
887
1346
  if (check_type(var_type))
888
1347
  {
889
1348
    if (var_type != OPT_DEFAULT)
890
1349
    {
891
1350
      my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
892
 
               name.c_str(), var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
 
1351
               name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
893
1352
      return 0;
894
1353
    }
895
1354
    /* As there was no local variable, return the global value */
930
1389
    pthread_mutex_unlock(&LOCK_global_system_variables);
931
1390
    return new Item_int((uint64_t) value);
932
1391
  }
933
 
  case SHOW_SIZE:
934
 
  {
935
 
    size_t value;
936
 
    pthread_mutex_lock(&LOCK_global_system_variables);
937
 
    value= *(size_t*) value_ptr(session, var_type, base);
938
 
    pthread_mutex_unlock(&LOCK_global_system_variables);
939
 
    return new Item_int((uint64_t) value);
940
 
  }
941
1392
  case SHOW_MY_BOOL:
942
1393
  {
943
1394
    int32_t value;
982
1433
    return tmp;
983
1434
  }
984
1435
  default:
985
 
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name.c_str());
 
1436
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
986
1437
  }
987
1438
  return 0;
988
1439
}
998
1449
}
999
1450
 
1000
1451
 
1001
 
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)
1002
1453
{
1003
1454
  if (type == OPT_GLOBAL)
1004
1455
    global_system_variables.*offset= (uint32_t) option_limits->def_value;
1008
1459
 
1009
1460
 
1010
1461
unsigned char *sys_var_session_enum::value_ptr(Session *session,
1011
 
                                               sql_var_t type,
1012
 
                                               const LEX_STRING *)
 
1462
                                               enum_var_type type,
 
1463
                                               LEX_STRING *)
1013
1464
{
1014
1465
  uint32_t tmp= ((type == OPT_GLOBAL) ?
1015
1466
              global_system_variables.*offset :
1030
1481
}
1031
1482
 
1032
1483
 
1033
 
unsigned char *sys_var_session_bit::value_ptr(Session *session, sql_var_t,
1034
 
                                              const LEX_STRING *)
 
1484
unsigned char *sys_var_session_bit::value_ptr(Session *session, enum_var_type,
 
1485
                                              LEX_STRING *)
1035
1486
{
1036
1487
  /*
1037
1488
    If reverse is 0 (default) return 1 if bit is set.
1043
1494
}
1044
1495
 
1045
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
 
1046
1601
typedef struct old_names_map_st
1047
1602
{
1048
1603
  const char *old_name;
1059
1614
    String str(buff,sizeof(buff), system_charset_info), *res;
1060
1615
    if (!(res=var->value->val_str(&str)))
1061
1616
    {
1062
 
      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");
1063
1618
      return 1;
1064
1619
    }
1065
 
    if (!(tmp=get_charset_by_name(res->c_ptr())))
 
1620
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
1066
1621
    {
1067
1622
      my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
1068
1623
      return 1;
1070
1625
  }
1071
1626
  else // INT_RESULT
1072
1627
  {
1073
 
    if (!(tmp=get_charset((int) var->value->val_int())))
 
1628
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1074
1629
    {
1075
1630
      char buf[20];
1076
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
1631
      int10_to_str((int) var->value->val_int(), buf, -10);
1077
1632
      my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1078
1633
      return 1;
1079
1634
    }
1083
1638
}
1084
1639
 
1085
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
 
1086
1696
bool sys_var_collation_sv::update(Session *session, set_var *var)
1087
1697
{
1088
1698
  if (var->type == OPT_GLOBAL)
1090
1700
  else
1091
1701
  {
1092
1702
    session->variables.*offset= var->save_result.charset;
 
1703
    session->update_charset();
1093
1704
  }
1094
1705
  return 0;
1095
1706
}
1096
1707
 
1097
1708
 
1098
 
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)
1099
1710
{
1100
1711
  if (type == OPT_GLOBAL)
1101
1712
    global_system_variables.*offset= *global_default;
1102
1713
  else
1103
1714
  {
1104
1715
    session->variables.*offset= global_system_variables.*offset;
 
1716
    session->update_charset();
1105
1717
  }
1106
1718
}
1107
1719
 
1108
1720
 
1109
1721
unsigned char *sys_var_collation_sv::value_ptr(Session *session,
1110
 
                                               sql_var_t type,
1111
 
                                               const LEX_STRING *)
 
1722
                                               enum_var_type type,
 
1723
                                               LEX_STRING *)
1112
1724
{
1113
1725
  const CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
1114
1726
                           global_system_variables.*offset :
1116
1728
  return cs ? (unsigned char*) cs->name : (unsigned char*) "NULL";
1117
1729
}
1118
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
 
 
1942
  old_value= var_str->value;
 
1943
  var_str->value= res;
 
1944
  var_str->value_length= str_length;
 
1945
  free(old_value);
 
1946
  if (log_state)
 
1947
  {
 
1948
    switch (log_type) {
 
1949
    default:
 
1950
      assert(0);
 
1951
    }
 
1952
  }
 
1953
 
 
1954
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1955
 
 
1956
err:
 
1957
  return result;
 
1958
}
 
1959
 
 
1960
 
 
1961
/*****************************************************************************
 
1962
  Functions to handle SET NAMES and SET CHARACTER SET
 
1963
*****************************************************************************/
 
1964
 
 
1965
int set_var_collation_client::check(Session *)
 
1966
{
 
1967
  /* Currently, UCS-2 cannot be used as a client character set */
 
1968
  if (character_set_client->mbminlen > 1)
 
1969
  {
 
1970
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
 
1971
             character_set_client->csname);
 
1972
    return 1;
 
1973
  }
 
1974
  return 0;
 
1975
}
 
1976
 
 
1977
int set_var_collation_client::update(Session *session)
 
1978
{
 
1979
  session->variables.character_set_client= character_set_client;
 
1980
  session->variables.character_set_results= character_set_results;
 
1981
  session->variables.collation_connection= collation_connection;
 
1982
  session->update_charset();
 
1983
  session->protocol_text.init(session);
 
1984
  return 0;
 
1985
}
 
1986
 
1119
1987
/****************************************************************************/
1120
1988
 
1121
1989
bool sys_var_timestamp::update(Session *session,  set_var *var)
1125
1993
}
1126
1994
 
1127
1995
 
1128
 
void sys_var_timestamp::set_default(Session *session, sql_var_t)
 
1996
void sys_var_timestamp::set_default(Session *session, enum_var_type)
1129
1997
{
1130
1998
  session->user_time=0;
1131
1999
}
1132
2000
 
1133
2001
 
1134
 
unsigned char *sys_var_timestamp::value_ptr(Session *session, sql_var_t,
1135
 
                                            const LEX_STRING *)
 
2002
unsigned char *sys_var_timestamp::value_ptr(Session *session, enum_var_type,
 
2003
                                            LEX_STRING *)
1136
2004
{
1137
 
  session->sys_var_tmp.int32_t_value= (int32_t) session->start_time;
1138
 
  return (unsigned char*) &session->sys_var_tmp.int32_t_value;
 
2005
  session->sys_var_tmp.long_value= (long) session->start_time;
 
2006
  return (unsigned char*) &session->sys_var_tmp.long_value;
1139
2007
}
1140
2008
 
1141
2009
 
1148
2016
 
1149
2017
 
1150
2018
unsigned char *sys_var_last_insert_id::value_ptr(Session *session,
1151
 
                                                 sql_var_t,
1152
 
                                                 const LEX_STRING *)
 
2019
                                                 enum_var_type,
 
2020
                                                 LEX_STRING *)
1153
2021
{
1154
2022
  /*
1155
2023
    this tmp var makes it robust againt change of type of
1161
2029
}
1162
2030
 
1163
2031
 
 
2032
bool sys_var_insert_id::update(Session *session, set_var *var)
 
2033
{
 
2034
  session->force_one_auto_inc_interval(var->save_result.uint64_t_value);
 
2035
  return 0;
 
2036
}
 
2037
 
 
2038
 
 
2039
unsigned char *sys_var_insert_id::value_ptr(Session *session, enum_var_type,
 
2040
                                            LEX_STRING *)
 
2041
{
 
2042
  session->sys_var_tmp.uint64_t_value=
 
2043
    session->auto_inc_intervals_forced.minimum();
 
2044
  return (unsigned char*) &session->sys_var_tmp.uint64_t_value;
 
2045
}
 
2046
 
 
2047
 
1164
2048
bool sys_var_session_time_zone::check(Session *session, set_var *var)
1165
2049
{
1166
2050
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
1192
2076
 
1193
2077
 
1194
2078
unsigned char *sys_var_session_time_zone::value_ptr(Session *session,
1195
 
                                                    sql_var_t type,
1196
 
                                                    const LEX_STRING *)
 
2079
                                                    enum_var_type type,
 
2080
                                                    LEX_STRING *)
1197
2081
{
1198
2082
  /*
1199
2083
    We can use ptr() instead of c_ptr() here because String contaning
1216
2100
}
1217
2101
 
1218
2102
 
1219
 
void sys_var_session_time_zone::set_default(Session *session, sql_var_t type)
 
2103
void sys_var_session_time_zone::set_default(Session *session, enum_var_type type)
1220
2104
{
1221
2105
 pthread_mutex_lock(&LOCK_global_system_variables);
1222
2106
 if (type == OPT_GLOBAL)
1245
2129
 
1246
2130
  if (var->value->result_type() == INT_RESULT)
1247
2131
  {
1248
 
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
 
2132
    if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
1249
2133
    {
1250
2134
      char buf[20];
1251
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
2135
      int10_to_str((int) var->value->val_int(), buf, -10);
1252
2136
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
1253
2137
      return 1;
1254
2138
    }
1259
2143
    String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1260
2144
    if (!(res=var->value->val_str(&str)))
1261
2145
    {
1262
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
2146
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1263
2147
      return 1;
1264
2148
    }
1265
2149
    const char *locale_str= res->c_ptr();
1287
2171
 
1288
2172
 
1289
2173
unsigned char *sys_var_session_lc_time_names::value_ptr(Session *session,
1290
 
                                                        sql_var_t type,
1291
 
                                                        const LEX_STRING *)
 
2174
                                                        enum_var_type type,
 
2175
                                                        LEX_STRING *)
1292
2176
{
1293
2177
  return type == OPT_GLOBAL ?
1294
2178
                 (unsigned char *) global_system_variables.lc_time_names->name :
1296
2180
}
1297
2181
 
1298
2182
 
1299
 
void sys_var_session_lc_time_names::set_default(Session *session, sql_var_t type)
 
2183
void sys_var_session_lc_time_names::set_default(Session *session, enum_var_type type)
1300
2184
{
1301
2185
  if (type == OPT_GLOBAL)
1302
2186
    global_system_variables.lc_time_names= my_default_lc_time_names;
1334
2218
}
1335
2219
 
1336
2220
 
1337
 
void sys_var_microseconds::set_default(Session *session, sql_var_t type)
 
2221
void sys_var_microseconds::set_default(Session *session, enum_var_type type)
1338
2222
{
1339
2223
  int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
1340
2224
  if (type == OPT_GLOBAL)
1347
2231
    session->variables.*offset= microseconds;
1348
2232
}
1349
2233
 
 
2234
 
 
2235
unsigned char *sys_var_microseconds::value_ptr(Session *session,
 
2236
                                               enum_var_type type,
 
2237
                                               LEX_STRING *)
 
2238
{
 
2239
  session->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
 
2240
                                   global_system_variables.*offset :
 
2241
                                   session->variables.*offset) / 1000000.0;
 
2242
  return (unsigned char*) &session->tmp_double_value;
 
2243
}
 
2244
 
 
2245
 
1350
2246
/*
1351
2247
  Functions to update session->options bits
1352
2248
*/
1378
2274
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
1379
2275
    {
1380
2276
      /* We changed to auto_commit mode */
1381
 
      session->options&= ~(uint64_t) (OPTION_BEGIN);
 
2277
      session->options&= ~(uint64_t) (OPTION_BEGIN | OPTION_KEEP_LOG);
 
2278
      session->transaction.all.modified_non_trans_table= false;
1382
2279
      session->server_status|= SERVER_STATUS_AUTOCOMMIT;
1383
 
      TransactionServices &transaction_services= TransactionServices::singleton();
1384
 
      if (transaction_services.ha_commit_trans(session, true))
1385
 
        return 1;
 
2280
      if (ha_commit(session))
 
2281
        return 1;
1386
2282
    }
1387
2283
    else
1388
2284
    {
 
2285
      session->transaction.all.modified_non_trans_table= false;
1389
2286
      session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
1390
2287
    }
1391
2288
  }
1392
2289
  return 0;
1393
2290
}
1394
2291
 
 
2292
static int check_log_update(Session *, set_var *)
 
2293
{
 
2294
  return 0;
 
2295
}
 
2296
 
 
2297
 
1395
2298
static int check_pseudo_thread_id(Session *, set_var *var)
1396
2299
{
1397
2300
  var->save_result.uint64_t_value= var->value->val_int();
1400
2303
 
1401
2304
static unsigned char *get_warning_count(Session *session)
1402
2305
{
1403
 
  session->sys_var_tmp.uint32_t_value=
 
2306
  session->sys_var_tmp.long_value=
1404
2307
    (session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE] +
1405
2308
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR] +
1406
2309
     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN]);
1407
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2310
  return (unsigned char*) &session->sys_var_tmp.long_value;
1408
2311
}
1409
2312
 
1410
2313
static unsigned char *get_error_count(Session *session)
1411
2314
{
1412
 
  session->sys_var_tmp.uint32_t_value=
 
2315
  session->sys_var_tmp.long_value=
1413
2316
    session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR];
1414
 
  return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
 
2317
  return (unsigned char*) &session->sys_var_tmp.long_value;
1415
2318
}
1416
2319
 
1417
2320
 
1431
2334
*/
1432
2335
static unsigned char *get_tmpdir(Session *)
1433
2336
{
1434
 
  assert(drizzle_tmpdir);
 
2337
  if (opt_drizzle_tmpdir)
 
2338
    return (unsigned char *)opt_drizzle_tmpdir;
1435
2339
  return (unsigned char*)drizzle_tmpdir;
1436
2340
}
1437
2341
 
1474
2378
}
1475
2379
 
1476
2380
 
 
2381
/**
 
2382
  Return variable name and length for hashing of variables.
 
2383
*/
 
2384
 
 
2385
static unsigned char *get_sys_var_length(const sys_var *var, size_t *length,
 
2386
                                         bool)
 
2387
{
 
2388
  *length= var->name_length;
 
2389
  return (unsigned char*) var->name;
 
2390
}
 
2391
 
 
2392
 
1477
2393
/*
1478
2394
  Add variables to the dynamic hash of system variables
1479
2395
 
1491
2407
int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
1492
2408
{
1493
2409
  sys_var *var;
 
2410
 
1494
2411
  /* A write lock should be held on LOCK_system_variables_hash */
1495
2412
 
1496
 
  for (var= first; var; var= var->getNext())
 
2413
  for (var= first; var; var= var->next)
1497
2414
  {
1498
 
 
1499
 
    string lower_name(var->getName());
1500
 
    transform(lower_name.begin(), lower_name.end(),
1501
 
              lower_name.begin(), ::tolower);
1502
 
 
1503
 
    /* this fails if there is a conflicting variable name. */
1504
 
    if (system_variable_map.find(lower_name) != system_variable_map.end())
1505
 
    {
1506
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Variable named %s already exists!\n"),
1507
 
                    var->getName().c_str());
1508
 
      return 1;
1509
 
    } 
1510
 
 
1511
 
    pair<SystemVariableMap::iterator, bool> ret= 
1512
 
      system_variable_map.insert(make_pair(lower_name, var));
1513
 
    if (ret.second == false)
1514
 
    {
1515
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Could not add Variable: %s\n"),
1516
 
                    var->getName().c_str());
1517
 
      return 1;
1518
 
    }
1519
 
 
 
2415
    var->name_length= strlen(var->name);
 
2416
    /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
 
2417
    if (my_hash_insert(&system_variable_hash, (unsigned char*) var))
 
2418
      goto error;
1520
2419
    if (long_options)
1521
 
      var->setOptionLimits(find_option(long_options, var->getName().c_str()));
 
2420
      var->option_limits= find_option(long_options, var->name);
1522
2421
  }
1523
2422
  return 0;
1524
2423
 
 
2424
error:
 
2425
  for (; first != var; first= first->next)
 
2426
    hash_delete(&system_variable_hash, (unsigned char*) first);
 
2427
  return 1;
1525
2428
}
1526
2429
 
1527
2430
 
1539
2442
 
1540
2443
int mysql_del_sys_var_chain(sys_var *first)
1541
2444
{
 
2445
  int result= 0;
1542
2446
 
1543
2447
  /* A write lock should be held on LOCK_system_variables_hash */
1544
 
  for (sys_var *var= first; var; var= var->getNext())
1545
 
  {
1546
 
    string lower_name(var->getName());
1547
 
    transform(lower_name.begin(), lower_name.end(),
1548
 
              lower_name.begin(), ::tolower);
1549
 
    system_variable_map.erase(lower_name);
1550
 
  }
1551
 
  return 0;
1552
 
}
1553
 
 
 
2448
 
 
2449
  for (sys_var *var= first; var; var= var->next)
 
2450
    result|= hash_delete(&system_variable_hash, (unsigned char*) var);
 
2451
 
 
2452
  return result;
 
2453
}
 
2454
 
 
2455
 
 
2456
static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
 
2457
{
 
2458
  return strcmp(a->name, b->name);
 
2459
}
1554
2460
 
1555
2461
 
1556
2462
/*
1562
2468
    sorted      If TRUE, the system variables should be sorted
1563
2469
 
1564
2470
  RETURN VALUES
1565
 
    pointer     Array of drizzle_show_var elements for display
 
2471
    pointer     Array of SHOW_VAR elements for display
1566
2472
    NULL        FAILURE
1567
2473
*/
1568
2474
 
1569
 
drizzle_show_var* enumerate_sys_vars(Session *session, bool)
 
2475
SHOW_VAR* enumerate_sys_vars(Session *session, bool sorted)
1570
2476
{
 
2477
  int count= system_variable_hash.records, i;
1571
2478
  int fixed_count= fixed_show_vars.elements;
1572
 
  int size= sizeof(drizzle_show_var) * (system_variable_map.size() + fixed_count + 1);
1573
 
  drizzle_show_var *result= (drizzle_show_var*) session->alloc(size);
 
2479
  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
 
2480
  SHOW_VAR *result= (SHOW_VAR*) session->alloc(size);
1574
2481
 
1575
2482
  if (result)
1576
2483
  {
1577
 
    drizzle_show_var *show= result + fixed_count;
1578
 
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(drizzle_show_var));
 
2484
    SHOW_VAR *show= result + fixed_count;
 
2485
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
1579
2486
 
1580
 
    SystemVariableMap::const_iterator iter= system_variable_map.begin();
1581
 
    while (iter != system_variable_map.end())
 
2487
    for (i= 0; i < count; i++)
1582
2488
    {
1583
 
      sys_var *var= (*iter).second;
1584
 
      show->name= var->getName().c_str();
 
2489
      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
 
2490
      show->name= var->name;
1585
2491
      show->value= (char*) var;
1586
2492
      show->type= SHOW_SYS;
1587
2493
      show++;
1588
 
      ++iter;
1589
2494
    }
1590
2495
 
 
2496
    /* sort into order */
 
2497
    if (sorted)
 
2498
      my_qsort(result, count + fixed_count, sizeof(SHOW_VAR),
 
2499
               (qsort_cmp) show_cmp);
 
2500
 
1591
2501
    /* make last element empty */
1592
 
    memset(show, 0, sizeof(drizzle_show_var));
 
2502
    memset(show, 0, sizeof(SHOW_VAR));
1593
2503
  }
1594
2504
  return result;
1595
2505
}
1610
2520
{
1611
2521
  uint32_t count= 0;
1612
2522
 
1613
 
  for (sys_var *var= vars.first; var; var= var->getNext(), count++) {};
 
2523
  for (sys_var *var=vars.first; var; var= var->next, count++) {};
1614
2524
 
1615
 
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(drizzle_show_var),
 
2525
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR),
1616
2526
                            FIXED_VARS_SIZE + 64, 64))
1617
2527
    goto error;
1618
2528
 
1619
2529
  fixed_show_vars.elements= FIXED_VARS_SIZE;
1620
2530
  memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
1621
2531
 
1622
 
  vars.last->setNext(NULL);
 
2532
  if (hash_init(&system_variable_hash, system_charset_info, count, 0,
 
2533
                0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
 
2534
    goto error;
 
2535
 
 
2536
  vars.last->next= NULL;
1623
2537
  if (mysql_add_sys_var_chain(vars.first, my_long_options))
1624
2538
    goto error;
1625
2539
 
1633
2547
 
1634
2548
void set_var_free()
1635
2549
{
 
2550
  hash_free(&system_variable_hash);
1636
2551
  delete_dynamic(&fixed_show_vars);
1637
2552
}
1638
2553
 
1639
2554
 
 
2555
/*
 
2556
  Add elements to the dynamic list of read-only system variables.
 
2557
 
 
2558
  SYNOPSIS
 
2559
    mysql_append_static_vars()
 
2560
    show_vars   Pointer to start of array
 
2561
    count       Number of elements
 
2562
 
 
2563
  RETURN VALUES
 
2564
    0           SUCCESS
 
2565
    otherwise   FAILURE
 
2566
*/
 
2567
int mysql_append_static_vars(const SHOW_VAR *show_vars, uint32_t count)
 
2568
{
 
2569
  for (; count > 0; count--, show_vars++)
 
2570
    if (insert_dynamic(&fixed_show_vars, (unsigned char*) show_vars))
 
2571
      return 1;
 
2572
  return 0;
 
2573
}
 
2574
 
 
2575
 
1640
2576
/**
1641
2577
  Find a user set-table variable.
1642
2578
 
1651
2587
    0           Unknown variable (error message is given)
1652
2588
*/
1653
2589
 
1654
 
sys_var *intern_find_sys_var(const char *str, uint32_t, bool no_error)
 
2590
sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error)
1655
2591
{
1656
 
  string lower_name(str);
1657
 
  transform(lower_name.begin(), lower_name.end(),
1658
 
            lower_name.begin(), ::tolower);
1659
 
 
1660
 
  sys_var *result= NULL;
1661
 
 
1662
 
  SystemVariableMap::iterator iter= system_variable_map.find(lower_name);
1663
 
  if (iter != system_variable_map.end())
1664
 
  {
1665
 
    result= (*iter).second;
1666
 
  } 
 
2592
  sys_var *var;
1667
2593
 
1668
2594
  /*
1669
2595
    This function is only called from the sql_plugin.cc.
1670
2596
    A lock on LOCK_system_variable_hash should be held
1671
2597
  */
1672
 
  if (result == NULL)
1673
 
  {
1674
 
    if (no_error)
1675
 
    {
1676
 
      return NULL;
1677
 
    }
1678
 
    else
1679
 
    {
1680
 
      my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
1681
 
      return NULL;
1682
 
    }
1683
 
  }
 
2598
  var= (sys_var*) hash_search(&system_variable_hash,
 
2599
                              (unsigned char*) str, length ? length : strlen(str));
 
2600
  if (!(var || no_error))
 
2601
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
1684
2602
 
1685
 
  return result;
 
2603
  return var;
1686
2604
}
1687
2605
 
1688
2606
 
1730
2648
}
1731
2649
 
1732
2650
 
 
2651
/**
 
2652
  Say if all variables set by a SET support the ONE_SHOT keyword
 
2653
  (currently, only character set and collation do; later timezones
 
2654
  will).
 
2655
 
 
2656
  @param var_list       List of variables to update
 
2657
 
 
2658
  @note
 
2659
    It has a "not_" because it makes faster tests (no need to "!")
 
2660
 
 
2661
  @retval
 
2662
    0   all variables of the list support ONE_SHOT
 
2663
  @retval
 
2664
    1   at least one does not support ONE_SHOT
 
2665
*/
 
2666
 
 
2667
bool not_all_support_one_shot(List<set_var_base> *var_list)
 
2668
{
 
2669
  List_iterator_fast<set_var_base> it(*var_list);
 
2670
  set_var_base *var;
 
2671
  while ((var= it++))
 
2672
  {
 
2673
    if (var->no_support_one_shot())
 
2674
      return 1;
 
2675
  }
 
2676
  return 0;
 
2677
}
 
2678
 
 
2679
 
1733
2680
/*****************************************************************************
1734
2681
  Functions to handle SET mysql_internal_variable=const_expr
1735
2682
*****************************************************************************/
1738
2685
{
1739
2686
  if (var->is_readonly())
1740
2687
  {
1741
 
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->getName().c_str(), "read only");
 
2688
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
1742
2689
    return -1;
1743
2690
  }
1744
2691
  if (var->check_type(type))
1745
2692
  {
1746
2693
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
1747
 
    my_error(err, MYF(0), var->getName().c_str());
 
2694
    my_error(err, MYF(0), var->name);
1748
2695
    return -1;
1749
2696
  }
1750
2697
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
1752
2699
  {
1753
2700
    if (var->check_default(type))
1754
2701
    {
1755
 
      my_error(ER_NO_DEFAULT, MYF(0), var->getName().c_str());
 
2702
      my_error(ER_NO_DEFAULT, MYF(0), var->name);
1756
2703
      return -1;
1757
2704
    }
1758
2705
    return 0;
1763
2710
    return -1;
1764
2711
  if (var->check_update_type(value->result_type()))
1765
2712
  {
1766
 
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->getName().c_str());
 
2713
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
1767
2714
    return -1;
1768
2715
  }
1769
2716
  return var->check(session, this) ? -1 : 0;
1783
2730
*/
1784
2731
int set_var::update(Session *session)
1785
2732
{
1786
 
  if (! value)
 
2733
  if (!value)
1787
2734
    var->set_default(session, type);
1788
2735
  else if (var->update(session, this))
1789
2736
    return -1;                          // should never happen
1790
 
  if (var->getAfterUpdateTrigger())
1791
 
    (*var->getAfterUpdateTrigger())(session, type);
 
2737
  if (var->after_update)
 
2738
    (*var->after_update)(session, type);
1792
2739
  return 0;
1793
2740
}
1794
2741
 
 
2742
 
1795
2743
/*****************************************************************************
1796
2744
  Functions to handle SET @user_variable=const_expr
1797
2745
*****************************************************************************/
1830
2778
  const char *value;
1831
2779
  String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
1832
2780
 
1833
 
  var->save_result.storage_engine= NULL;
 
2781
  var->save_result.plugin= NULL;
1834
2782
  if (var->value->result_type() == STRING_RESULT)
1835
2783
  {
1836
 
    res= var->value->val_str(&str);
1837
 
    if (res == NULL || res->ptr() == NULL)
 
2784
    LEX_STRING engine_name;
 
2785
    handlerton *hton;
 
2786
    if (!(res=var->value->val_str(&str)) ||
 
2787
        !(engine_name.str= (char *)res->ptr()) ||
 
2788
        !(engine_name.length= res->length()) ||
 
2789
        !(var->save_result.plugin= ha_resolve_by_name(session, &engine_name)) ||
 
2790
        !(hton= plugin_data(var->save_result.plugin, handlerton *)))
1838
2791
    {
1839
 
      value= "NULL";
 
2792
      value= res ? res->c_ptr() : "NULL";
1840
2793
      goto err;
1841
2794
    }
1842
 
    else
1843
 
    {
1844
 
      const std::string engine_name(res->ptr());
1845
 
      plugin::StorageEngine *engine;
1846
 
      var->save_result.storage_engine= plugin::StorageEngine::findByName(*session, engine_name);
1847
 
      if (var->save_result.storage_engine == NULL)
1848
 
      {
1849
 
        value= res->c_ptr();
1850
 
        goto err;
1851
 
      }
1852
 
      engine= var->save_result.storage_engine;
1853
 
    }
1854
2795
    return 0;
1855
2796
  }
1856
2797
  value= "unknown";
1862
2803
 
1863
2804
 
1864
2805
unsigned char *sys_var_session_storage_engine::value_ptr(Session *session,
1865
 
                                                         sql_var_t type,
1866
 
                                                         const LEX_STRING *)
 
2806
                                                         enum_var_type type,
 
2807
                                                         LEX_STRING *)
1867
2808
{
1868
2809
  unsigned char* result;
1869
 
  string engine_name;
1870
 
  plugin::StorageEngine *engine= session->variables.*offset;
1871
 
  if (type == OPT_GLOBAL)
1872
 
    engine= global_system_variables.*offset;
1873
 
  engine_name= engine->getName();
1874
 
  result= (unsigned char *) session->strmake(engine_name.c_str(),
1875
 
                                             engine_name.size());
 
2810
  handlerton *hton;
 
2811
  LEX_STRING *engine_name;
 
2812
  plugin_ref plugin= session->variables.*offset;
 
2813
  if (type == OPT_GLOBAL)
 
2814
    plugin= my_plugin_lock(session, &(global_system_variables.*offset));
 
2815
  hton= plugin_data(plugin, handlerton*);
 
2816
  engine_name= ha_storage_engine_name(hton);
 
2817
  result= (unsigned char *) session->strmake(engine_name->str, engine_name->length);
 
2818
  if (type == OPT_GLOBAL)
 
2819
    plugin_unlock(session, plugin);
1876
2820
  return result;
1877
2821
}
1878
2822
 
1879
2823
 
1880
 
void sys_var_session_storage_engine::set_default(Session *session, sql_var_t type)
 
2824
void sys_var_session_storage_engine::set_default(Session *session, enum_var_type type)
1881
2825
{
1882
 
  plugin::StorageEngine *old_value, *new_value, **value;
 
2826
  plugin_ref old_value, new_value, *value;
1883
2827
  if (type == OPT_GLOBAL)
1884
2828
  {
1885
2829
    value= &(global_system_variables.*offset);
1886
 
    new_value= myisam_engine;
 
2830
    new_value= ha_lock_engine(NULL, myisam_hton);
1887
2831
  }
1888
2832
  else
1889
2833
  {
1890
2834
    value= &(session->variables.*offset);
1891
 
    new_value= global_system_variables.*offset;
 
2835
    new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
1892
2836
  }
1893
2837
  assert(new_value);
1894
2838
  old_value= *value;
1895
2839
  *value= new_value;
 
2840
  plugin_unlock(NULL, old_value);
1896
2841
}
1897
2842
 
1898
2843
 
1899
2844
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
1900
2845
{
1901
 
  plugin::StorageEngine **value= &(global_system_variables.*offset), *old_value;
 
2846
  plugin_ref *value= &(global_system_variables.*offset), old_value;
1902
2847
   if (var->type != OPT_GLOBAL)
1903
2848
     value= &(session->variables.*offset);
1904
2849
  old_value= *value;
1905
 
  if (old_value != var->save_result.storage_engine)
1906
 
  {
1907
 
    *value= var->save_result.storage_engine;
1908
 
  }
1909
 
  return 0;
1910
 
}
1911
 
 
1912
 
} /* namespace drizzled */
 
2850
  if (old_value != var->save_result.plugin)
 
2851
  {
 
2852
    *value= my_plugin_lock(NULL, &var->save_result.plugin);
 
2853
    plugin_unlock(NULL, old_value);
 
2854
  }
 
2855
  return 0;
 
2856
}
 
2857
 
 
2858
bool
 
2859
sys_var_session_optimizer_switch::
 
2860
symbolic_mode_representation(Session *session, uint32_t val, LEX_STRING *rep)
 
2861
{
 
2862
  char buff[STRING_BUFFER_USUAL_SIZE*8];
 
2863
  String tmp(buff, sizeof(buff), &my_charset_utf8_general_ci);
 
2864
 
 
2865
  tmp.length(0);
 
2866
 
 
2867
  for (uint32_t i= 0; val; val>>= 1, i++)
 
2868
  {
 
2869
    if (val & 1)
 
2870
    {
 
2871
      tmp.append(optimizer_switch_typelib.type_names[i],
 
2872
                 optimizer_switch_typelib.type_lengths[i]);
 
2873
      tmp.append(',');
 
2874
    }
 
2875
  }
 
2876
 
 
2877
  if (tmp.length())
 
2878
    tmp.length(tmp.length() - 1); /* trim the trailing comma */
 
2879
 
 
2880
  rep->str= session->strmake(tmp.ptr(), tmp.length());
 
2881
 
 
2882
  rep->length= rep->str ? tmp.length() : 0;
 
2883
 
 
2884
  return rep->length != tmp.length();
 
2885
}
 
2886
 
 
2887
 
 
2888
unsigned char *sys_var_session_optimizer_switch::value_ptr(Session *session,
 
2889
                                                           enum_var_type type,
 
2890
                                                           LEX_STRING *)
 
2891
{
 
2892
  LEX_STRING opts;
 
2893
  uint64_t val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
 
2894
                  session->variables.*offset);
 
2895
  (void) symbolic_mode_representation(session, val, &opts);
 
2896
  return (unsigned char *) opts.str;
 
2897
}
 
2898
 
 
2899
 
 
2900
void sys_var_session_optimizer_switch::set_default(Session *session, enum_var_type type)
 
2901
{
 
2902
  if (type == OPT_GLOBAL)
 
2903
    global_system_variables.*offset= 0;
 
2904
  else
 
2905
    session->variables.*offset= global_system_variables.*offset;
 
2906
}
 
2907
 
 
2908
 
 
2909
/****************************************************************************
 
2910
  Named list handling
 
2911
****************************************************************************/
 
2912
 
 
2913
unsigned char* find_named(I_List<NAMED_LIST> *list, const char *name, uint32_t length,
 
2914
                NAMED_LIST **found)
 
2915
{
 
2916
  I_List_iterator<NAMED_LIST> it(*list);
 
2917
  NAMED_LIST *element;
 
2918
  while ((element= it++))
 
2919
  {
 
2920
    if (element->cmp(name, length))
 
2921
    {
 
2922
      if (found)
 
2923
        *found= element;
 
2924
      return element->data;
 
2925
    }
 
2926
  }
 
2927
  return 0;
 
2928
}
 
2929
 
 
2930
 
 
2931
void delete_elements(I_List<NAMED_LIST> *list,
 
2932
                     void (*free_element)(const char *name, unsigned char*))
 
2933
{
 
2934
  NAMED_LIST *element;
 
2935
  while ((element= list->get()))
 
2936
  {
 
2937
    (*free_element)(element->name, element->data);
 
2938
    delete element;
 
2939
  }
 
2940
  return;
 
2941
}
 
2942
 
 
2943
 
 
2944
/* Key cache functions */
 
2945
 
 
2946
static KEY_CACHE *create_key_cache(const char *name, uint32_t length)
 
2947
{
 
2948
  KEY_CACHE *key_cache;
 
2949
 
 
2950
  if ((key_cache= (KEY_CACHE*) malloc(sizeof(KEY_CACHE))))
 
2951
  {
 
2952
    memset(key_cache, 0, sizeof(KEY_CACHE));
 
2953
    if (!new NAMED_LIST(&key_caches, name, length, (unsigned char*) key_cache))
 
2954
    {
 
2955
      free((char*) key_cache);
 
2956
      key_cache= 0;
 
2957
    }
 
2958
    else
 
2959
    {
 
2960
      /*
 
2961
        Set default values for a key cache
 
2962
        The values in dflt_key_cache_var is set by my_getopt() at startup
 
2963
 
 
2964
        We don't set 'buff_size' as this is used to enable the key cache
 
2965
      */
 
2966
      key_cache->param_block_size=     dflt_key_cache_var.param_block_size;
 
2967
      key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
 
2968
      key_cache->param_age_threshold=  dflt_key_cache_var.param_age_threshold;
 
2969
    }
 
2970
  }
 
2971
  return(key_cache);
 
2972
}
 
2973
 
 
2974
 
 
2975
KEY_CACHE *get_or_create_key_cache(const char *name, uint32_t length)
 
2976
{
 
2977
  LEX_STRING key_cache_name;
 
2978
  KEY_CACHE *key_cache;
 
2979
 
 
2980
  key_cache_name.str= (char *) name;
 
2981
  key_cache_name.length= length;
 
2982
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2983
  if (!(key_cache= get_key_cache(&key_cache_name)))
 
2984
    key_cache= create_key_cache(name, length);
 
2985
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2986
  return key_cache;
 
2987
}
 
2988
 
 
2989
 
 
2990
void free_key_cache(const char *, KEY_CACHE *key_cache)
 
2991
{
 
2992
  ha_end_key_cache(key_cache);
 
2993
  free((char*) key_cache);
 
2994
}
 
2995
 
 
2996
 
 
2997
bool process_key_caches(process_key_cache_t func)
 
2998
{
 
2999
  I_List_iterator<NAMED_LIST> it(key_caches);
 
3000
  NAMED_LIST *element;
 
3001
 
 
3002
  while ((element= it++))
 
3003
  {
 
3004
    KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
 
3005
    func(element->name, key_cache);
 
3006
  }
 
3007
  return 0;
 
3008
}
 
3009
 
 
3010
 
 
3011
bool sys_var_opt_readonly::update(Session *session, set_var *var)
 
3012
{
 
3013
  bool result;
 
3014
 
 
3015
  /* Prevent self dead-lock */
 
3016
  if (session->locked_tables || session->active_transaction())
 
3017
  {
 
3018
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
3019
    return(true);
 
3020
  }
 
3021
 
 
3022
  if (session->global_read_lock)
 
3023
  {
 
3024
    /*
 
3025
      This connection already holds the global read lock.
 
3026
      This can be the case with:
 
3027
      - FLUSH TABLES WITH READ LOCK
 
3028
      - SET GLOBAL READ_ONLY = 1
 
3029
    */
 
3030
    result= sys_var_bool_ptr::update(session, var);
 
3031
    return(result);
 
3032
  }
 
3033
 
 
3034
  /*
 
3035
    Perform a 'FLUSH TABLES WITH READ LOCK'.
 
3036
    This is a 3 step process:
 
3037
    - [1] lock_global_read_lock()
 
3038
    - [2] close_cached_tables()
 
3039
    - [3] make_global_read_lock_block_commit()
 
3040
    [1] prevents new connections from obtaining tables locked for write.
 
3041
    [2] waits until all existing connections close their tables.
 
3042
    [3] prevents transactions from being committed.
 
3043
  */
 
3044
 
 
3045
  if (lock_global_read_lock(session))
 
3046
    return(true);
 
3047
 
 
3048
  /*
 
3049
    This call will be blocked by any connection holding a READ or WRITE lock.
 
3050
    Ideally, we want to wait only for pending WRITE locks, but since:
 
3051
    con 1> LOCK TABLE T FOR READ;
 
3052
    con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
 
3053
    con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
 
3054
    can cause to wait on a read lock, it's required for the client application
 
3055
    to unlock everything, and acceptable for the server to wait on all locks.
 
3056
  */
 
3057
  if ((result= close_cached_tables(session, NULL, false, true, true)) == true)
 
3058
    goto end_with_read_lock;
 
3059
 
 
3060
  if ((result= make_global_read_lock_block_commit(session)) == true)
 
3061
    goto end_with_read_lock;
 
3062
 
 
3063
  /* Change the opt_readonly system variable, safe because the lock is held */
 
3064
  result= sys_var_bool_ptr::update(session, var);
 
3065
 
 
3066
end_with_read_lock:
 
3067
  /* Release the lock */
 
3068
  unlock_global_read_lock(session);
 
3069
  return(result);
 
3070
}
 
3071
 
 
3072
/****************************************************************************
 
3073
  Used templates
 
3074
****************************************************************************/
 
3075
 
 
3076
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3077
template class List<set_var_base>;
 
3078
template class List_iterator_fast<set_var_base>;
 
3079
template class I_List_iterator<NAMED_LIST>;
 
3080
#endif