~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/set_var.cc

  • Committer: Jim Winstead
  • Date: 2008-07-19 02:56:45 UTC
  • mto: (202.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 207.
  • Revision ID: jimw@mysql.com-20080719025645-w2pwytebgzusjzjb
Various fixes to enable compilation on Mac OS X, and remove the glib dependency.
Temporarily disables tab-completion in the drizzle client until an appropriate
autoconf check can be added/enabled.

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