~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/set_var.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 17:54:00 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717175400-xm2aazihjra8mdzq
Removal of DBUG from libdrizzle/ - Round 2

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_variable sys_have_dlopen(&vars, "have_dynamic_loading", &have_dlopen);
 
588
static sys_var_have_plugin sys_have_innodb(&vars, "have_innodb", C_STRING_WITH_LEN("innodb"), MYSQL_STORAGE_ENGINE_PLUGIN);
 
589
static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
 
590
/* Global read-only variable describing server license */
 
591
static sys_var_const_str        sys_license(&vars, "license", STRINGIFY_ARG(LICENSE));
 
592
/* Global variables which enable|disable logging */
 
593
static sys_var_log_state sys_var_general_log(&vars, "general_log", &opt_log,
 
594
                                      QUERY_LOG_GENERAL);
 
595
/* Synonym of "general_log" for consistency with SHOW VARIABLES output */
 
596
static sys_var_log_state sys_var_log(&vars, "log", &opt_log, QUERY_LOG_GENERAL);
 
597
static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
 
598
                                         QUERY_LOG_SLOW);
 
599
/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
 
600
static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
 
601
                                          &opt_slow_log, QUERY_LOG_SLOW);
 
602
sys_var_str sys_var_general_log_path(&vars, "general_log_file", sys_check_log_path,
 
603
                                     sys_update_general_log_path,
 
604
                                     sys_default_general_log_path,
 
605
                                     opt_logname);
 
606
sys_var_str sys_var_slow_log_path(&vars, "slow_query_log_file", sys_check_log_path,
 
607
                                  sys_update_slow_log_path, 
 
608
                                  sys_default_slow_log_path,
 
609
                                  opt_slow_logname);
 
610
static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
 
611
                                            &log_output_typelib, 0);
 
612
 
 
613
 
 
614
/*
 
615
  Additional variables (not derived from sys_var class, not accessible as
 
616
  @@varname in SELECT or SET). Sorted in alphabetical order to facilitate
 
617
  maintenance - SHOW VARIABLES will sort its output.
 
618
  TODO: remove this list completely
 
619
*/
 
620
 
 
621
#define FIXED_VARS_SIZE (sizeof(fixed_vars) / sizeof(SHOW_VAR))
 
622
static SHOW_VAR fixed_vars[]= {
 
623
  {"back_log",                (char*) &back_log,                    SHOW_LONG},
 
624
  {"character_sets_dir",      mysql_charsets_dir,                   SHOW_CHAR},
 
625
  {"init_file",               (char*) &opt_init_file,               SHOW_CHAR_PTR},
 
626
  {"language",                language,                             SHOW_CHAR},
 
627
#ifdef HAVE_MLOCKALL
 
628
  {"locked_in_memory",        (char*) &locked_in_memory,            SHOW_MY_BOOL},
 
629
#endif
 
630
  {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
 
631
  {"log_error",               (char*) log_error_file,               SHOW_CHAR},
 
632
  {"lower_case_file_system",  (char*) &lower_case_file_system,      SHOW_MY_BOOL},
 
633
  {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_INT},
 
634
  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
 
635
  {"open_files_limit",        (char*) &open_files_limit,            SHOW_LONG},
 
636
  {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
 
637
  {"plugin_dir",              (char*) opt_plugin_dir,               SHOW_CHAR},
 
638
  {"port",                    (char*) &mysqld_port,                 SHOW_INT},
 
639
  {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
 
640
  {"skip_networking",         (char*) &opt_disable_networking,      SHOW_BOOL},
 
641
  {"skip_show_database",      (char*) &opt_skip_show_db,            SHOW_BOOL},
 
642
  {"thread_stack",            (char*) &my_thread_stack_size,        SHOW_LONG},
 
643
};
 
644
 
 
645
 
 
646
bool sys_var::check(THD *thd __attribute__((__unused__)), set_var *var)
 
647
{
 
648
  var->save_result.uint64_t_value= var->value->val_int();
334
649
  return 0;
335
650
}
336
651
 
337
 
bool sys_var_str::check(Session *session, set_var *var)
 
652
bool sys_var_str::check(THD *thd, set_var *var)
338
653
{
 
654
  int res;
339
655
  if (!check_func)
340
656
    return 0;
341
657
 
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());
 
658
  if ((res=(*check_func)(thd, var)) < 0)
 
659
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
 
660
             name, var->value->str_value.ptr());
345
661
  return res;
346
662
}
347
663
 
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
664
/*
365
665
  Functions to check and update variables
366
666
*/
367
667
 
368
668
 
 
669
/*
 
670
  Update variables 'init_connect, init_slave'.
 
671
 
 
672
  In case of 'DEFAULT' value
 
673
  (for example: 'set GLOBAL init_connect=DEFAULT')
 
674
  'var' parameter is NULL pointer.
 
675
*/
 
676
 
 
677
bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
 
678
                        set_var *var)
 
679
{
 
680
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
 
681
  uint new_length= (var ? var->value->str_value.length() : 0);
 
682
  if (!old_value)
 
683
    old_value= (char*) "";
 
684
  if (!(res= my_strndup(old_value, new_length, MYF(0))))
 
685
    return 1;
 
686
  /*
 
687
    Replace the old value in such a way that the any thread using
 
688
    the value will work.
 
689
  */
 
690
  rw_wrlock(var_mutex);
 
691
  old_value= var_str->value;
 
692
  var_str->value= res;
 
693
  var_str->value_length= new_length;
 
694
  rw_unlock(var_mutex);
 
695
  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
 
696
  return 0;
 
697
}
 
698
 
 
699
 
 
700
static bool sys_update_init_connect(THD *thd __attribute__((__unused__)), set_var *var)
 
701
{
 
702
  return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
 
703
}
 
704
 
 
705
 
 
706
static void sys_default_init_connect(THD* thd __attribute__((__unused__)),
 
707
                                     enum_var_type type __attribute__((__unused__)))
 
708
{
 
709
  update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
 
710
}
 
711
 
 
712
 
 
713
static bool sys_update_init_slave(THD *thd __attribute__((__unused__)),
 
714
                                  set_var *var)
 
715
{
 
716
  return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
 
717
}
 
718
 
 
719
 
 
720
static void sys_default_init_slave(THD* thd __attribute__((__unused__)),
 
721
                                   enum_var_type type __attribute__((__unused__)))
 
722
{
 
723
  update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
 
724
}
 
725
 
 
726
 
 
727
/**
 
728
  If one sets the LOW_PRIORIY UPDATES flag, we also must change the
 
729
  used lock type.
 
730
*/
 
731
 
 
732
static void fix_low_priority_updates(THD *thd, enum_var_type type)
 
733
{
 
734
  if (type == OPT_GLOBAL)
 
735
    thr_upgraded_concurrent_insert_lock= 
 
736
      (global_system_variables.low_priority_updates ?
 
737
       TL_WRITE_LOW_PRIORITY : TL_WRITE);
 
738
  else
 
739
    thd->update_lock_default= (thd->variables.low_priority_updates ?
 
740
                               TL_WRITE_LOW_PRIORITY : TL_WRITE);
 
741
}
 
742
 
 
743
 
 
744
static void
 
745
fix_myisam_max_sort_file_size(THD *thd __attribute__((__unused__)),
 
746
                              enum_var_type type __attribute__((__unused__)))
 
747
{
 
748
  myisam_max_temp_length=
 
749
    (my_off_t) global_system_variables.myisam_max_sort_file_size;
 
750
}
 
751
 
369
752
/**
370
753
  Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
371
754
*/
372
755
 
373
 
static void fix_max_join_size(Session *session, sql_var_t type)
 
756
static void fix_max_join_size(THD *thd, enum_var_type type)
374
757
{
375
758
  if (type != OPT_GLOBAL)
376
759
  {
377
 
    if (session->variables.max_join_size == HA_POS_ERROR)
378
 
      session->options|= OPTION_BIG_SELECTS;
 
760
    if (thd->variables.max_join_size == HA_POS_ERROR)
 
761
      thd->options|= OPTION_BIG_SELECTS;
379
762
    else
380
 
      session->options&= ~OPTION_BIG_SELECTS;
 
763
      thd->options&= ~OPTION_BIG_SELECTS;
381
764
  }
382
765
}
383
766
 
386
769
  Can't change the 'next' tx_isolation while we are already in
387
770
  a transaction
388
771
*/
389
 
static int check_tx_isolation(Session *session, set_var *var)
 
772
static int check_tx_isolation(THD *thd, set_var *var)
390
773
{
391
 
  if (var->type == OPT_DEFAULT && (session->server_status & SERVER_STATUS_IN_TRANS))
 
774
  if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
392
775
  {
393
776
    my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
394
777
    return 1;
400
783
  If one doesn't use the SESSION modifier, the isolation level
401
784
  is only active for the next command.
402
785
*/
403
 
static void fix_tx_isolation(Session *session, sql_var_t type)
 
786
static void fix_tx_isolation(THD *thd, enum_var_type type)
404
787
{
405
788
  if (type == OPT_SESSION)
406
 
    session->session_tx_isolation= ((enum_tx_isolation)
407
 
                                    session->variables.tx_isolation);
 
789
    thd->session_tx_isolation= ((enum_tx_isolation)
 
790
                                thd->variables.tx_isolation);
408
791
}
409
792
 
410
 
static void fix_completion_type(Session *, sql_var_t) {}
 
793
static void fix_completion_type(THD *thd __attribute__((unused)),
 
794
                                enum_var_type type __attribute__((unused))) {}
411
795
 
412
 
static int check_completion_type(Session *, set_var *var)
 
796
static int check_completion_type(THD *thd __attribute__((__unused__)),
 
797
                                 set_var *var)
413
798
{
414
799
  int64_t val= var->value->val_int();
415
800
  if (val < 0 || val > 2)
416
801
  {
417
802
    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)
 
803
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
 
804
    return 1;
 
805
  }
 
806
  return 0;
 
807
}
 
808
 
 
809
 
 
810
/*
 
811
  If we are changing the thread variable, we have to copy it to NET too
 
812
*/
 
813
 
 
814
#ifdef HAVE_REPLICATION
 
815
static void fix_net_read_timeout(THD *thd, enum_var_type type)
 
816
{
 
817
  if (type != OPT_GLOBAL)
 
818
    my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
 
819
}
 
820
 
 
821
 
 
822
static void fix_net_write_timeout(THD *thd, enum_var_type type)
 
823
{
 
824
  if (type != OPT_GLOBAL)
 
825
    my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
 
826
}
 
827
 
 
828
static void fix_net_retry_count(THD *thd, enum_var_type type)
 
829
{
 
830
  if (type != OPT_GLOBAL)
 
831
    thd->net.retry_count=thd->variables.net_retry_count;
 
832
}
 
833
#else /* HAVE_REPLICATION */
 
834
static void fix_net_read_timeout(THD *thd __attribute__((unused)),
 
835
                                 enum_var_type type __attribute__((unused)))
 
836
{}
 
837
static void fix_net_write_timeout(THD *thd __attribute__((unused)),
 
838
                                  enum_var_type type __attribute__((unused)))
 
839
{}
 
840
static void fix_net_retry_count(THD *thd __attribute__((unused)),
 
841
                                enum_var_type type __attribute__((unused)))
 
842
{}
 
843
#endif /* HAVE_REPLICATION */
 
844
 
 
845
 
 
846
extern void fix_delay_key_write(THD *thd __attribute__((__unused__)),
 
847
                                enum_var_type type __attribute__((__unused__)))
 
848
{
 
849
  switch ((enum_delay_key_write) delay_key_write_options) {
 
850
  case DELAY_KEY_WRITE_NONE:
 
851
    myisam_delay_key_write=0;
 
852
    break;
 
853
  case DELAY_KEY_WRITE_ON:
 
854
    myisam_delay_key_write=1;
 
855
    break;
 
856
  case DELAY_KEY_WRITE_ALL:
 
857
    myisam_delay_key_write=1;
 
858
    ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
 
859
    break;
 
860
  }
 
861
}
 
862
 
 
863
bool sys_var_set::update(THD *thd __attribute__((__unused__)),
 
864
                         set_var *var)
 
865
{
 
866
  *value= var->save_result.ulong_value;
 
867
  return 0;
 
868
}
 
869
 
 
870
uchar *sys_var_set::value_ptr(THD *thd,
 
871
                              enum_var_type type __attribute__((__unused__)),
 
872
                              LEX_STRING *base __attribute__((__unused__)))
 
873
{
 
874
  char buff[256];
 
875
  String tmp(buff, sizeof(buff), &my_charset_latin1);
 
876
  ulong length;
 
877
  ulong val= *value;
 
878
 
 
879
  tmp.length(0);
 
880
  for (uint i= 0; val; val>>= 1, i++)
 
881
  {
 
882
    if (val & 1)
 
883
    {
 
884
      tmp.append(enum_names->type_names[i],
 
885
                 enum_names->type_lengths[i]);
 
886
      tmp.append(',');
 
887
    }
 
888
  }
 
889
 
 
890
  if ((length= tmp.length()))
 
891
    length--;
 
892
  return (uchar*) thd->strmake(tmp.ptr(), length);
 
893
}
 
894
 
 
895
void sys_var_set_slave_mode::set_default(THD *thd __attribute__((__unused__)),
 
896
                                         enum_var_type type __attribute__((__unused__)))
 
897
{
 
898
  slave_exec_mode_options= 0;
 
899
  bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
 
900
}
 
901
 
 
902
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
 
903
{
 
904
  bool rc=  sys_var_set::check(thd, var);
 
905
  if (!rc &&
 
906
      bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 &&
 
907
      bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
908
  {
 
909
    rc= true;
 
910
    my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
 
911
  }
 
912
  return rc;
 
913
}
 
914
 
 
915
bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
 
916
{
 
917
  bool rc;
 
918
  pthread_mutex_lock(&LOCK_global_system_variables);
 
919
  rc= sys_var_set::update(thd, var);
 
920
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
921
  return rc;
 
922
}
 
923
 
 
924
void fix_slave_exec_mode(enum_var_type type __attribute__((__unused__)))
 
925
{
 
926
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 &&
 
927
      bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
928
  {
 
929
    sql_print_error("Ambiguous slave modes combination."
 
930
                    " STRICT will be used");
 
931
    bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT);
 
932
  }
 
933
  if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
 
934
    bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
 
935
}
 
936
 
 
937
bool sys_var_thd_binlog_format::is_readonly() const
 
938
{
 
939
  /*
 
940
    Under certain circumstances, the variable is read-only (unchangeable):
 
941
  */
 
942
  THD *thd= current_thd;
 
943
  /*
 
944
    If RBR and open temporary tables, their CREATE TABLE may not be in the
 
945
    binlog, so we can't toggle to SBR in this connection.
 
946
    The test below will also prevent SET GLOBAL, well it was not easy to test
 
947
    if global or not here.
 
948
    And this test will also prevent switching from RBR to RBR (a no-op which
 
949
    should not happen too often).
 
950
 
 
951
    If we don't have row-based replication compiled in, the variable
 
952
    is always read-only.
 
953
  */
 
954
  if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
 
955
      thd->temporary_tables)
 
956
  {
 
957
    my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
 
958
    return 1;
 
959
  }
 
960
  /*
 
961
    if in a stored function/trigger, it's too late to change mode
 
962
  */
 
963
  if (thd->in_sub_stmt)
 
964
  {
 
965
    my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
 
966
    return 1;    
 
967
  }
 
968
  return sys_var_thd_enum::is_readonly();
 
969
}
 
