~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Monty Taylor
  • Date: 2008-08-15 20:01:00 UTC
  • Revision ID: monty@inaugust.com-20080815200100-tht5d421maap6kjp
Updated POTFILES with local_infile.c.

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