~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Brian Aker
  • Date: 2010-02-07 01:33:54 UTC
  • Revision ID: brian@gaz-20100207013354-d2pg1n68u5c09pgo
Remove giant include header to its own file.

Show diffs side-by-side

added added

removed removed

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