970
 
 
971
 
 
972
void fix_binlog_format_after_update(THD *thd,
 
973
                                    enum_var_type type __attribute__((__unused__)))
 
974
{
 
975
  thd->reset_current_stmt_binlog_row_based();
 
976
}
 
977
 
 
978
 
 
979
static void fix_max_binlog_size(THD *thd __attribute__((__unused__)),
 
980
                                enum_var_type type __attribute__((__unused__)))
 
981
{
 
982
  mysql_bin_log.set_max_size(max_binlog_size);
 
983
#ifdef HAVE_REPLICATION
 
984
  if (!max_relay_log_size)
 
985
    active_mi->rli.relay_log.set_max_size(max_binlog_size);
 
986
#endif
 
987
  return;
 
988
}
 
989
 
 
990
static void fix_max_relay_log_size(THD *thd __attribute__((__unused__)),
 
991
                                   enum_var_type type __attribute__((__unused__)))
 
992
{
 
993
#ifdef HAVE_REPLICATION
 
994
  active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
 
995
                                        max_relay_log_size: max_binlog_size);
 
996
#endif
 
997
  return;
 
998
}
 
999
 
 
1000
static void fix_max_connections(THD *thd __attribute__((__unused__)),
 
1001
                                enum_var_type type __attribute__((__unused__)))
 
1002
{
 
1003
  resize_thr_alarm(max_connections +  10);
 
1004
}
 
1005
 
 
1006
 
 
1007
static void fix_thd_mem_root(THD *thd, enum_var_type type)
 
1008
{
 
1009
  if (type != OPT_GLOBAL)
 
1010
    reset_root_defaults(thd->mem_root,
 
1011
                        thd->variables.query_alloc_block_size,
 
1012
                        thd->variables.query_prealloc_size);
 
1013
}
 
1014
 
 
1015
 
 
1016
static void fix_trans_mem_root(THD *thd, enum_var_type type)
 
1017
{
 
1018
  if (type != OPT_GLOBAL)
 
1019
    reset_root_defaults(&thd->transaction.mem_root,
 
1020
                        thd->variables.trans_alloc_block_size,
 
1021
                        thd->variables.trans_prealloc_size);
 
1022
}
 
1023
 
 
1024
 
 
1025
static void fix_server_id(THD *thd __attribute__((__unused__)),
 
1026
                          enum_var_type type __attribute__((__unused__)))
 
1027
{
 
1028
  server_id_supplied = 1;
 
1029
  thd->server_id= server_id;
 
1030
}
 
1031
 
 
1032
 
 
1033
bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
 
1034
                          const char *name, int64_t val)
440
1035
{
441
1036
  if (fixed)
442
1037
  {
443
 
    char buf[DECIMAL_LONGLONG_DIGITS];
 
1038
    char buf[22];
444
1039
 
445
1040
    if (unsignd)
446
 
      internal::ullstr((uint64_t) val, buf);
 
1041
      ullstr((uint64_t) val, buf);
447
1042
    else
448
 
      internal::llstr(val, buf);
 
1043
      llstr(val, buf);
449
1044
 
450
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
1045
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
451
1046
                        ER_TRUNCATED_WRONG_VALUE,
452
 
                        ER(ER_TRUNCATED_WRONG_VALUE), name.c_str(), buf);
 
1047
                        ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
453
1048
  }
454
1049
  return false;
455
1050
}
456
1051
 
457
 
uint64_t fix_unsigned(Session *session, uint64_t num,
458
 
                              const struct option *option_limits)
 
1052
static uint64_t fix_unsigned(THD *thd, uint64_t num,
 
1053
                              const struct my_option *option_limits)
459
1054
{
460
1055
  bool fixed= false;
461
1056
  uint64_t out= getopt_ull_limit_value(num, option_limits, &fixed);
462
1057
 
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,
 
1058
  throw_bounds_warning(thd, fixed, true, option_limits->name, (int64_t) num);
 
1059
  return out;
 
1060
}
 
1061
 
 
1062
static bool get_unsigned(THD *thd __attribute__((__unused__)), set_var *var)
 
1063
{
 
1064
  if (var->value->unsigned_flag)
 
1065
    var->save_result.uint64_t_value= (uint64_t) var->value->val_int();
 
1066
  else
 
1067
  {
 
1068
    int64_t v= var->value->val_int();
 
1069
    var->save_result.uint64_t_value= (uint64_t) ((v < 0) ? 0 : v);
 
1070
  }
 
1071
  return 0;
 
1072
}
 
1073
 
 
1074
 
 
1075
sys_var_long_ptr::
 
1076
sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
 
1077
                 sys_after_update_func after_update_arg)
 
1078
  :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
 
1079
                           &LOCK_global_system_variables, after_update_arg)
 
1080
{}
 
1081
 
 
1082
 
 
1083
bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
 
1084
{
 
1085
  return get_unsigned(thd, var);
 
1086
}
 
1087
 
 
1088
bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
 
1089
{
 
1090
  uint64_t tmp= var->save_result.uint64_t_value;
 
1091
  pthread_mutex_lock(guard);
 
1092
  if (option_limits)
 
1093
    *value= (ulong) fix_unsigned(thd, tmp, option_limits);
 
1094
  else
 
1095
  {
 
1096
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
1097
    /* Avoid overflows on 32 bit systems */
 
1098
    if (tmp > ULONG_MAX)
 
1099
    {
 
1100
      tmp= ULONG_MAX;
 
1101
      throw_bounds_warning(thd, true, true, name,
 
1102
                           (int64_t) var->save_result.uint64_t_value);
 
1103
    }
 
1104
#endif
 
1105
    *value= (ulong) tmp;
 
1106
  }
 
1107
 
 
1108
  pthread_mutex_unlock(guard);
 
1109
  return 0;
 
1110
}
 
1111
 
 
1112
 
 
1113
void sys_var_long_ptr_global::set_default(THD *thd __attribute__((__unused__)), enum_var_type type __attribute__((__unused__)))
 
1114
{
 
1115
  bool not_used;
 
1116
  pthread_mutex_lock(guard);
 
1117
  *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
569
1118
                                         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
 
 
 
1119
  pthread_mutex_unlock(guard);
 
1120
}
 
1121
 
 
1122
 
 
1123
bool sys_var_uint64_t_ptr::update(THD *thd, set_var *var)
 
1124
{
 
1125
  uint64_t tmp= var->save_result.uint64_t_value;
 
1126
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1127
  if (option_limits)
 
1128
    *value= (uint64_t) fix_unsigned(thd, tmp, option_limits);
 
1129
  else
 
1130
    *value= (uint64_t) tmp;
 
1131
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1132
  return 0;
 
1133
}
 
1134
 
 
1135
 
 
1136
void sys_var_uint64_t_ptr::set_default(THD *thd __attribute__((__unused__)),
 
1137
                                        enum_var_type type __attribute__((__unused__)))
 
1138
{
 
1139
  bool not_used;
 
1140
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1141
  *value= getopt_ull_limit_value((uint64_t) option_limits->def_value,
 
1142
                                 option_limits, &not_used);
 
1143
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
1144
}
 
1145
 
 
1146
 
 
1147
bool sys_var_bool_ptr::update(THD *thd __attribute__((__unused__)), set_var *var)
 
1148
{
 
1149
  *value= (bool) var->save_result.ulong_value;
 
1150
  return 0;
 
1151
}
 
1152
 
 
1153
 
 
1154
void sys_var_bool_ptr::set_default(THD *thd __attribute__((__unused__)), enum_var_type type __attribute__((__unused__)))
 
1155
{
 
1156
  *value= (bool) option_limits->def_value;
 
1157
}
 
1158
 
 
1159
 
 
1160
bool sys_var_enum::update(THD *thd __attribute__((__unused__)), set_var *var)
 
1161
{
 
1162
  *value= (uint) var->save_result.ulong_value;
 
1163
  return 0;
 
1164
}
 
1165
 
 
1166
 
 
1167
uchar *sys_var_enum::value_ptr(THD *thd __attribute__((__unused__)),
 
1168
                               enum_var_type type __attribute__((__unused__)),
 
1169
                               LEX_STRING *base __attribute__((__unused__)))
 
1170
{
 
1171
  return (uchar*) enum_names->type_names[*value];
 
1172
}
 
1173
 
 
1174
 
 
1175
uchar *sys_var_enum_const::value_ptr(THD *thd __attribute__((__unused__)),
 
1176
                                     enum_var_type type __attribute__((__unused__)),
 
1177
                                     LEX_STRING *base __attribute__((__unused__)))
 
1178
{
 
1179
  return (uchar*) enum_names->type_names[global_system_variables.*offset];
 
1180
}
 
1181
 
 
1182
bool sys_var_thd_ulong::check(THD *thd, set_var *var)
 
1183
{
 
1184
  return (get_unsigned(thd, var) ||
 
1185
          (check_func && (*check_func)(thd, var)));
 
1186
}
 
1187
 
 
1188
bool sys_var_thd_ulong::update(THD *thd, set_var *var)
 
1189
{
 
1190
  uint64_t tmp= var->save_result.uint64_t_value;
 
1191
  
603
1192
  /* Don't use bigger value than given with --maximum-variable-name=.. */
604
 
  if ((uint32_t) tmp > max_system_variables.*offset)
 
1193
  if ((ulong) tmp > max_system_variables.*offset)
605
1194
  {
606
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
 
1195
    throw_bounds_warning(thd, true, true, name, (int64_t) tmp);
607
1196
    tmp= max_system_variables.*offset;
608
1197
  }
609
 
 
 
1198
  
610
1199
  if (option_limits)
611
 
    tmp= (uint32_t) fix_unsigned(session, tmp, option_limits);
612
 
  else if (tmp > UINT32_MAX)
 
1200
    tmp= (ulong) fix_unsigned(thd, tmp, option_limits);
 
1201
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
1202
  else if (tmp > ULONG_MAX)
613
1203
  {
614
 
    tmp= UINT32_MAX;
615
 
    throw_bounds_warning(session, true, true, getName(), int64_t(var->getInteger()));
 
1204
    tmp= ULONG_MAX;
 
1205
    throw_bounds_warning(thd, true, true, name, (int64_t) var->save_result.uint64_t_value);
616
1206
  }
617
 
 
 
1207
#endif
 
1208
  
618
1209
  if (var->type == OPT_GLOBAL)
619
 
     global_system_variables.*offset= (uint32_t) tmp;
 
1210
     global_system_variables.*offset= (ulong) tmp;
620
1211
   else
621
 
     session->variables.*offset= (uint32_t) tmp;
 
1212
     thd->variables.*offset= (ulong) tmp;
622
1213
 
623
1214
   return 0;
624
1215
 }
625
1216
 
626
1217
 
627
 
 void sys_var_session_uint32_t::set_default(Session *session, sql_var_t type)
 
1218
 void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
628
1219
 {
629
1220
   if (type == OPT_GLOBAL)
630
1221
   {
631
1222
     bool not_used;
632
1223
     /* We will not come here if option_limits is not set */
633
1224
     global_system_variables.*offset=
634
 
       (uint32_t) getopt_ull_limit_value((uint32_t) option_limits->def_value,
 
1225
       (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
635
1226
                                      option_limits, &not_used);
636
1227
   }
637
1228
   else
638
 
     session->variables.*offset= global_system_variables.*offset;
 
1229
     thd->variables.*offset= global_system_variables.*offset;
639
1230
 }
640
1231
 
641
1232
 
642
 
unsigned char *sys_var_session_uint32_t::value_ptr(Session *session,
643
 
                                                sql_var_t type,
644
 
                                                const LEX_STRING *)
 
1233
uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
 
1234
                                    LEX_STRING *base __attribute__((__unused__)))
645
1235
{
646
1236
  if (type == OPT_GLOBAL)
647
 
    return (unsigned char*) &(global_system_variables.*offset);
648
 
  return (unsigned char*) &(session->variables.*offset);
 
1237
    return (uchar*) &(global_system_variables.*offset);
 
1238
  return (uchar*) &(thd->variables.*offset);
649
1239
}
650
1240
 
651
1241
 
652
 
bool sys_var_session_ha_rows::update(Session *session, set_var *var)
 
1242
bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
653
1243
{
654
 
  uint64_t tmp= var->getInteger();
 
1244
  uint64_t tmp= var->save_result.uint64_t_value;
655
1245
 
656
1246
  /* Don't use bigger value than given with --maximum-variable-name=.. */
657
1247
  if ((ha_rows) tmp > max_system_variables.*offset)
658
1248
    tmp= max_system_variables.*offset;
659
1249
 
660
1250
  if (option_limits)
661
 
    tmp= (ha_rows) fix_unsigned(session, tmp, option_limits);
 
1251
    tmp= (ha_rows) fix_unsigned(thd, tmp, option_limits);
662
1252
  if (var->type == OPT_GLOBAL)
663
1253
  {
664
1254
    /* Lock is needed to make things safe on 32 bit systems */
665
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1255
    pthread_mutex_lock(&LOCK_global_system_variables);    
666
1256
    global_system_variables.*offset= (ha_rows) tmp;
 
1257
    pthread_mutex_unlock(&LOCK_global_system_variables);
667
1258
  }
668
1259
  else
669
 
  {
670
 
    session->variables.*offset= (ha_rows) tmp;
671
 
  }
672
 
 
 
1260
    thd->variables.*offset= (ha_rows) tmp;
673
1261
  return 0;
674
1262
}
675
1263
 
676
1264
 
677
 
void sys_var_session_ha_rows::set_default(Session *session, sql_var_t type)
 
1265
void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
678
1266
{
679
1267
  if (type == OPT_GLOBAL)
680
1268
  {
681
1269
    bool not_used;
682
1270
    /* We will not come here if option_limits is not set */
683
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1271
    pthread_mutex_lock(&LOCK_global_system_variables);
684
1272
    global_system_variables.*offset=
685
1273
      (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
686
1274
                                       option_limits, &not_used);
 
1275
    pthread_mutex_unlock(&LOCK_global_system_variables);
687
1276
  }
688
1277
  else
689
 
  {
690
 
    session->variables.*offset= global_system_variables.*offset;
691
 
  }
 
1278
    thd->variables.*offset= global_system_variables.*offset;
692
1279
}
693
1280
 
694
1281
 
695
 
unsigned char *sys_var_session_ha_rows::value_ptr(Session *session,
696
 
                                                  sql_var_t type,
697
 
                                                  const LEX_STRING *)
 
1282
uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
 
1283
                                      LEX_STRING *base __attribute__((__unused__)))
