~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/set_var.cc

  • Committer: Monty Taylor
  • Date: 2008-07-26 16:51:58 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080726165158-qneg06kyisawnt3d
Added drizzle.pot. Not 100% on best practice here, but this seems ok.

Show diffs side-by-side

added added

removed removed

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