~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/set_var.cc

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

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