698
1284
{
699
1285
  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();
 
1286
    return (uchar*) &(global_system_variables.*offset);
 
1287
  return (uchar*) &(thd->variables.*offset);
 
1288
}
 
1289
 
 
1290
bool sys_var_thd_uint64_t::check(THD *thd, set_var *var)
 
1291
{
 
1292
  return get_unsigned(thd, var);
 
1293
}
 
1294
 
 
1295
bool sys_var_thd_uint64_t::update(THD *thd,  set_var *var)
 
1296
{
 
1297
  uint64_t tmp= var->save_result.uint64_t_value;
713
1298
 
714
1299
  if (tmp > max_system_variables.*offset)
715
 
  {
716
 
    throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
717
1300
    tmp= max_system_variables.*offset;
718
 
  }
719
1301
 
720
1302
  if (option_limits)
721
 
    tmp= fix_unsigned(session, tmp, option_limits);
 
1303
    tmp= fix_unsigned(thd, tmp, option_limits);
722
1304
  if (var->type == OPT_GLOBAL)
723
1305
  {
724
1306
    /* Lock is needed to make things safe on 32 bit systems */
725
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1307
    pthread_mutex_lock(&LOCK_global_system_variables);
726
1308
    global_system_variables.*offset= (uint64_t) tmp;
 
1309
    pthread_mutex_unlock(&LOCK_global_system_variables);
727
1310
  }
728
1311
  else
729
 
  {
730
 
    session->variables.*offset= (uint64_t) tmp;
731
 
  }
732
 
 
 
1312
    thd->variables.*offset= (uint64_t) tmp;
733
1313
  return 0;
734
1314
}
735
1315
 
736
1316
 
737
 
void sys_var_session_uint64_t::set_default(Session *session, sql_var_t type)
 
1317
void sys_var_thd_uint64_t::set_default(THD *thd, enum_var_type type)
738
1318
{
739
1319
  if (type == OPT_GLOBAL)
740
1320
  {
741
1321
    bool not_used;
742
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
1322
    pthread_mutex_lock(&LOCK_global_system_variables);
743
1323
    global_system_variables.*offset=
744
1324
      getopt_ull_limit_value((uint64_t) option_limits->def_value,
745
1325
                             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 *,
 
1326
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
1327
  }
 
1328
  else
 
1329
    thd->variables.*offset= global_system_variables.*offset;
 
1330
}
 
1331
 
 
1332
 
 
1333
uchar *sys_var_thd_uint64_t::value_ptr(THD *thd, enum_var_type type,
 
1334
                                        LEX_STRING *base __attribute__((__unused__)))
 
1335
{
 
1336
  if (type == OPT_GLOBAL)
 
1337
    return (uchar*) &(global_system_variables.*offset);
 
1338
  return (uchar*) &(thd->variables.*offset);
 
1339
}
 
1340
 
 
1341
 
 
1342
bool sys_var_thd_bool::update(THD *thd,  set_var *var)
 
1343
{
 
1344
  if (var->type == OPT_GLOBAL)
 
1345
    global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
 
1346
  else
 
1347
    thd->variables.*offset= (my_bool) var->save_result.ulong_value;
 
1348
  return 0;
 
1349
}
 
1350
 
 
1351
 
 
1352
void sys_var_thd_bool::set_default(THD *thd,  enum_var_type type)
 
1353
{
 
1354
  if (type == OPT_GLOBAL)
 
1355
    global_system_variables.*offset= (my_bool) option_limits->def_value;
 
1356
  else
 
1357
    thd->variables.*offset= global_system_variables.*offset;
 
1358
}
 
1359
 
 
1360
 
 
1361
uchar *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
 
1362
                                   LEX_STRING *base __attribute__((__unused__)))
 
1363
{
 
1364
  if (type == OPT_GLOBAL)
 
1365
    return (uchar*) &(global_system_variables.*offset);
 
1366
  return (uchar*) &(thd->variables.*offset);
 
1367
}
 
1368
 
 
1369
 
 
1370
bool sys_var::check_enum(THD *thd __attribute__((__unused__)),
855
1371
                         set_var *var, const TYPELIB *enum_names)
856
1372
{
857
1373
  char buff[STRING_BUFFER_USUAL_SIZE];
860
1376
 
861
1377
  if (var->value->result_type() == STRING_RESULT)
862
1378
  {
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);
 
1379
    if (!(res=var->value->val_str(&str)) ||
 
1380
        ((long) (var->save_result.ulong_value=
 
1381
                 (ulong) find_type(enum_names, res->ptr(),
 
1382
                                   res->length(),1)-1)) < 0)
 
1383
    {
 
1384
      value= res ? res->c_ptr() : "NULL";
 
1385
      goto err;
 
1386
    }
877
1387
  }
878
1388
  else
879
1389
  {
880
 
    uint64_t tmp= var->value->val_int();
 
1390
    uint64_t tmp=var->value->val_int();
881
1391
    if (tmp >= enum_names->count)
882
1392
    {
883
 
      internal::llstr(tmp,buff);
 
1393
      llstr(tmp,buff);
884
1394
      value=buff;                               // Wrong value is here
885
1395
      goto err;
886
1396
    }
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);
 
1397
    var->save_result.ulong_value= (ulong) tmp;  // Save for update
 
1398
  }
 
1399
  return 0;
 
1400
 
 
1401
err:
 
1402
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
 
1403
  return 1;
 
1404
}
 
1405
 
 
1406
 
 
1407
bool sys_var::check_set(THD *thd __attribute__((__unused__)),
 
1408
                        set_var *var, TYPELIB *enum_names)
 
1409
{
 
1410
  bool not_used;
 
1411
  char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
 
1412
  uint error_len= 0;
 
1413
  String str(buff, sizeof(buff), system_charset_info), *res;
 
1414
 
 
1415
  if (var->value->result_type() == STRING_RESULT)
 
1416
  {
 
1417
    if (!(res= var->value->val_str(&str)))
 
1418
    {
 
1419
      strmov(buff, "NULL");
 
1420
      goto err;
 
1421
    }
 
1422
 
 
1423
    if (!m_allow_empty_value &&
 
1424
        res->length() == 0)
 
1425
    {
 
1426
      buff[0]= 0;
 
1427
      goto err;
 
1428
    }
 
1429
 
 
1430
    var->save_result.ulong_value= ((ulong)
 
1431
                                   find_set(enum_names, res->c_ptr(),
 
1432
                                            res->length(),
 
1433
                                            NULL,
 
1434
                                            &error, &error_len,
 
1435
                                            &not_used));
 
1436
    if (error_len)
 
1437
    {
 
1438
      strmake(buff, error, min(sizeof(buff) - 1, error_len));
 
1439
      goto err;
 
1440
    }
 
1441
  }
 
1442
  else
 
1443
  {
 
1444
    uint64_t tmp= var->value->val_int();
 
1445
 
 
1446
    if (!m_allow_empty_value &&
 
1447
        tmp == 0)
 
1448
    {
 
1449
      buff[0]= '0';
 
1450
      buff[1]= 0;
 
1451
      goto err;
 
1452
    }
 
1453
 
 
1454
    /*
 
1455
      For when the enum is made to contain 64 elements, as 1ULL<<64 is
 
1456
      undefined, we guard with a "count<64" test.
 
1457
    */
 
1458
    if (unlikely((tmp >= ((1ULL) << enum_names->count)) &&
 
1459
                 (enum_names->count < 64)))
 
1460
    {
 
1461
      llstr(tmp, buff);
 
1462
      goto err;
 
1463
    }
 
1464
    var->save_result.ulong_value= (ulong) tmp;  // Save for update
 
1465
  }
 
1466
  return 0;
 
1467
 
 
1468
err:
 
1469
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
893
1470
  return 1;
894
1471
}
895
1472
 
902
1479
  If type is not given, return local value if exists, else global.
903
1480
*/
904
1481
 
905
 
Item *sys_var::item(Session *session, sql_var_t var_type, const LEX_STRING *base)
 
1482
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
906
1483
{
907
1484
  if (check_type(var_type))
908
1485
  {
909
1486
    if (var_type != OPT_DEFAULT)
910
1487
    {
911
1488
      my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
912
 
               name.c_str(), var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
 
1489
               name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
913
1490
      return 0;
914
1491
    }
915
1492
    /* As there was no local variable, return the global value */
916
1493
    var_type= OPT_GLOBAL;
917
1494
  }
918
1495
  switch (show_type()) {
 
1496
  case SHOW_INT:
 
1497
  {
 
1498
    uint value;
 
1499
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1500
    value= *(uint*) value_ptr(thd, var_type, base);
 
1501
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
1502
    return new Item_uint((uint64_t) value);
 
1503
  }
919
1504
  case SHOW_LONG:
920
 
  case SHOW_INT:
921
1505
  {
922
 
    uint32_t value;
923
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
924
 
    value= *(uint*) value_ptr(session, var_type, base);
925
 
 
 
1506
    ulong value;
 
1507
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1508
    value= *(ulong*) value_ptr(thd, var_type, base);
 
1509
    pthread_mutex_unlock(&LOCK_global_system_variables);
926
1510
    return new Item_uint((uint64_t) value);
927
1511
  }
928
1512
  case SHOW_LONGLONG:
929
1513
  {
930
1514
    int64_t value;
931
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
932
 
    value= *(int64_t*) value_ptr(session, var_type, base);
933
 
 
 
1515
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1516
    value= *(int64_t*) value_ptr(thd, var_type, base);
 
1517
    pthread_mutex_unlock(&LOCK_global_system_variables);
934
1518
    return new Item_int(value);
935
1519
  }
936
1520
  case SHOW_DOUBLE:
937
1521
  {
938
1522
    double value;
939
 
    {
940
 
      boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
941
 
      value= *(double*) value_ptr(session, var_type, base);
942
 
    }
943
 
 
 
1523
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1524
    value= *(double*) value_ptr(thd, var_type, base);
 
1525
    pthread_mutex_unlock(&LOCK_global_system_variables);
944
1526
    /* 6, as this is for now only used with microseconds */
945
1527
    return new Item_float(value, 6);
946
1528
  }
947
1529
  case SHOW_HA_ROWS:
948
1530
  {
949
1531
    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
 
 
 
1532
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1533
    value= *(ha_rows*) value_ptr(thd, var_type, base);
 
1534
    pthread_mutex_unlock(&LOCK_global_system_variables);
961
1535
    return new Item_int((uint64_t) value);
962
1536
  }
963
1537
  case SHOW_MY_BOOL:
964
1538
  {
965
 
    int32_t value;
966
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
967
 
    value= *(bool*) value_ptr(session, var_type, base);
 
1539
    int32 value;
 
1540
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1541
    value= *(my_bool*) value_ptr(thd, var_type, base);
 
1542
    pthread_mutex_unlock(&LOCK_global_system_variables);
968
1543
    return new Item_int(value,1);
969
1544
  }
970
1545
  case SHOW_CHAR_PTR:
971
1546
  {
972
1547
    Item *tmp;
973
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
974
 
    char *str= *(char**) value_ptr(session, var_type, base);
 
1548
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1549
    char *str= *(char**) value_ptr(thd, var_type, base);
975
1550
    if (str)
976
1551
    {
977
 
      uint32_t length= strlen(str);
978
 
      tmp= new Item_string(session->strmake(str, length), length,
 
1552
      uint length= strlen(str);
 
1553
      tmp= new Item_string(thd->strmake(str, length), length,
979
1554
                           system_charset_info, DERIVATION_SYSCONST);
980
1555
    }
981
1556
    else
983
1558
      tmp= new Item_null();
984
1559
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
985
1560
    }
986
 
 
 
1561
    pthread_mutex_unlock(&LOCK_global_system_variables);
987
1562
    return tmp;
988
1563
  }
989
1564
  case SHOW_CHAR:
990
1565
  {
991
1566
    Item *tmp;
992
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
993
 
    char *str= (char*) value_ptr(session, var_type, base);
 
1567
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1568
    char *str= (char*) value_ptr(thd, var_type, base);
994
1569
    if (str)
995
1570
      tmp= new Item_string(str, strlen(str),
996
1571
                           system_charset_info, DERIVATION_SYSCONST);
999
1574
      tmp= new Item_null();
1000
1575
      tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
1001
1576
    }
1002
 
 
 
1577
    pthread_mutex_unlock(&LOCK_global_system_variables);
1003
1578
    return tmp;
1004
1579
  }
1005
1580
  default:
1006
 
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name.c_str());
 
1581
    my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
1007
1582
  }
1008
1583
  return 0;
1009
1584
}
1010
1585
 
1011
1586
 
1012
 
bool sys_var_session_enum::update(Session *session, set_var *var)
 
1587
bool sys_var_thd_enum::update(THD *thd, set_var *var)
1013
1588
{
1014
1589
  if (var->type == OPT_GLOBAL)
1015
 
    global_system_variables.*offset= var->getInteger();
 
1590
    global_system_variables.*offset= var->save_result.ulong_value;
1016
1591
  else
1017
 
    session->variables.*offset= var->getInteger();
 
1592
    thd->variables.*offset= var->save_result.ulong_value;
1018
1593
  return 0;
1019
1594
}
1020
1595
 
1021
1596
 
1022
 
void sys_var_session_enum::set_default(Session *session, sql_var_t type)
 
1597
void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
1023
1598
{
1024
1599
  if (type == OPT_GLOBAL)
1025
 
    global_system_variables.*offset= (uint32_t) option_limits->def_value;
 
1600
    global_system_variables.*offset= (ulong) option_limits->def_value;
1026
1601
  else
1027
 
    session->variables.*offset= global_system_variables.*offset;
 
1602
    thd->variables.*offset= global_system_variables.*offset;
1028
1603
}
1029
1604
 
1030
1605
 
1031
 
unsigned char *sys_var_session_enum::value_ptr(Session *session,
1032
 
                                               sql_var_t type,
1033
 
                                               const LEX_STRING *)
 
1606
uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
 
1607
                                   LEX_STRING *base __attribute__((__unused__)))
1034
1608
{
1035
 
  uint32_t tmp= ((type == OPT_GLOBAL) ?
 
1609
  ulong tmp= ((type == OPT_GLOBAL) ?
1036
1610
              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);
 
1611
              thd->variables.*offset);
 
1612
  return (uchar*) enum_names->type_names[tmp];
 
1613
}
 
1614
 
 
1615
bool sys_var_thd_bit::check(THD *thd, set_var *var)
 
1616
{
 
1617
  return (check_enum(thd, var, &bool_typelib) ||
 
1618
          (check_func && (*check_func)(thd, var)));
 
1619
}
 
1620
 
 
1621
bool sys_var_thd_bit::update(THD *thd, set_var *var)
 
1622
{
 
1623
  int res= (*update_func)(thd, var);
1050
1624
  return res;
1051
1625
}
1052
1626
 
1053
1627
 
1054
 
unsigned char *sys_var_session_bit::value_ptr(Session *session, sql_var_t,
1055
 
                                              const LEX_STRING *)
 
1628
uchar *sys_var_thd_bit::value_ptr(THD *thd,
 
1629
                                  enum_var_type type __attribute__((__unused__)),
 
1630
                                  LEX_STRING *base __attribute__((__unused__)))
1056
1631
{
1057
1632
  /*
1058
1633
    If reverse is 0 (default) return 1 if bit is set.
1059
1634
    If reverse is 1, return 0 if bit is set
1060
1635
  */
1061
 
  session->sys_var_tmp.bool_value= ((session->options & bit_flag) ?
 
1636
  thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
1062
1637
                                   !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;
 
1638
  return (uchar*) &thd->sys_var_tmp.my_bool_value;
 
1639
}
 
1640
 
 
1641
 
 
1642
/** Update a date_time format variable based on given value. */
 
1643
 
 
1644
void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
 
1645
                                           DATE_TIME_FORMAT *new_value)
 
1646
{
 
1647
  DATE_TIME_FORMAT *old;
 
1648
 
 
1649
  if (type == OPT_GLOBAL)
 
1650
  {
 
1651
    pthread_mutex_lock(&LOCK_global_system_variables);
 
1652
    old= (global_system_variables.*offset);
 
1653
    (global_system_variables.*offset)= new_value;
 
1654
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
1655
  }
 
1656
  else
 
1657
  {
 
1658
    old= (thd->variables.*offset);
 
1659
    (thd->variables.*offset)= new_value;
 
1660
  }
 
1661
  my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR));
 
1662
  return;
 
1663
}
 
1664
 
 
1665
 
 
1666
bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
 
1667
{
 
1668
  DATE_TIME_FORMAT *new_value;
 
1669
  /* We must make a copy of the last value to get it into normal memory */
 
1670
  new_value= date_time_format_copy((THD*) 0,
 
1671
                                   var->save_result.date_time_format);
 
1672
  if (!new_value)
 
1673
    return 1;                                   // Out of memory
 
1674
  update2(thd, var->type, new_value);           // Can't fail
 
1675
  return 0;
 
1676
}
 
1677
 
 
1678
 
 
1679
bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
 
1680
{
 
1681
  char buff[STRING_BUFFER_USUAL_SIZE];
 
1682
  String str(buff,sizeof(buff), system_charset_info), *res;
 
1683
  DATE_TIME_FORMAT *format;
 
1684
 
 
1685
  if (!(res=var->value->val_str(&str)))
 
1686
    res= &my_empty_string;
 
1687
 
 
1688
  if (!(format= date_time_format_make(date_time_type,
 
1689
                                      res->ptr(), res->length())))
 
1690
  {
 
1691
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
 
1692
    return 1;
 
1693
  }
 
1694
  
 
1695
  /*
 
1696
    We must copy result to thread space to not get a memory leak if
 
1697
    update is aborted
 
1698
  */
 
1699
  var->save_result.date_time_format= date_time_format_copy(thd, format);
 
1700
  my_free((char*) format, MYF(0));
 
1701
  return var->save_result.date_time_format == 0;
 
1702
}
 
1703
 
 
1704
 
 
1705
void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type)
 
1706
{
 
1707
  DATE_TIME_FORMAT *res= 0;
 
1708
 
 
1709
  if (type == OPT_GLOBAL)
 
1710
  {
 
1711
    const char *format;
 
1712
    if ((format= opt_date_time_formats[date_time_type]))
 
1713
      res= date_time_format_make(date_time_type, format, strlen(format));
 
1714
  }
 
1715
  else
 
1716
  {
 
1717
    /* Make copy with malloc */
 
1718
    res= date_time_format_copy((THD *) 0, global_system_variables.*offset);
 
1719
  }
 
1720
 
 
1721
  if (res)                                      // Should always be true
 
1722
    update2(thd, type, res);
 
1723
}
 
1724
 
 
1725
 
 
1726
uchar *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type,
 
1727
                                               LEX_STRING *base __attribute__((__unused__)))
 
1728
{
 
1729
  if (type == OPT_GLOBAL)
 
1730
  {
 
1731
    char *res;
 
1732
    /*
 
1733
      We do a copy here just to be sure things will work even if someone
 
1734
      is modifying the original string while the copy is accessed
 
1735
      (Can't happen now in SQL SHOW, but this is a good safety for the future)
 
1736
    */
 
1737
    res= thd->strmake((global_system_variables.*offset)->format.str,
 
1738
                      (global_system_variables.*offset)->format.length);
 
1739
    return (uchar*) res;
 
1740
  }
 
1741
  return (uchar*) (thd->variables.*offset)->format.str;
 
1742
}
 
1743
 
 
1744
 
 
1745
typedef struct old_names_map_st
 
1746
{
 
1747
  const char *old_name;
 
1748
  const char *new_name;
 
1749
} my_old_conv;
 
1750
 
 
1751
static my_old_conv old_conv[]= 
 
1752
{
 
1753
  {     "cp1251_koi8"           ,       "cp1251"        },
 
1754
  {     "cp1250_latin2"         ,       "cp1250"        },
 
1755
  {     "kam_latin2"            ,       "keybcs2"       },
 
1756
  {     "mac_latin2"            ,       "MacRoman"      },
 
1757
  {     "macce_latin2"          ,       "MacCE"         },
 
1758
  {     "pc2_latin2"            ,       "pclatin2"      },
 
1759
  {     "vga_latin2"            ,       "pclatin1"      },
 
1760
  {     "koi8_cp1251"           ,       "koi8r"         },
 
1761
  {     "win1251ukr_koi8_ukr"   ,       "win1251ukr"    },
 
1762
  {     "koi8_ukr_win1251ukr"   ,       "koi8u"         },
 
1763
  {     NULL                    ,       NULL            }
 
1764
};
 
1765
 
 
1766
CHARSET_INFO *get_old_charset_by_name(const char *name)
 
1767
{
 
1768
  my_old_conv *conv;
 
1769
 
 
1770
  for (conv= old_conv; conv->old_name; conv++)
 
1771
  {
 
1772
    if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
 
1773
      return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0));
 
1774
  }
 
1775
  return NULL;
 
1776
}
 
1777
 
 
1778
 
 
1779
bool sys_var_collation::check(THD *thd __attribute__((__unused__)),
 
1780
                              set_var *var)
 
1781
{
 
1782
  CHARSET_INFO *tmp;
1070
1783
 
1071
1784
  if (var->value->result_type() == STRING_RESULT)
1072
1785
  {
1074
1787
    String str(buff,sizeof(buff), system_charset_info), *res;
1075
1788
    if (!(res=var->value->val_str(&str)))
1076
1789
    {
1077
 
      boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string("NULL")));
 
1790
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1078
1791
      return 1;
1079
1792
    }
1080
 
    if (!(tmp=get_charset_by_name(res->c_ptr())))
 
1793
    if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
1081
1794
    {
1082
1795
      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
1796
      return 1;
1085
1797
    }
1086
1798
  }
1087
1799
  else // INT_RESULT
1088
1800
  {
1089
 
    if (!(tmp=get_charset((int) var->value->val_int())))
 
1801
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
1090
1802
    {
1091
1803
      char buf[20];
1092
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
1804
      int10_to_str((int) var->value->val_int(), buf, -10);
1093
1805
      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
 
  }
 
1806
      return 1;
 
1807
    }
 
1808
  }
 
1809
  var->save_result.charset= tmp;        // Save for update
 
1810
  return 0;
 
1811
}
 
1812
 
 
1813
 
 
1814
bool sys_var_character_set::check(THD *thd __attribute__((__unused__)),
 
1815
                                  set_var *var)
 
1816
{
 
1817
  CHARSET_INFO *tmp;
 
1818
 
 
1819
  if (var->value->result_type() == STRING_RESULT)
 
1820
  {
 
1821
    char buff[STRING_BUFFER_USUAL_SIZE];
 
1822
    String str(buff,sizeof(buff), system_charset_info), *res;
 
1823
    if (!(res=var->value->val_str(&str)))
 
1824
    {
 
1825
      if (!nullable)
 
1826
      {
 
1827
        my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
 
1828
        return 1;
 
1829
      }
 
1830
      tmp= NULL;
 
1831
    }
 
1832
    else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
 
1833
             !(tmp=get_old_charset_by_name(res->c_ptr())))
 
1834
    {
 
1835
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
 
1836
      return 1;
 
1837
    }
 
1838
  }
 
1839
  else // INT_RESULT
 
1840
  {
 
1841
    if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
 
1842
    {
 
1843
      char buf[20];
 
1844
      int10_to_str((int) var->value->val_int(), buf, -10);
 
1845
      my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
 
1846
      return 1;
 
1847
    }
 
1848
  }
 
1849
  var->save_result.charset= tmp;        // Save for update
 
1850
  return 0;
 
1851
}
 
1852
 
 
1853
 
 
1854
bool sys_var_character_set::update(THD *thd, set_var *var)
 
1855
{
 
1856
  ci_ptr(thd,var->type)[0]= var->save_result.charset;
 
1857
  thd->update_charset();
 
1858
  return 0;
 
1859
}
 
1860
 
 
1861
 
 
1862
uchar *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
 
1863
                                        LEX_STRING *base __attribute__((__unused__)))
 
1864
{
 
1865
  CHARSET_INFO *cs= ci_ptr(thd,type)[0];
 
1866
  return cs ? (uchar*) cs->csname : (uchar*) NULL;
 
1867
}
 
1868
 
 
1869
 
 
1870
void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
 
1871
{
 
1872
  if (type == OPT_GLOBAL)
 
1873
    global_system_variables.*offset= *global_default;
 
1874
  else
 
1875
  {
 
1876
    thd->variables.*offset= global_system_variables.*offset;
 
1877
    thd->update_charset();
 
1878
  }
 
1879
}
 
1880
CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
 
1881
{
 
1882
  if (type == OPT_GLOBAL)
 
1883
    return &(global_system_variables.*offset);
 
1884
  else
 
1885
    return &(thd->variables.*offset);
 
1886
}
 
1887
 
 
1888
 
 
1889
bool sys_var_character_set_client::check(THD *thd, set_var *var)
 
1890
{
 
1891
  if (sys_var_character_set_sv::check(thd, var))
 
1892
    return 1;
 
1893
  /* Currently, UCS-2 cannot be used as a client character set */
 
1894
  if (var->save_result.charset->mbminlen > 1)
 
1895
  {
 
1896
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, 
 
1897
             var->save_result.charset->csname);
 
1898
    return 1;
 
1899
  }
 
1900
  return 0;
 
1901
}
 
1902
 
 
1903
 
 
1904
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
 
1905
                                                       enum_var_type type)
 
1906
{
 
1907
  if (type == OPT_GLOBAL)
 
1908
    return &global_system_variables.collation_database;
 
1909
  else
 
1910
    return &thd->variables.collation_database;
 
1911
}
 
1912
 
 
1913
 
 
1914
void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
 
1915
{
 
1916
 if (type == OPT_GLOBAL)
 
1917
    global_system_variables.collation_database= default_charset_info;
 
1918
  else
 
1919
  {
 
1920
    thd->variables.collation_database= thd->db_charset;
 
1921
    thd->update_charset();
 
1922
  }
 
1923
}
 
1924
 
 
1925
 
 
1926
bool sys_var_collation_sv::update(THD *thd, set_var *var)
 
1927
{
1098
1928
  if (var->type == OPT_GLOBAL)
1099
 
    global_system_variables.*offset= tmp;
 
1929
    global_system_variables.*offset= var->save_result.charset;
1100
1930
  else
1101
1931
  {
1102
 
    session->variables.*offset= tmp;
 
1932
    thd->variables.*offset= var->save_result.charset;
 
1933
    thd->update_charset();
1103
1934
  }
1104
1935
  return 0;
1105
1936
}
1106
1937
 
1107
1938
 
1108
 
void sys_var_collation_sv::set_default(Session *session, sql_var_t type)
 
1939
void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
1109
1940
{
1110
1941
  if (type == OPT_GLOBAL)
1111
1942
    global_system_variables.*offset= *global_default;
1112
1943
  else
1113
1944
  {
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";
 
1945
    thd->variables.*offset= global_system_variables.*offset;
 
1946
    thd->update_charset();
 
1947
  }
 
1948
}
 
1949
 
 
1950
 
 
1951
uchar *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type,
 
1952
                                       LEX_STRING *base __attribute__((__unused__)))
 
1953
{
 
1954
  CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
 
1955
                     global_system_variables.*offset : thd->variables.*offset);
 
1956
  return cs ? (uchar*) cs->name : (uchar*) "NULL";
 
1957
}
 
1958
 
 
1959
 
 
1960
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
 
1961
 
 
1962
static KEY_CACHE zero_key_cache;
 
1963
 
 
1964
KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
 
1965
{
 
1966
  safe_mutex_assert_owner(&LOCK_global_system_variables);
 
1967
  if (!cache_name || ! cache_name->length)
 
1968
    cache_name= &default_key_cache_base;
 
1969
  return ((KEY_CACHE*) find_named(&key_caches,
 
1970
                                      cache_name->str, cache_name->length, 0));
 
1971
}
 
1972
 
 
1973
 
 
1974
uchar *sys_var_key_cache_param::value_ptr(THD *thd __attribute__((__unused__)),
 
1975
                                          enum_var_type type __attribute__((__unused__)),
 
1976
                                          LEX_STRING *base __attribute__((__unused__)))
 
1977
{
 
1978
  KEY_CACHE *key_cache= get_key_cache(base);
 
1979
  if (!key_cache)
 
1980
    key_cache= &zero_key_cache;
 
1981
  return (uchar*) key_cache + offset ;
 
1982
}
 
1983
 
 
1984
 
 
1985
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
 
1986
{
 
1987
  uint64_t tmp= var->save_result.uint64_t_value;
 
1988
  LEX_STRING *base_name= &var->base;
 
1989
  KEY_CACHE *key_cache;
 
1990
  bool error= 0;
 
1991
 
 
1992
  /* If no basename, assume it's for the key cache named 'default' */
 
1993
  if (!base_name->length)
 
1994
    base_name= &default_key_cache_base;
 
1995
 
 
1996
  pthread_mutex_lock(&LOCK_global_system_variables);
 
1997
  key_cache= get_key_cache(base_name);
 
1998
                            
 
1999
  if (!key_cache)
 
2000
  {
 
2001
    /* Key cache didn't exists */
 
2002
    if (!tmp)                                   // Tried to delete cache
 
2003
      goto end;                                 // Ok, nothing to do
 
2004
    if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
 
2005
    {
 
2006
      error= 1;
 
2007
      goto end;
 
2008
    }
 
2009
  }
 
2010
 
 
2011
  /*
 
2012
    Abort if some other thread is changing the key cache
 
2013
    TODO: This should be changed so that we wait until the previous
 
2014
    assignment is done and then do the new assign
 
2015
  */
 
2016
  if (key_cache->in_init)
 
2017
    goto end;
 
2018
 
 
2019
  if (!tmp)                                     // Zero size means delete
 
2020
  {
 
2021
    if (key_cache == dflt_key_cache)
 
2022
    {
 
2023
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2024
                          ER_WARN_CANT_DROP_DEFAULT_KEYCACHE,
 
2025
                          ER(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE));
 
2026
      goto end;                                 // Ignore default key cache
 
2027
    }
 
2028
 
 
2029
    if (key_cache->key_cache_inited)            // If initied
 
2030
    {
 
2031
      /*
 
2032
        Move tables using this key cache to the default key cache
 
2033
        and clear the old key cache.
 
2034
      */
 
2035
      NAMED_LIST *list; 
 
2036
      key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
 
2037
                                              base_name->length, &list);
 
2038
      key_cache->in_init= 1;
 
2039
      pthread_mutex_unlock(&LOCK_global_system_variables);
 
2040
      error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
 
2041
      pthread_mutex_lock(&LOCK_global_system_variables);
 
2042
      key_cache->in_init= 0;
 
2043
    }
 
2044
    /*
 
2045
      We don't delete the key cache as some running threads my still be
 
2046
      in the key cache code with a pointer to the deleted (empty) key cache
 
2047
    */
 
2048
    goto end;
 
2049
  }
 
2050
 
 
2051
  key_cache->param_buff_size=
 
2052
    (uint64_t) fix_unsigned(thd, tmp, option_limits);
 
2053
 
 
2054
  /* If key cache didn't existed initialize it, else resize it */
 
2055
  key_cache->in_init= 1;
 
2056
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2057
 
 
2058
  if (!key_cache->key_cache_inited)
 
2059
    error= (bool) (ha_init_key_cache("", key_cache));
 
2060
  else
 
2061
    error= (bool)(ha_resize_key_cache(key_cache));
 
2062
 
 
2063
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2064
  key_cache->in_init= 0;  
 
2065
 
 
2066
end:
 
2067
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2068
  return error;
 
2069
}
 
2070
 
 
2071
 
 
2072
/**
 
2073
  @todo
 
2074
  Abort if some other thread is changing the key cache.
 
2075
  This should be changed so that we wait until the previous
 
2076
  assignment is done and then do the new assign
 
2077
*/
 
2078
bool sys_var_key_cache_long::update(THD *thd, set_var *var)
 
2079
{
 
2080
  ulong tmp= (ulong) var->value->val_int();
 
2081
  LEX_STRING *base_name= &var->base;
 
2082
  bool error= 0;
 
2083
 
 
2084
  if (!base_name->length)
 
2085
    base_name= &default_key_cache_base;
 
2086
 
 
2087
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2088
  KEY_CACHE *key_cache= get_key_cache(base_name);
 
2089
 
 
2090
  if (!key_cache && !(key_cache= create_key_cache(base_name->str,
 
2091
                                                  base_name->length)))
 
2092
  {
 
2093
    error= 1;
 
2094
    goto end;
 
2095
  }
 
2096
 
 
2097
  /*
 
2098
    Abort if some other thread is changing the key cache
 
2099
    TODO: This should be changed so that we wait until the previous
 
2100
    assignment is done and then do the new assign
 
2101
  */
 
2102
  if (key_cache->in_init)
 
2103
    goto end;
 
2104
 
 
2105
  *((ulong*) (((char*) key_cache) + offset))=
 
2106
    (ulong) fix_unsigned(thd, tmp, option_limits);
 
2107
 
 
2108
  /*
 
2109
    Don't create a new key cache if it didn't exist
 
2110
    (key_caches are created only when the user sets block_size)
 
2111
  */
 
2112
  key_cache->in_init= 1;
 
2113
 
 
2114
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2115
 
 
2116
  error= (bool) (ha_resize_key_cache(key_cache));
 
2117
 
 
2118
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2119
  key_cache->in_init= 0;  
 
2120
 
 
2121
end:
 
2122
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2123
  return error;
 
2124
}
 
2125
 
 
2126
 
 
2127
bool sys_var_log_state::update(THD *thd, set_var *var)
 
2128
{
 
2129
  bool res;
 
2130
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2131
  if (!var->save_result.ulong_value)
 
2132
  {
 
2133
    logger.deactivate_log_handler(thd, log_type);
 
2134
    res= false;
 
2135
  }
 
2136
  else
 
2137
    res= logger.activate_log_handler(thd, log_type);
 
2138
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2139
  return res;
 
2140
}
 
2141
 
 
2142
void sys_var_log_state::set_default(THD *thd,
 
2143
                                    enum_var_type type __attribute__((__unused__)))
 
2144
{
 
2145
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2146
  logger.deactivate_log_handler(thd, log_type);
 
2147
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2148
}
 
2149
 
 
2150
 
 
2151
static int  sys_check_log_path(THD *thd __attribute__((__unused__)),
 
2152
                               set_var *var)
 
2153
{
 
2154
  char path[FN_REFLEN], buff[FN_REFLEN];
 
2155
  struct stat f_stat;
 
2156
  String str(buff, sizeof(buff), system_charset_info), *res;
 
2157
  const char *log_file_str;
 
2158
  size_t path_length;
 
2159
 
 
2160
  if (!(res= var->value->val_str(&str)))
 
2161
    goto err;
 
2162
 
 
2163
  log_file_str= res->c_ptr();
 
2164
  bzero(&f_stat, sizeof(struct stat));
 
2165
 
 
2166
  path_length= unpack_filename(path, log_file_str);
 
2167
 
 
2168
  if (!path_length)
 
2169
  {
 
2170
    /* File name is empty. */
 
2171
 
 
2172
    goto err;
 
2173
  }
 
2174
 
 
2175
  if (!stat(path, &f_stat))
 
2176
  {
 
2177
    /*
 
2178
      A file system object exists. Check if argument is a file and we have
 
2179
      'write' permission.
 
2180
    */
 
2181
 
 
2182
    if (!MY_S_ISREG(f_stat.st_mode) ||
 
2183
        !(f_stat.st_mode & MY_S_IWRITE))
 
2184
      goto err;
 
2185
 
 
2186
    return 0;
 
2187
  }
 
2188
 
 
2189
  /* Get dirname of the file path. */
 
2190
  (void) dirname_part(path, log_file_str, &path_length);
 
2191
 
 
2192
  /* Dirname is empty if file path is relative. */
 
2193
  if (!path_length)
 
2194
    return 0;
 
2195
 
 
2196
  /*
 
2197
    Check if directory exists and we have permission to create file and
 
2198
    write to file.
 
2199
  */
 
2200
  if (my_access(path, (F_OK|W_OK)))
 
2201
    goto err;
 
2202
 
 
2203
  return 0;
 
2204
 
 
2205
err:
 
2206
  my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, 
 
2207
           res ? log_file_str : "NULL");
 
2208
  return 1;
 
2209
}
 
2210
 
 
2211
 
 
2212
bool update_sys_var_str_path(THD *thd __attribute__((__unused__)),
 
2213
                             sys_var_str *var_str,
 
2214
                             set_var *var, const char *log_ext,
 
2215
                             bool log_state, uint log_type)
 
2216
{
 
2217
  MYSQL_QUERY_LOG *file_log;
 
2218
  char buff[FN_REFLEN];
 
2219
  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
 
2220
  bool result= 0;
 
2221
  uint str_length= (var ? var->value->str_value.length() : 0);
 
2222
 
 
2223
  switch (log_type) {
 
2224
  case QUERY_LOG_SLOW:
 
2225
    file_log= logger.get_slow_log_file_handler();
 
2226
    break;
 
2227
  case QUERY_LOG_GENERAL:
 
2228
    file_log= logger.get_log_file_handler();
 
2229
    break;
 
2230
  default:
 
2231
    assert(0);                                  // Impossible
 
2232
  }
 
2233
 
 
2234
  if (!old_value)
 
2235
  {
 
2236
    old_value= make_default_log_name(buff, log_ext);
 
2237
    str_length= strlen(old_value);
 
2238
  }
 
2239
  if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
 
2240
  {
 
2241
    result= 1;
 
2242
    goto err;
 
2243
  }
 
2244
 
 
2245
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2246
  logger.lock_exclusive();
 
2247
 
 
2248
  if (file_log && log_state)
 
2249
    file_log->close(0);
 
2250
  old_value= var_str->value;
 
2251
  var_str->value= res;
 
2252
  var_str->value_length= str_length;
 
2253
  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
 
2254
  if (file_log && log_state)
 
2255
  {
 
2256
    switch (log_type) {
 
2257
    case QUERY_LOG_SLOW:
 
2258
      file_log->open_slow_log(sys_var_slow_log_path.value);
 
2259
      break;
 
2260
    case QUERY_LOG_GENERAL:
 
2261
      file_log->open_query_log(sys_var_general_log_path.value);
 
2262
      break;
 
2263
    default:
 
2264
      assert(0);
 
2265
    }
 
2266
  }
 
2267
 
 
2268
  logger.unlock();
 
2269
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2270
 
 
2271
err:
 
2272
  return result;
 
2273
}
 
2274
 
 
2275
 
 
2276
static bool sys_update_general_log_path(THD *thd, set_var * var)
 
2277
{
 
2278
  return update_sys_var_str_path(thd, &sys_var_general_log_path,
 
2279
                                 var, ".log", opt_log, QUERY_LOG_GENERAL);
 
2280
}
 
2281
 
 
2282
 
 
2283
static void sys_default_general_log_path(THD *thd,
 
2284
                                         enum_var_type type __attribute__((__unused__)))
 
2285
{
 
2286
  (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
 
2287
                                 0, ".log", opt_log, QUERY_LOG_GENERAL);
 
2288
}
 
2289
 
 
2290
 
 
2291
static bool sys_update_slow_log_path(THD *thd, set_var * var)
 
2292
{
 
2293
  return update_sys_var_str_path(thd, &sys_var_slow_log_path,
 
2294
                                 var, "-slow.log", opt_slow_log,
 
2295
                                 QUERY_LOG_SLOW);
 
2296
}
 
2297
 
 
2298
 
 
2299
static void sys_default_slow_log_path(THD *thd,
 
2300
                                      enum_var_type type __attribute__((__unused__)))
 
2301
{
 
2302
  (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
 
2303
                                 0, "-slow.log", opt_slow_log,
 
2304
                                 QUERY_LOG_SLOW);
 
2305
}
 
2306
 
 
2307
 
 
2308
bool sys_var_log_output::update(THD *thd __attribute__((__unused__)),
 
2309
                                set_var *var)
 
2310
{
 
2311
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2312
  logger.lock_exclusive();
 
2313
  logger.init_slow_log(var->save_result.ulong_value);
 
2314
  logger.init_general_log(var->save_result.ulong_value);
 
2315
  *value= var->save_result.ulong_value;
 
2316
  logger.unlock();
 
2317
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2318
  return 0;
 
2319
}
 
2320
 
 
2321
 
 
2322
void sys_var_log_output::set_default(THD *thd __attribute__((__unused__)),
 
2323
                                     enum_var_type type __attribute__((__unused__)))
 
2324
{
 
2325
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2326
  logger.lock_exclusive();
 
2327
  logger.init_slow_log(LOG_FILE);
 
2328
  logger.init_general_log(LOG_FILE);
 
2329
  *value= LOG_FILE;
 
2330
  logger.unlock();
 
2331
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2332
}
 
2333
 
 
2334
 
 
2335
uchar *sys_var_log_output::value_ptr(THD *thd,
 
2336
                                     enum_var_type type __attribute__((__unused__)),
 
2337
                                     LEX_STRING *base __attribute__((__unused__)))
 
2338
{
 
2339
  char buff[256];
 
2340
  String tmp(buff, sizeof(buff), &my_charset_latin1);
 
2341
  ulong length;
 
2342
  ulong val= *value;
 
2343
 
 
2344
  tmp.length(0);
 
2345
  for (uint i= 0; val; val>>= 1, i++)
 
2346
  {
 
2347
    if (val & 1)
 
2348
    {
 
2349
      tmp.append(log_output_typelib.type_names[i],
 
2350
                 log_output_typelib.type_lengths[i]);
 
2351
      tmp.append(',');
 
2352
    }
 
2353
  }
 
2354
 
 
2355
  if ((length= tmp.length()))
 
2356
    length--;
 
2357
  return (uchar*) thd->strmake(tmp.ptr(), length);
 
2358
}
 
2359
 
 
2360
 
 
2361
/*****************************************************************************
 
2362
  Functions to handle SET NAMES and SET CHARACTER SET
 
2363
*****************************************************************************/
 
2364
 
 
2365
int set_var_collation_client::check(THD *thd __attribute__((__unused__)))
 
2366
{
 
2367
  /* Currently, UCS-2 cannot be used as a client character set */
 
2368
  if (character_set_client->mbminlen > 1)
 
2369
  {
 
2370
    my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
 
2371
             character_set_client->csname);
 
2372
    return 1;
 
2373
  }
 
2374
  return 0;
 
2375
}
 
2376
 
 
2377
int set_var_collation_client::update(THD *thd)
 
2378
{
 
2379
  thd->variables.character_set_client= character_set_client;
 
2380
  thd->variables.character_set_results= character_set_results;
 
2381
  thd->variables.collation_connection= collation_connection;
 
2382
  thd->update_charset();
 
2383
  thd->protocol_text.init(thd);
 
2384
  return 0;
1127
2385
}
1128
2386
 
1129
2387
/****************************************************************************/
1130
2388
 
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 *)
 
2389
bool sys_var_timestamp::update(THD *thd,  set_var *var)
 
2390
{
 
2391
  thd->set_time((time_t) var->save_result.uint64_t_value);
 
2392
  return 0;
 
2393
}
 
2394
 
 
2395
 
 
2396
void sys_var_timestamp::set_default(THD *thd,
 
2397
                                    enum_var_type type __attribute__((__unused__)))
 
2398
{
 
2399
  thd->user_time=0;
 
2400
}
 
2401
 
 
2402
 
 
2403
uchar *sys_var_timestamp::value_ptr(THD *thd,
 
2404
                                    enum_var_type type __attribute__((__unused__)),
 
2405
                                    LEX_STRING *base __attribute__((__unused__)))
 
2406
{
 
2407
  thd->sys_var_tmp.long_value= (long) thd->start_time;
 
2408
  return (uchar*) &thd->sys_var_tmp.long_value;
 
2409
}
 
2410
 
 
2411
 
 
2412
bool sys_var_last_insert_id::update(THD *thd, set_var *var)
 
2413
{
 
2414
  thd->first_successful_insert_id_in_prev_stmt=
 
2415
    var->save_result.uint64_t_value;
 
2416
  return 0;
 
2417
}
 
2418
 
 
2419
 
 
2420
uchar *sys_var_last_insert_id::value_ptr(THD *thd,
 
2421
                                         enum_var_type type __attribute__((__unused__)),
 
2422
                                         LEX_STRING *base __attribute__((__unused__)))
1162
2423
{
1163
2424
  /*
1164
2425
    this tmp var makes it robust againt change of type of
1165
2426
    read_first_successful_insert_id_in_prev_stmt().
1166
2427
  */
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)
 
2428
  thd->sys_var_tmp.uint64_t_value= 
 
2429
    thd->read_first_successful_insert_id_in_prev_stmt();
 
2430
  return (uchar*) &thd->sys_var_tmp.uint64_t_value;
 
2431
}
 
2432
 
 
2433
 
 
2434
bool sys_var_insert_id::update(THD *thd, set_var *var)
 
2435
{
 
2436
  thd->force_one_auto_inc_interval(var->save_result.uint64_t_value);
 
2437
  return 0;
 
2438
}
 
2439
 
 
2440
 
 
2441
uchar *sys_var_insert_id::value_ptr(THD *thd,
 
2442
                                    enum_var_type type __attribute__((__unused__)),
 
2443
                                    LEX_STRING *base __attribute__((__unused__)))
 
2444
{
 
2445
  thd->sys_var_tmp.uint64_t_value=
 
2446
    thd->auto_inc_intervals_forced.minimum();
 
2447
  return (uchar*) &thd->sys_var_tmp.uint64_t_value;
 
2448
}
 
2449
 
 
2450
 
 
2451
bool sys_var_rand_seed1::update(THD *thd, set_var *var)
 
2452
{
 
2453
  thd->rand.seed1= (ulong) var->save_result.uint64_t_value;
 
2454
  return 0;
 
2455
}
 
2456
 
 
2457
bool sys_var_rand_seed2::update(THD *thd, set_var *var)
 
2458
{
 
2459
  thd->rand.seed2= (ulong) var->save_result.uint64_t_value;
 
2460
  return 0;
 
2461
}
 
2462
 
 
2463
 
 
2464
bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
 
2465
{
 
2466
  char buff[MAX_TIME_ZONE_NAME_LENGTH];
 
2467
  String str(buff, sizeof(buff), &my_charset_latin1);
 
2468
  String *res= var->value->val_str(&str);
 
2469
 
 
2470
  if (!(var->save_result.time_zone= my_tz_find(thd, res)))
 
2471
  {
 
2472
    my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
 
2473
    return 1;
 
2474
  }
 
2475
  return 0;
 
2476
}
 
2477
 
 
2478
 
 
2479
bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
 
2480
{
 
2481
  /* We are using Time_zone object found during check() phase. */
 
2482
  if (var->type == OPT_GLOBAL)
 
2483
  {
 
2484
    pthread_mutex_lock(&LOCK_global_system_variables);
 
2485
    global_system_variables.time_zone= var->save_result.time_zone;
 
2486
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
2487
  }
 
2488
  else
 
2489
    thd->variables.time_zone= var->save_result.time_zone;
 
2490
  return 0;
 
2491
}
 
2492
 
 
2493
 
 
2494
uchar *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
 
2495
                                        LEX_STRING *base __attribute__((__unused__)))
 
2496
{
 
2497
  /* 
 
2498
    We can use ptr() instead of c_ptr() here because String contaning
 
2499
    time zone name is guaranteed to be zero ended.
 
2500
  */
 
2501
  if (type == OPT_GLOBAL)
 
2502
    return (uchar *)(global_system_variables.time_zone->get_name()->ptr());
 
2503
  else
 
2504
  {
 
2505
    /*
 
2506
      This is an ugly fix for replication: we don't replicate properly queries
 
2507
      invoking system variables' values to update tables; but
 
2508
      CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
 
2509
      replicable (i.e. we tell the binlog code to store the session
 
2510
      timezone). If it's the global value which was used we can't replicate
 
2511
      (binlog code stores session value only).
 
2512
    */
 
2513
    thd->time_zone_used= 1;
 
2514
    return (uchar *)(thd->variables.time_zone->get_name()->ptr());
 
2515
  }
 
2516
}
 
2517
 
 
2518
 
 
2519
void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
 
2520
{
 
2521
 pthread_mutex_lock(&LOCK_global_system_variables);
 
2522
 if (type == OPT_GLOBAL)
 
2523
 {
 
2524
   if (default_tz_name)
 
2525
   {
 
2526
     String str(default_tz_name, &my_charset_latin1);
 
2527
     /*
 
2528
       We are guaranteed to find this time zone since its existence
 
2529
       is checked during start-up.
 
2530
     */
 
2531
     global_system_variables.time_zone= my_tz_find(thd, &str);
 
2532
   }
 
2533
   else
 
2534
     global_system_variables.time_zone= my_tz_SYSTEM;
 
2535
 }
 
2536
 else
 
2537
   thd->variables.time_zone= global_system_variables.time_zone;
 
2538
 pthread_mutex_unlock(&LOCK_global_system_variables);
 
2539
}
 
2540
 
 
2541
 
 
2542
bool sys_var_max_user_conn::check(THD *thd, set_var *var)
 
2543
{
 
2544
  if (var->type == OPT_GLOBAL)
 
2545
    return sys_var_thd::check(thd, var);
 
2546
  else
 
2547
  {
 
2548
    /*
 
2549
      Per-session values of max_user_connections can't be set directly.
 
2550
      May be we should have a separate error message for this?
 
2551
    */
 
2552
    my_error(ER_GLOBAL_VARIABLE, MYF(0), name);
 
2553
    return true;
 
2554
  }
 
2555
}
 
2556
 
 
2557
bool sys_var_max_user_conn::update(THD *thd __attribute__((__unused__)),
 
2558
                                   set_var *var)
 
2559
{
 
2560
  assert(var->type == OPT_GLOBAL);
 
2561
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2562
  max_user_connections= (uint)var->save_result.uint64_t_value;
 
2563
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2564
  return 0;
 
2565
}
 
2566
 
 
2567
 
 
2568
void sys_var_max_user_conn::set_default(THD *thd __attribute__((__unused__)),
 
2569
                                        enum_var_type type __attribute__((__unused__)))
 
2570
{
 
2571
  assert(type == OPT_GLOBAL);
 
2572
  pthread_mutex_lock(&LOCK_global_system_variables);
 
2573
  max_user_connections= (ulong) option_limits->def_value;
 
2574
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
2575
}
 
2576
 
 
2577
 
 
2578
uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
 
2579
                                        LEX_STRING *base __attribute__((__unused__)))
 
2580
{
 
2581
  if (type != OPT_GLOBAL &&
 
2582
      thd->user_connect && thd->user_connect->user_resources.user_conn)
 
2583
    return (uchar*) &(thd->user_connect->user_resources.user_conn);
 
2584
  return (uchar*) &(max_user_connections);
 
2585
}
 
2586
 
 
2587
 
 
2588
bool sys_var_thd_lc_time_names::check(THD *thd __attribute__((__unused__)),
 
2589
                                      set_var *var)
1173
2590
{
1174
2591
  MY_LOCALE *locale_match;
1175
2592
 
1176
2593
  if (var->value->result_type() == INT_RESULT)
1177
2594
  {
1178
 
    if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
 
2595
    if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
1179
2596
    {
1180
 
      char buf[DECIMAL_LONGLONG_DIGITS];
1181
 
      internal::int10_to_str((int) var->value->val_int(), buf, -10);
 
2597
      char buf[20];
 
2598
      int10_to_str((int) var->value->val_int(), buf, -10);
1182
2599
      my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
1183
2600
      return 1;
1184
2601
    }
1185
2602
  }
1186
2603
  else // STRING_RESULT
1187
2604
  {
1188
 
    char buff[6];
1189
 
    String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
 
2605
    char buff[6]; 
 
2606
    String str(buff, sizeof(buff), &my_charset_latin1), *res;
1190
2607
    if (!(res=var->value->val_str(&str)))
1191
2608
    {
1192
 
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
 
2609
      my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
1193
2610
      return 1;
1194
2611
    }
1195
2612
    const char *locale_str= res->c_ptr();
1201
2618
    }
1202
2619
  }
1203
2620
 
 
2621
  var->save_result.locale_value= locale_match;
 
2622
  return 0;
 
2623
}
 
2624
 
 
2625
 
 
2626
bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
 
2627
{
1204
2628
  if (var->type == OPT_GLOBAL)
1205
 
    global_system_variables.lc_time_names= locale_match;
 
2629
    global_system_variables.lc_time_names= var->save_result.locale_value;
1206
2630
  else
1207
 
    session->variables.lc_time_names= locale_match;
 
2631
    thd->variables.lc_time_names= var->save_result.locale_value;
1208
2632
  return 0;
1209
2633
}
1210
2634
 
1211
2635
 
1212
 
unsigned char *sys_var_session_lc_time_names::value_ptr(Session *session,
1213
 
                                                        sql_var_t type,
1214
 
                                                        const LEX_STRING *)
 
2636
uchar *sys_var_thd_lc_time_names::value_ptr(THD *thd,
 
2637
                                            enum_var_type type,
 
2638
                                            LEX_STRING *base __attribute__((__unused__)))
1215
2639
{
1216
2640
  return type == OPT_GLOBAL ?
1217
 
                 (unsigned char *) global_system_variables.lc_time_names->name :
1218
 
                 (unsigned char *) session->variables.lc_time_names->name;
 
2641
                 (uchar *) global_system_variables.lc_time_names->name :
 
2642
                 (uchar *) thd->variables.lc_time_names->name;
1219
2643
}
1220
2644
 
1221
2645
 
1222
 
void sys_var_session_lc_time_names::set_default(Session *session, sql_var_t type)
 
2646
void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
1223
2647
{
1224
2648
  if (type == OPT_GLOBAL)
1225
2649
    global_system_variables.lc_time_names= my_default_lc_time_names;
1226
2650
  else
1227
 
    session->variables.lc_time_names= global_system_variables.lc_time_names;
 
2651
    thd->variables.lc_time_names= global_system_variables.lc_time_names;
1228
2652
}
1229
2653
 
1230
2654
/*
1236
2660
    This is used for handling long_query_time
1237
2661
*/
1238
2662
 
1239
 
bool sys_var_microseconds::update(Session *session, set_var *var)
 
2663
bool sys_var_microseconds::update(THD *thd, set_var *var)
1240
2664
{
1241
2665
  double num= var->value->val_real();
1242
2666
  int64_t microseconds;
1247
2671
  microseconds= (int64_t) (num * 1000000.0 + 0.5);
1248
2672
  if (var->type == OPT_GLOBAL)
1249
2673
  {
1250
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
2674
    pthread_mutex_lock(&LOCK_global_system_variables);
1251
2675
    (global_system_variables.*offset)= microseconds;
 
2676
    pthread_mutex_unlock(&LOCK_global_system_variables);
1252
2677
  }
1253
2678
  else
1254
 
    session->variables.*offset= microseconds;
 
2679
    thd->variables.*offset= microseconds;
1255
2680
  return 0;
1256
2681
}
1257
2682
 
1258
2683
 
1259
 
void sys_var_microseconds::set_default(Session *session, sql_var_t type)
 
2684
void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
1260
2685
{
1261
2686
  int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
1262
2687
  if (type == OPT_GLOBAL)
1263
2688
  {
1264
 
    boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
 
2689
    pthread_mutex_lock(&LOCK_global_system_variables);
1265
2690
    global_system_variables.*offset= microseconds;
 
2691
    pthread_mutex_unlock(&LOCK_global_system_variables);
1266
2692
  }
1267
2693
  else
1268
 
    session->variables.*offset= microseconds;
1269
 
}
 
2694
    thd->variables.*offset= microseconds;
 
2695
}
 
2696
 
 
2697
 
 
2698
uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
 
2699
                                          LEX_STRING *base __attribute__((__unused__)))
 
2700
{
 
2701
  thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
 
2702
                                   global_system_variables.*offset :
 
2703
                                   thd->variables.*offset) / 1000000.0;
 
2704
  return (uchar*) &thd->tmp_double_value;
 
2705
}
 
2706
 
1270
2707
 
1271
2708
/*
1272
 
  Functions to update session->options bits
 
2709
  Functions to update thd->options bits
1273
2710
*/
1274
2711
 
1275
 
static bool set_option_bit(Session *session, set_var *var)
 
2712
static bool set_option_bit(THD *thd, set_var *var)
1276
2713
{
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;
 
2714
  sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
 
2715
  if ((var->save_result.ulong_value != 0) == sys_var->reverse)
 
2716
    thd->options&= ~sys_var->bit_flag;
1280
2717
  else
1281
 
    session->options|= sys_var->bit_flag;
 
2718
    thd->options|= sys_var->bit_flag;
1282
2719
  return 0;
1283
2720
}
1284
2721
 
1285
2722
 
1286
 
static bool set_option_autocommit(Session *session, set_var *var)
 
2723
static bool set_option_autocommit(THD *thd, set_var *var)
1287
2724
{
1288
 
  bool success= true;
1289
2725
  /* The test is negative as the flag we use is NOT autocommit */
1290
2726
 
1291
 
  uint64_t org_options= session->options;
1292
 
  uint64_t new_options= session->options;
 
2727
  uint64_t org_options= thd->options;
1293
2728
 
1294
 
  if (var->getInteger() != 0)
1295
 
    new_options&= ~((sys_var_session_bit*) var->var)->bit_flag;
 
2729
  if (var->save_result.ulong_value != 0)
 
2730
    thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
1296
2731
  else
1297
 
    new_options|= ((sys_var_session_bit*) var->var)->bit_flag;
 
2732
    thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
1298
2733
 
1299
 
  if ((org_options ^ new_options) & OPTION_NOT_AUTOCOMMIT)
 
2734
  if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
1300
2735
  {
1301
2736
    if ((org_options & OPTION_NOT_AUTOCOMMIT))
1302
2737
    {
1303
 
      success= session->endActiveTransaction();
1304
2738
      /* We changed to auto_commit mode */
1305
 
      session->options&= ~(uint64_t) (OPTION_BEGIN);
1306
 
      session->server_status|= SERVER_STATUS_AUTOCOMMIT;
 
2739
      thd->options&= ~(uint64_t) (OPTION_BEGIN | OPTION_KEEP_LOG);
 
2740
      thd->transaction.all.modified_non_trans_table= false;
 
2741
      thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
 
2742
      if (ha_commit(thd))
 
2743
        return 1;
1307
2744
    }
1308
2745
    else
1309
2746
    {
1310
 
      session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
 
2747
      thd->transaction.all.modified_non_trans_table= false;
 
2748
      thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
1311
2749
    }
1312
2750
  }
1313
 
 
1314
 
  if (var->getInteger() != 0)
1315
 
    session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
 
2751
  return 0;
 
2752
}
 
2753
 
 
2754
static int check_log_update(THD *thd __attribute__((__unused__)),
 
2755
                            set_var *var __attribute__((__unused__)))
 
2756
{
 
2757
  return 0;
 
2758
}
 
2759
 
 
2760
static bool set_log_update(THD *thd __attribute__((__unused__)),
 
2761
                           set_var *var __attribute__((__unused__)))
 
2762
{
 
2763
  /*
 
2764
    The update log is not supported anymore since 5.0.
 
2765
    See sql/mysqld.cc/, comments in function init_server_components() for an
 
2766
    explaination of the different warnings we send below
 
2767
  */
 
2768
 
 
2769
  if (opt_sql_bin_update)
 
2770
  {
 
2771
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
2772
                 ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
 
2773
                 ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
 
2774
  }
1316
2775
  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;
 
2776
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
2777
                 ER_UPDATE_LOG_DEPRECATED_IGNORED,
 
2778
                 ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
 
2779
  set_option_bit(thd, var);
 
2780
  return 0;
 
2781
}
 
2782
 
 
2783
 
 
2784
static int check_pseudo_thread_id(THD *thd __attribute__((__unused__)),
 
2785
                                  set_var *var)
 
2786
{
 
2787
  var->save_result.uint64_t_value= var->value->val_int();
 
2788
  return 0;
 
2789
}
 
2790
 
 
2791
static uchar *get_warning_count(THD *thd)
 
2792
{
 
2793
  thd->sys_var_tmp.long_value=
 
2794
    (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
 
2795
     thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
 
2796
     thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
 
2797
  return (uchar*) &thd->sys_var_tmp.long_value;
 
2798
}
 
2799
 
 
2800
static uchar *get_error_count(THD *thd)
 
2801
{
 
2802
  thd->sys_var_tmp.long_value= 
 
2803
    thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
 
2804
  return (uchar*) &thd->sys_var_tmp.long_value;
1345
2805
}
1346
2806
 
1347
2807
 
1350
2810
 
1351
2811
  This is necessary because if the user does not specify a temporary
1352
2812
  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
 
2813
  or system defaults.  But we can't just always use mysql_tmpdir, because
1354
2814
  that is actually a call to my_tmpdir() which cycles among possible
1355
2815
  temporary directories.
1356
2816
 
1357
 
  @param session                thread handle
 
2817
  @param thd            thread handle
1358
2818
 
1359
2819
  @retval
1360
2820
    ptr         pointer to NUL-terminated string
1361
2821
*/
1362
 
static unsigned char *get_tmpdir(Session *)
 
2822
static uchar *get_tmpdir(THD *thd __attribute__((__unused__)))
1363
2823
{
1364
 
  assert(drizzle_tmpdir.size());
1365
 
  return (unsigned char*)drizzle_tmpdir.c_str();
 
2824
  if (opt_mysql_tmpdir)
 
2825
    return (uchar *)opt_mysql_tmpdir;
 
2826
  return (uchar*)mysql_tmpdir;
1366
2827
}
1367
2828
 
1368
2829
/****************************************************************************
1385
2846
    ptr         pointer to option structure
1386
2847
*/
1387
2848
 
1388
 
static struct option *find_option(struct option *opt, const char *name)
 
2849
static struct my_option *find_option(struct my_option *opt, const char *name) 
1389
2850
{
1390
 
  uint32_t length=strlen(name);
 
2851
  uint length=strlen(name);
1391
2852
  for (; opt->name; opt++)
1392
2853
  {
1393
2854
    if (!getopt_compare_strings(opt->name, name, length) &&
1404
2865
}
1405
2866
 
1406
2867
 
1407
 
 
1408
 
 
1409
 
 
 
2868
/**
 
2869
  Return variable name and length for hashing of variables.
 
2870
*/
 
2871
 
 
2872
static uchar *get_sys_var_length(const sys_var *var, size_t *length,
 
2873
                                 my_bool first __attribute__((__unused__)))
 
2874
{
 
2875
  *length= var->name_length;
 
2876
  return (uchar*) var->name;
 
2877
}
 
2878
 
 
2879
 
 
2880
/*
 
2881
  Add variables to the dynamic hash of system variables
 
2882
  
 
2883
  SYNOPSIS
 
2884
    mysql_add_sys_var_chain()
 
2885
    first       Pointer to first system variable to add
 
2886
    long_opt    (optional)command line arguments may be tied for limit checks.
 
2887
  
 
2888
  RETURN VALUES
 
2889
    0           SUCCESS
 
2890
    otherwise   FAILURE
 
2891
*/
 
2892
 
 
2893
 
 
2894
int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
 
2895
{
 
2896
  sys_var *var;
 
2897
  
 
2898
  /* A write lock should be held on LOCK_system_variables_hash */
 
2899
  
 
2900
  for (var= first; var; var= var->next)
 
2901
  {
 
2902
    var->name_length= strlen(var->name);
 
2903
    /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
 
2904
    if (my_hash_insert(&system_variable_hash, (uchar*) var))
 
2905
      goto error;
 
2906
    if (long_options)
 
2907
      var->option_limits= find_option(long_options, var->name);
 
2908
  }
 
2909
  return 0;
 
2910
 
 
2911
error:
 
2912
  for (; first != var; first= first->next)
 
2913
    hash_delete(&system_variable_hash, (uchar*) first);
 
2914
  return 1;
 
2915
}
 
2916
 
 
2917
 
 
2918
/*
 
2919
  Remove variables to the dynamic hash of system variables
 
2920
   
 
2921
  SYNOPSIS
 
2922
    mysql_del_sys_var_chain()
 
2923
    first       Pointer to first system variable to remove
 
2924
   
 
2925
  RETURN VALUES
 
2926
    0           SUCCESS
 
2927
    otherwise   FAILURE
 
2928
*/
 
2929
 
 
2930
int mysql_del_sys_var_chain(sys_var *first)
 
2931
{
 
2932
  int result= 0;
 
2933
 
 
2934
  /* A write lock should be held on LOCK_system_variables_hash */
 
2935
   
 
2936
  for (sys_var *var= first; var; var= var->next)
 
2937
    result|= hash_delete(&system_variable_hash, (uchar*) var);
 
2938
 
 
2939
  return result;
 
2940
}
 
2941
 
 
2942
 
 
2943
static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
 
2944
{
 
2945
  return strcmp(a->name, b->name);
 
2946
}
 
2947
 
 
2948
 
1410
2949
/*
1411
2950
  Constructs an array of system variables for display to the user.
1412
 
 
 
2951
  
1413
2952
  SYNOPSIS
1414
2953
    enumerate_sys_vars()
1415
 
    session         current thread
1416
 
 
 
2954
    thd         current thread
 
2955
    sorted      If TRUE, the system variables should be sorted
 
2956
  
1417
2957
  RETURN VALUES
1418
 
    pointer     Array of drizzle_show_var elements for display
 
2958
    pointer     Array of SHOW_VAR elements for display
1419
2959
    NULL        FAILURE
1420
2960
*/
1421
2961
 
1422
 
drizzle_show_var* enumerate_sys_vars(Session *session)
 
2962
SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
1423
2963
{
1424
 
  int size= sizeof(drizzle_show_var) * (system_variable_map.size() + 1);
1425
 
  drizzle_show_var *result= (drizzle_show_var*) session->getMemRoot()->allocate(size);
 
2964
  int count= system_variable_hash.records, i;
 
2965
  int fixed_count= fixed_show_vars.elements;
 
2966
  int size= sizeof(SHOW_VAR) * (count + fixed_count + 1);
 
2967
  SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size);
1426
2968
 
1427
2969
  if (result)
1428
2970
  {
1429
 
    drizzle_show_var *show= result;
 
2971
    SHOW_VAR *show= result + fixed_count;
 
2972
    memcpy(result, fixed_show_vars.buffer, fixed_count * sizeof(SHOW_VAR));
1430
2973
 
1431
 
    SystemVariableMap::const_iterator iter= system_variable_map.begin();
1432
 
    while (iter != system_variable_map.end())
 
2974
    for (i= 0; i < count; i++)
1433
2975
    {
1434
 
      sys_var *var= (*iter).second;
1435
 
      show->name= var->getName().c_str();
 
2976
      sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
 
2977
      show->name= var->name;
1436
2978
      show->value= (char*) var;
1437
2979
      show->type= SHOW_SYS;
1438
 
      ++show;
1439
 
      ++iter;
 
2980
      show++;
1440
2981
    }
1441
2982
 
 
2983
    /* sort into order */
 
2984
    if (sorted)
 
2985
      my_qsort(result, count + fixed_count, sizeof(SHOW_VAR),
 
2986
               (qsort_cmp) show_cmp);
 
2987
    
1442
2988
    /* make last element empty */
1443
 
    memset(show, 0, sizeof(drizzle_show_var));
 
2989
    bzero(show, sizeof(SHOW_VAR));
1444
2990
  }
1445
2991
  return result;
1446
2992
}
1447
2993
 
1448
2994
 
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
2995
/*
1481
2996
  Initialize the system variables
1482
 
 
 
2997
  
1483
2998
  SYNOPSIS
1484
 
    sys_var_init()
1485
 
 
 
2999
    set_var_init()
 
3000
  
1486
3001
  RETURN VALUES
1487
3002
    0           SUCCESS
1488
3003
    otherwise   FAILURE
1489
3004
*/
1490
3005
 
1491
 
int sys_var_init()
 
3006
int set_var_init()
1492
3007
{
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
 
  }
 
3008
  uint count= 0;
 
3009
  
 
3010
  for (sys_var *var=vars.first; var; var= var->next, count++) {};
 
3011
 
 
3012
  if (my_init_dynamic_array(&fixed_show_vars, sizeof(SHOW_VAR),
 
3013
                            FIXED_VARS_SIZE + 64, 64))
 
3014
    goto error;
 
3015
 
 
3016
  fixed_show_vars.elements= FIXED_VARS_SIZE;
 
3017
  memcpy(fixed_show_vars.buffer, fixed_vars, sizeof(fixed_vars));
 
3018
 
 
3019
  if (hash_init(&system_variable_hash, system_charset_info, count, 0,
 
3020
                0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
 
3021
    goto error;
 
3022
 
 
3023
  vars.last->next= NULL;
 
3024
  if (mysql_add_sys_var_chain(vars.first, my_long_options))
 
3025
    goto error;
 
3026
 
 
3027
  /*
 
3028
    Special cases
 
3029
    Needed because MySQL can't find the limits for a variable it it has
 
3030
    a different name than the command line option.
 
3031
    As these variables are deprecated, this code will disappear soon...
 
3032
  */
 
3033
  sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
 
3034
 
1571
3035
  return(0);
 
3036
 
 
3037
error:
 
3038
  fprintf(stderr, "failed to initialize system variables");
 
3039
  return(1);
 
3040
}
 
3041
 
 
3042
 
 
3043
void set_var_free()
 
3044
{
 
3045
  hash_free(&system_variable_hash);
 
3046
  delete_dynamic(&fixed_show_vars);
 
3047
}
 
3048
 
 
3049
 
 
3050
/*
 
3051
  Add elements to the dynamic list of read-only system variables.
 
3052
  
 
3053
  SYNOPSIS
 
3054
    mysql_append_static_vars()
 
3055
    show_vars   Pointer to start of array
 
3056
    count       Number of elements
 
3057
  
 
3058
  RETURN VALUES
 
3059
    0           SUCCESS
 
3060
    otherwise   FAILURE
 
3061
*/
 
3062
int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count)
 
3063
{
 
3064
  for (; count > 0; count--, show_vars++)
 
3065
    if (insert_dynamic(&fixed_show_vars, (uchar*) show_vars))
 
3066
      return 1;
 
3067
  return 0;
1572
3068
}
1573
3069
 
1574
3070
 
1575
3071
/**
1576
3072
  Find a user set-table variable.
1577
3073
 
1578
 
  @param name      Name of system variable to find
 
3074
  @param str       Name of system variable to find
 
3075
  @param length    Length of variable.  zero means that we should use strlen()
 
3076
                   on the variable
 
3077
  @param no_error  Refuse to emit an error, even if one occurred.
1579
3078
 
1580
3079
  @retval
1581
3080
    pointer     pointer to variable definitions
1583
3082
    0           Unknown variable (error message is given)
1584
3083
*/
1585
3084
 
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
 
 
 
3085
sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
 
3086
{
 
3087
  sys_var *var;
 
3088
 
 
3089
  /*
 
3090
    This function is only called from the sql_plugin.cc.
 
3091
    A lock on LOCK_system_variable_hash should be held
 
3092
  */
 
3093
  var= (sys_var*) hash_search(&system_variable_hash,
 
3094
                              (uchar*) str, length ? length : strlen(str));
 
3095
  if (!(var || no_error))
 
3096
    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
 
3097
 
 
3098
  return var;
 
3099
}
 
3100
 
 
3101
 
 
3102
/**
 
3103
  Execute update of all variables.
 
3104
 
 
3105
  First run a check of all variables that all updates will go ok.
 
3106
  If yes, then execute all updates, returning an error if any one failed.
 
3107
 
 
3108
  This should ensure that in all normal cases none all or variables are
 
3109
  updated.
 
3110
 
 
3111
  @param THD            Thread id
 
3112
  @param var_list       List of variables to update
 
3113
 
 
3114
  @retval
 
3115
    0   ok
 
3116
  @retval
 
3117
    1   ERROR, message sent (normally no variables was updated)
 
3118
  @retval
 
3119
    -1  ERROR, message not sent
 
3120
*/
 
3121
 
 
3122
int sql_set_variables(THD *thd, List<set_var_base> *var_list)
 
3123
{
 
3124
  int error;
 
3125
  List_iterator_fast<set_var_base> it(*var_list);
 
3126
 
 
3127
  set_var_base *var;
 
3128
  while ((var=it++))
 
3129
  {
 
3130
    if ((error= var->check(thd)))
 
3131
      goto err;
 
3132
  }
 
3133
  if (!(error= test(thd->is_error())))
 
3134
  {
 
3135
    it.rewind();
 
3136
    while ((var= it++))
 
3137
      error|= var->update(thd);         // Returns 0, -1 or 1
 
3138
  }
 
3139
 
 
3140
err:
 
3141
  free_underlaid_joins(thd, &thd->lex->select_lex);
 
3142
  return(error);
 
3143
}
 
3144
 
 
3145
 
 
3146
/**
 
3147
  Say if all variables set by a SET support the ONE_SHOT keyword
 
3148
  (currently, only character set and collation do; later timezones
 
3149
  will).
 
3150
 
 
3151
  @param var_list       List of variables to update
 
3152
 
 
3153
  @note
 
3154
    It has a "not_" because it makes faster tests (no need to "!")
 
3155
 
 
3156
  @retval
 
3157
    0   all variables of the list support ONE_SHOT
 
3158
  @retval
 
3159
    1   at least one does not support ONE_SHOT
 
3160
*/
 
3161
 
 
3162
bool not_all_support_one_shot(List<set_var_base> *var_list)
 
3163
{
 
3164
  List_iterator_fast<set_var_base> it(*var_list);
 
3165
  set_var_base *var;
 
3166
  while ((var= it++))
 
3167
  {
 
3168
    if (var->no_support_one_shot())
 
3169
      return 1;
 
3170
  }
 
3171
  return 0;
 
3172
}
 
3173
 
 
3174
 
 
3175
/*****************************************************************************
 
3176
  Functions to handle SET mysql_internal_variable=const_expr
 
3177
*****************************************************************************/
 
3178
 
 
3179
int set_var::check(THD *thd)
 
3180
{
 
3181
  if (var->is_readonly())
 
3182
  {
 
3183
    my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
 
3184
    return -1;
 
3185
  }
 
3186
  if (var->check_type(type))
 
3187
  {
 
3188
    int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
 
3189
    my_error(err, MYF(0), var->name);
 
3190
    return -1;
 
3191
  }
 
3192
  /* value is a NULL pointer if we are using SET ... = DEFAULT */
 
3193
  if (!value)
 
3194
  {
 
3195
    if (var->check_default(type))
 
3196
    {
 
3197
      my_error(ER_NO_DEFAULT, MYF(0), var->name);
 
3198
      return -1;
 
3199
    }
 
3200
    return 0;
 
3201
  }
 
3202
 
 
3203
  if ((!value->fixed &&
 
3204
       value->fix_fields(thd, &value)) || value->check_cols(1))
 
3205
    return -1;
 
3206
  if (var->check_update_type(value->result_type()))
 
3207
  {
 
3208
    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
 
3209
    return -1;
 
3210
  }
 
3211
  return var->check(thd, this) ? -1 : 0;
 
3212
}
 
3213
 
 
3214
/**
 
3215
  Update variable
 
3216
 
 
3217
  @param   thd    thread handler
 
3218
  @returns 0|1    ok or ERROR
 
3219
 
 
3220
  @note ERROR can be only due to abnormal operations involving
 
3221
  the server's execution evironment such as
 
3222
  out of memory, hard disk failure or the computer blows up.
 
3223
  Consider set_var::check() method if there is a need to return
 
3224
  an error due to logics.
 
3225
*/
 
3226
int set_var::update(THD *thd)
 
3227
{
 
3228
  if (!value)
 
3229
    var->set_default(thd, type);
 
3230
  else if (var->update(thd, this))
 
3231
    return -1;                          // should never happen
 
3232
  if (var->after_update)
 
3233
    (*var->after_update)(thd, type);
 
3234
  return 0;
 
3235
}
 
3236
 
 
3237
 
 
3238
/*****************************************************************************
 
3239
  Functions to handle SET @user_variable=const_expr
 
3240
*****************************************************************************/
 
3241
 
 
3242
int set_var_user::check(THD *thd)
 
3243
{
 
3244
  /*
 
3245
    Item_func_set_user_var can't substitute something else on its place =>
 
3246
    0 can be passed as last argument (reference on item)
 
3247
  */
 
3248
  return (user_var_item->fix_fields(thd, (Item**) 0) ||
 
3249
          user_var_item->check(0)) ? -1 : 0;
 
3250
}
 
3251
 
 
3252
 
 
3253
int set_var_user::update(THD *thd __attribute__((__unused__)))
 
3254
{
 
3255
  if (user_var_item->update())
 
3256
  {
 
3257
    /* Give an error if it's not given already */
 
3258
    my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
 
3259
    return -1;
 
3260
  }
 
3261
  return 0;
 
3262
}
1609
3263
 
1610
3264
/****************************************************************************
1611
3265
 Functions to handle table_type
1612
3266
****************************************************************************/
1613
3267
 
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());
 
3268
/* Based upon sys_var::check_enum() */
 
3269
 
 
3270
bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
 
3271
{
 
3272
  char buff[STRING_BUFFER_USUAL_SIZE];
 
3273
  const char *value;
 
3274
  String str(buff, sizeof(buff), &my_charset_latin1), *res;
 
3275
 
 
3276
  var->save_result.plugin= NULL;
 
3277
  if (var->value->result_type() == STRING_RESULT)
 
3278
  {
 
3279
    LEX_STRING engine_name;
 
3280
    handlerton *hton;
 
3281
    if (!(res=var->value->val_str(&str)) ||
 
3282
        !(engine_name.str= (char *)res->ptr()) ||
 
3283
        !(engine_name.length= res->length()) ||
 
3284
        !(var->save_result.plugin= ha_resolve_by_name(thd, &engine_name)) ||
 
3285
        !(hton= plugin_data(var->save_result.plugin, handlerton *)) ||
 
3286
        ha_checktype(thd, ha_legacy_type(hton), 1, 0) != hton)
 
3287
    {
 
3288
      value= res ? res->c_ptr() : "NULL";
 
3289
      goto err;
 
3290
    }
 
3291
    return 0;
 
3292
  }
 
3293
  value= "unknown";
 
3294
 
 
3295
err:
 
3296
  my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
 
3297
  return 1;
 
3298
}
 
3299
 
 
3300
 
 
3301
uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
 
3302
                                             LEX_STRING *base __attribute__((__unused__)))
 
3303
{
 
3304
  uchar* result;
 
3305
  handlerton *hton;
 
3306
  LEX_STRING *engine_name;
 
3307
  plugin_ref plugin= thd->variables.*offset;
 
3308
  if (type == OPT_GLOBAL)
 
3309
    plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
 
3310
  hton= plugin_data(plugin, handlerton*);
 
3311
  engine_name= &hton2plugin[hton->slot]->name;
 
3312
  result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
 
3313
  if (type == OPT_GLOBAL)
 
3314
    plugin_unlock(thd, plugin);
1626
3315
  return result;
1627
3316
}
1628
3317
 
1629
3318
 
1630
 
void sys_var_session_storage_engine::set_default(Session *session, sql_var_t type)
 
3319
void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
1631
3320
{
1632
 
  plugin::StorageEngine *old_value, *new_value, **value;
 
3321
  plugin_ref old_value, new_value, *value;
1633
3322
  if (type == OPT_GLOBAL)
1634
3323
  {
1635
3324
    value= &(global_system_variables.*offset);
1636
 
    new_value= myisam_engine;
 
3325
    new_value= ha_lock_engine(NULL, myisam_hton);
1637
3326
  }
1638
3327
  else
1639
3328
  {
1640
 
    value= &(session->variables.*offset);
1641
 
    new_value= global_system_variables.*offset;
 
3329
    value= &(thd->variables.*offset);
 
3330
    new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
1642
3331
  }
1643
3332
  assert(new_value);
1644
3333
  old_value= *value;
1645
3334
  *value= new_value;
 
3335
  plugin_unlock(NULL, old_value);
1646
3336
}
1647
3337
 
1648
3338
 
1649
 
bool sys_var_session_storage_engine::update(Session *session, set_var *var)
 
3339
bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
1650
3340
{
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);
 
3341
  plugin_ref *value= &(global_system_variables.*offset), old_value;
1683
3342
   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 */
 
3343
     value= &(thd->variables.*offset);
 
3344
  old_value= *value;
 
3345
  if (old_value != var->save_result.plugin)
 
3346
  {
 
3347
    *value= my_plugin_lock(NULL, &var->save_result.plugin);
 
3348
    plugin_unlock(NULL, old_value);
 
3349
  }
 
3350
  return 0;
 
3351
}
 
3352
 
 
3353
bool
 
3354
sys_var_thd_optimizer_switch::
 
3355
symbolic_mode_representation(THD *thd, uint64_t val, LEX_STRING *rep)
 
3356
{
 
3357
  char buff[STRING_BUFFER_USUAL_SIZE*8];
 
3358
  String tmp(buff, sizeof(buff), &my_charset_latin1);
 
3359
 
 
3360
  tmp.length(0);
 
3361
 
 
3362
  for (uint i= 0; val; val>>= 1, i++)
 
3363
  {
 
3364
    if (val & 1)
 
3365
    {
 
3366
      tmp.append(optimizer_switch_typelib.type_names[i],
 
3367
                 optimizer_switch_typelib.type_lengths[i]);
 
3368
      tmp.append(',');
 
3369
    }
 
3370
  }
 
3371
 
 
3372
  if (tmp.length())
 
3373
    tmp.length(tmp.length() - 1); /* trim the trailing comma */
 
3374
 
 
3375
  rep->str= thd->strmake(tmp.ptr(), tmp.length());
 
3376
 
 
3377
  rep->length= rep->str ? tmp.length() : 0;
 
3378
 
 
3379
  return rep->length != tmp.length();
 
3380
}
 
3381
 
 
3382
 
 
3383
uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
 
3384
                                               LEX_STRING *base __attribute__((__unused__)))
 
3385
{
 
3386
  LEX_STRING opts;
 
3387
  uint64_t val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
 
3388
                  thd->variables.*offset);
 
3389
  (void) symbolic_mode_representation(thd, val, &opts);
 
3390
  return (uchar *) opts.str;
 
3391
}
 
3392
 
 
3393
 
 
3394
void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
 
3395
{
 
3396
  if (type == OPT_GLOBAL)
 
3397
    global_system_variables.*offset= 0;
 
3398
  else
 
3399
    thd->variables.*offset= global_system_variables.*offset;
 
3400
}
 
3401
 
 
3402
 
 
3403
/****************************************************************************
 
3404
  Named list handling
 
3405
****************************************************************************/
 
3406
 
 
3407
uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
 
3408
                NAMED_LIST **found)
 
3409
{
 
3410
  I_List_iterator<NAMED_LIST> it(*list);
 
3411
  NAMED_LIST *element;
 
3412
  while ((element= it++))
 
3413
  {
 
3414
    if (element->cmp(name, length))
 
3415
    {
 
3416
      if (found)
 
3417
        *found= element;
 
3418
      return element->data;
 
3419
    }
 
3420
  }
 
3421
  return 0;
 
3422
}
 
3423
 
 
3424
 
 
3425
void delete_elements(I_List<NAMED_LIST> *list,
 
3426
                     void (*free_element)(const char *name, uchar*))
 
3427
{
 
3428
  NAMED_LIST *element;
 
3429
  while ((element= list->get()))
 
3430
  {
 
3431
    (*free_element)(element->name, element->data);
 
3432
    delete element;
 
3433
  }
 
3434
  return;
 
3435
}
 
3436
 
 
3437
 
 
3438
/* Key cache functions */
 
3439
 
 
3440
static KEY_CACHE *create_key_cache(const char *name, uint length)
 
3441
{
 
3442
  KEY_CACHE *key_cache;
 
3443
  
 
3444
  if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
 
3445
                                             MYF(MY_ZEROFILL | MY_WME))))
 
3446
  {
 
3447
    if (!new NAMED_LIST(&key_caches, name, length, (uchar*) key_cache))
 
3448
    {
 
3449
      my_free((char*) key_cache, MYF(0));
 
3450
      key_cache= 0;
 
3451
    }
 
3452
    else
 
3453
    {
 
3454
      /*
 
3455
        Set default values for a key cache
 
3456
        The values in dflt_key_cache_var is set by my_getopt() at startup
 
3457
 
 
3458
        We don't set 'buff_size' as this is used to enable the key cache
 
3459
      */
 
3460
      key_cache->param_block_size=     dflt_key_cache_var.param_block_size;
 
3461
      key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
 
3462
      key_cache->param_age_threshold=  dflt_key_cache_var.param_age_threshold;
 
3463
    }
 
3464
  }
 
3465
  return(key_cache);
 
3466
}
 
3467
 
 
3468
 
 
3469
KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
 
3470
{
 
3471
  LEX_STRING key_cache_name;
 
3472
  KEY_CACHE *key_cache;
 
3473
 
 
3474
  key_cache_name.str= (char *) name;
 
3475
  key_cache_name.length= length;
 
3476
  pthread_mutex_lock(&LOCK_global_system_variables);
 
3477
  if (!(key_cache= get_key_cache(&key_cache_name)))
 
3478
    key_cache= create_key_cache(name, length);
 
3479
  pthread_mutex_unlock(&LOCK_global_system_variables);
 
3480
  return key_cache;
 
3481
}
 
3482
 
 
3483
 
 
3484
void free_key_cache(const char *name __attribute__((__unused__)),
 
3485
                    KEY_CACHE *key_cache)
 
3486
{
 
3487
  ha_end_key_cache(key_cache);
 
3488
  my_free((char*) key_cache, MYF(0));
 
3489
}
 
3490
 
 
3491
 
 
3492
bool process_key_caches(process_key_cache_t func)
 
3493
{
 
3494
  I_List_iterator<NAMED_LIST> it(key_caches);
 
3495
  NAMED_LIST *element;
 
3496
 
 
3497
  while ((element= it++))
 
3498
  {
 
3499
    KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
 
3500
    func(element->name, key_cache);
 
3501
  }
 
3502
  return 0;
 
3503
}
 
3504
 
 
3505
 
 
3506
bool sys_var_opt_readonly::update(THD *thd, set_var *var)
 
3507
{
 
3508
  bool result;
 
3509
 
 
3510
  /* Prevent self dead-lock */
 
3511
  if (thd->locked_tables || thd->active_transaction())
 
3512
  {
 
3513
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
3514
    return(true);
 
3515
  }
 
3516
 
 
3517
  if (thd->global_read_lock)
 
3518
  {
 
3519
    /*
 
3520
      This connection already holds the global read lock.
 
3521
      This can be the case with:
 
3522
      - FLUSH TABLES WITH READ LOCK
 
3523
      - SET GLOBAL READ_ONLY = 1
 
3524
    */
 
3525
    result= sys_var_bool_ptr::update(thd, var);
 
3526
    return(result);
 
3527
  }
 
3528
 
 
3529
  /*
 
3530
    Perform a 'FLUSH TABLES WITH READ LOCK'.
 
3531
    This is a 3 step process:
 
3532
    - [1] lock_global_read_lock()
 
3533
    - [2] close_cached_tables()
 
3534
    - [3] make_global_read_lock_block_commit()
 
3535
    [1] prevents new connections from obtaining tables locked for write.
 
3536
    [2] waits until all existing connections close their tables.
 
3537
    [3] prevents transactions from being committed.
 
3538
  */
 
3539
 
 
3540
  if (lock_global_read_lock(thd))
 
3541
    return(true);
 
3542
 
 
3543
  /*
 
3544
    This call will be blocked by any connection holding a READ or WRITE lock.
 
3545
    Ideally, we want to wait only for pending WRITE locks, but since:
 
3546
    con 1> LOCK TABLE T FOR READ;
 
3547
    con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
 
3548
    con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
 
3549
    can cause to wait on a read lock, it's required for the client application
 
3550
    to unlock everything, and acceptable for the server to wait on all locks.
 
3551
  */
 
3552
  if ((result= close_cached_tables(thd, NULL, false, true, true)) == true)
 
3553
    goto end_with_read_lock;
 
3554
 
 
3555
  if ((result= make_global_read_lock_block_commit(thd)) == true)
 
3556
    goto end_with_read_lock;
 
3557
 
 
3558
  /* Change the opt_readonly system variable, safe because the lock is held */
 
3559
  result= sys_var_bool_ptr::update(thd, var);
 
3560
 
 
3561
end_with_read_lock:
 
3562
  /* Release the lock */
 
3563
  unlock_global_read_lock(thd);
 
3564
  return(result);
 
3565
}
 
3566
 
 
3567
/****************************************************************************
 
3568
  Used templates
 
3569
****************************************************************************/
 
3570
 
 
3571
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3572
template class List<set_var_base>;
 
3573
template class List_iterator_fast<set_var_base>;
 
3574
template class I_List_iterator<NAMED_LIST>;
 
3575
#endif