Drizzled Public API Documentation

sys_var.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00041 #include <config.h>
00042 #include <drizzled/option.h>
00043 #include <drizzled/error.h>
00044 #include <drizzled/gettext.h>
00045 #include <drizzled/data_home.h>
00046 #include <drizzled/set_var.h>
00047 #include <drizzled/session.h>
00048 #include <drizzled/session/times.h>
00049 #include <drizzled/sql_base.h>
00050 #include <drizzled/lock.h>
00051 #include <drizzled/item/uint.h>
00052 #include <drizzled/item/null.h>
00053 #include <drizzled/item/float.h>
00054 #include <drizzled/item/string.h>
00055 #include <drizzled/plugin.h>
00056 #include <drizzled/version.h>
00057 #include <drizzled/internal/m_string.h>
00058 #include <drizzled/pthread_globals.h>
00059 #include <drizzled/charset.h>
00060 #include <drizzled/transaction_services.h>
00061 #include <drizzled/constrained_value.h>
00062 #include <drizzled/visibility.h>
00063 #include <drizzled/typelib.h>
00064 #include <drizzled/plugin/storage_engine.h>
00065 #include <drizzled/system_variables.h>
00066 #include <drizzled/catalog/instance.h>
00067 
00068 #include <cstdio>
00069 #include <map>
00070 #include <vector>
00071 #include <algorithm>
00072 
00073 using namespace std;
00074 
00075 namespace drizzled {
00076 
00077 namespace internal
00078 {
00079   extern bool timed_mutexes;
00080 }
00081 
00082 extern plugin::StorageEngine *myisam_engine;
00083 extern bool timed_mutexes;
00084 
00085 extern struct option my_long_options[];
00086 extern const charset_info_st *character_set_filesystem;
00087 extern size_t my_thread_stack_size;
00088 
00089 typedef map<string, sys_var *> SystemVariableMap;
00090 static SystemVariableMap system_variable_map;
00091 extern char *opt_drizzle_tmpdir;
00092 
00093 extern TYPELIB tx_isolation_typelib;
00094 
00095 namespace
00096 {
00097   static size_t revno= DRIZZLE7_VC_REVNO;
00098   static size_t release_id= DRIZZLE7_RELEASE_ID;
00099 }
00100 
00101 const char *bool_type_names[]= { "OFF", "ON", NULL };
00102 TYPELIB bool_typelib=
00103 {
00104   array_elements(bool_type_names)-1, "", bool_type_names, NULL
00105 };
00106 
00107 static bool set_option_bit(Session*, set_var*);
00108 static bool set_option_autocommit(Session*, set_var*);
00109 static int  check_pseudo_thread_id(Session*, set_var*);
00110 static int check_tx_isolation(Session*, set_var*);
00111 static void fix_tx_isolation(Session*, sql_var_t);
00112 static int check_completion_type(Session*, set_var*);
00113 static void fix_max_join_size(Session*, sql_var_t);
00114 static void fix_session_mem_root(Session*, sql_var_t);
00115 void throw_bounds_warning(Session*, bool fixed, bool unsignd, const std::string &name, int64_t);
00116 static unsigned char *get_error_count(Session*);
00117 static unsigned char *get_warning_count(Session*);
00118 static unsigned char *get_tmpdir(Session*);
00119 
00120 /*
00121   Variable definition list
00122 
00123   These are variables that can be set from the command line, in
00124   alphabetic order.
00125 
00126   The variables are linked into the list. A variable is added to
00127   it in the constructor (see sys_var class for details).
00128 */
00129 static sys_var_session_uint64_t
00130 sys_auto_increment_increment("auto_increment_increment", &drizzle_system_variables::auto_increment_increment);
00131 static sys_var_session_uint64_t
00132 sys_auto_increment_offset("auto_increment_offset", &drizzle_system_variables::auto_increment_offset);
00133 
00134 static sys_var_fs_path sys_basedir("basedir", basedir);
00135 static sys_var_fs_path sys_pid_file("pid_file", pid_file);
00136 static sys_var_fs_path sys_plugin_dir("plugin_dir", plugin_dir);
00137 
00138 static sys_var_size_t_ptr sys_thread_stack_size("thread_stack", &my_thread_stack_size);
00139 static sys_var_constrained_value_readonly<uint32_t> sys_back_log("back_log", back_log);
00140 
00141 static sys_var_session_uint64_t sys_bulk_insert_buff_size("bulk_insert_buffer_size", &drizzle_system_variables::bulk_insert_buff_size);
00142 static sys_var_session_uint32_t sys_completion_type("completion_type", &drizzle_system_variables::completion_type, check_completion_type);
00143 static sys_var_collation_sv
00144 sys_collation_server("collation_server", &drizzle_system_variables::collation_server, &default_charset_info);
00145 static sys_var_fs_path sys_datadir("datadir", getDataHome());
00146 
00147 static sys_var_session_uint64_t sys_join_buffer_size("join_buffer_size", &drizzle_system_variables::join_buff_size);
00148 static sys_var_session_uint32_t sys_max_allowed_packet("max_allowed_packet", &drizzle_system_variables::max_allowed_packet);
00149 static sys_var_session_uint64_t sys_max_error_count("max_error_count", &drizzle_system_variables::max_error_count);
00150 static sys_var_session_uint64_t sys_max_heap_table_size("max_heap_table_size", &drizzle_system_variables::max_heap_table_size);
00151 static sys_var_session_uint64_t sys_pseudo_thread_id("pseudo_thread_id", &drizzle_system_variables::pseudo_thread_id, 0, check_pseudo_thread_id);
00152 static sys_var_session_ha_rows  sys_max_join_size("max_join_size", &drizzle_system_variables::max_join_size, fix_max_join_size);
00153 static sys_var_session_uint64_t sys_max_seeks_for_key("max_seeks_for_key", &drizzle_system_variables::max_seeks_for_key);
00154 static sys_var_session_uint64_t sys_max_length_for_sort_data("max_length_for_sort_data", &drizzle_system_variables::max_length_for_sort_data);
00155 static sys_var_session_size_t sys_max_sort_length("max_sort_length", &drizzle_system_variables::max_sort_length);
00156 static sys_var_uint64_t_ptr sys_max_write_lock_count("max_write_lock_count", &max_write_lock_count);
00157 static sys_var_session_uint64_t sys_min_examined_row_limit("min_examined_row_limit", &drizzle_system_variables::min_examined_row_limit);
00158 
00159 static sys_var_session_bool sys_optimizer_prune_level("optimizer_prune_level", &drizzle_system_variables::optimizer_prune_level);
00160 static sys_var_session_uint32_t sys_optimizer_search_depth("optimizer_search_depth", &drizzle_system_variables::optimizer_search_depth);
00161 
00162 static sys_var_session_uint64_t sys_preload_buff_size("preload_buffer_size", &drizzle_system_variables::preload_buff_size);
00163 static sys_var_session_uint32_t sys_read_buff_size("read_buffer_size", &drizzle_system_variables::read_buff_size);
00164 static sys_var_session_uint32_t sys_read_rnd_buff_size("read_rnd_buffer_size", &drizzle_system_variables::read_rnd_buff_size);
00165 static sys_var_session_uint32_t sys_div_precincrement("div_precision_increment", &drizzle_system_variables::div_precincrement);
00166 
00167 static sys_var_session_size_t sys_range_alloc_block_size("range_alloc_block_size", &drizzle_system_variables::range_alloc_block_size);
00168 
00169 static sys_var_session_bool sys_replicate_query("replicate_query", &drizzle_system_variables::replicate_query);
00170 
00171 static sys_var_session_uint32_t sys_query_alloc_block_size("query_alloc_block_size", &drizzle_system_variables::query_alloc_block_size, NULL, fix_session_mem_root);
00172 static sys_var_session_uint32_t sys_query_prealloc_size("query_prealloc_size", &drizzle_system_variables::query_prealloc_size, NULL, fix_session_mem_root);
00173 static sys_var_readonly sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
00174 
00175 static sys_var_fs_path sys_secure_file_priv("secure_file_priv", secure_file_priv);
00176 static sys_var_const_str_ptr sys_scheduler("scheduler", (char**)&opt_scheduler);
00177 
00178 static sys_var_uint32_t_ptr  sys_server_id("server_id", &server_id);
00179 
00180 static sys_var_const_string sys_server_uuid("server_uuid", server_uuid);
00181 
00182 static sys_var_session_size_t sys_sort_buffer("sort_buffer_size", &drizzle_system_variables::sortbuff_size);
00183 
00184 static sys_var_size_t_ptr_readonly sys_transaction_message_threshold("transaction_message_threshold", &transaction_message_threshold);
00185 
00186 static sys_var_session_storage_engine sys_storage_engine("storage_engine", &drizzle_system_variables::storage_engine);
00187 static sys_var_size_t_ptr sys_table_def_size("table_definition_cache", &table_def_size);
00188 static sys_var_uint64_t_ptr sys_table_cache_size("table_open_cache", &table_cache_size);
00189 static sys_var_uint64_t_ptr sys_table_lock_wait_timeout("table_lock_wait_timeout", &table_lock_wait_timeout);
00190 static sys_var_session_enum sys_tx_isolation("tx_isolation",
00191                                              &drizzle_system_variables::tx_isolation,
00192                                              &tx_isolation_typelib,
00193                                              fix_tx_isolation,
00194                                              check_tx_isolation);
00195 static sys_var_session_uint64_t sys_tmp_table_size("tmp_table_size",
00196              &drizzle_system_variables::tmp_table_size);
00197 static sys_var_bool_ptr  sys_timed_mutexes("timed_mutexes", &internal::timed_mutexes);
00198 static sys_var_const_str  sys_version("version", version().c_str());
00199 
00200 static sys_var_const_str sys_version_comment("version_comment", COMPILATION_COMMENT);
00201 static sys_var_const_str sys_version_compile_machine("version_compile_machine", HOST_CPU);
00202 static sys_var_const_str sys_version_compile_os("version_compile_os", HOST_OS);
00203 static sys_var_const_str sys_version_compile_vendor("version_compile_vendor", HOST_VENDOR);
00204 
00205 /* Variables that are bits in Session */
00206 
00207 sys_var_session_bit sys_autocommit("autocommit", 0, set_option_autocommit, OPTION_NOT_AUTOCOMMIT, 1);
00208 static sys_var_session_bit sys_big_selects("sql_big_selects", 0, set_option_bit, OPTION_BIG_SELECTS);
00209 static sys_var_session_bit sys_sql_warnings("sql_warnings", 0, set_option_bit, OPTION_WARNINGS);
00210 static sys_var_session_bit sys_sql_notes("sql_notes", 0, set_option_bit, OPTION_SQL_NOTES);
00211 static sys_var_session_bit sys_buffer_results("sql_buffer_result", 0, set_option_bit, OPTION_BUFFER_RESULT);
00212 static sys_var_session_bit sys_foreign_key_checks("foreign_key_checks", 0, set_option_bit, OPTION_NO_FOREIGN_KEY_CHECKS, 1);
00213 static sys_var_session_bit sys_unique_checks("unique_checks", 0, set_option_bit, OPTION_RELAXED_UNIQUE_CHECKS, 1);
00214 /* Local state variables */
00215 
00216 static sys_var_session_ha_rows  sys_select_limit("sql_select_limit", &drizzle_system_variables::select_limit);
00217 static sys_var_timestamp sys_timestamp("timestamp");
00218 static sys_var_last_insert_id
00219 sys_last_insert_id("last_insert_id");
00220 /*
00221   identity is an alias for last_insert_id(), so that we are compatible
00222   with Sybase
00223 */
00224 static sys_var_last_insert_id sys_identity("identity");
00225 
00226 static sys_var_session_lc_time_names sys_lc_time_names("lc_time_names");
00227 
00228 /*
00229   We want statements referring explicitly to @@session.insert_id to be
00230   unsafe, because insert_id is modified internally by the slave sql
00231   thread when NULL values are inserted in an AUTO_INCREMENT column.
00232   This modification interfers with the value of the
00233   @@session.insert_id variable if @@session.insert_id is referred
00234   explicitly by an insert statement (as is seen by executing "SET
00235   @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
00236   AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
00237   statement-based logging mode: t will be different on master and
00238   slave).
00239 */
00240 static sys_var_readonly sys_error_count("error_count", OPT_SESSION, SHOW_INT, get_error_count);
00241 static sys_var_readonly sys_warning_count("warning_count", OPT_SESSION, SHOW_INT, get_warning_count);
00242 
00243 sys_var_session_uint64_t sys_group_concat_max_len("group_concat_max_len", &drizzle_system_variables::group_concat_max_len);
00244 
00245 /* Global read-only variable containing hostname */
00246 static sys_var_const_string sys_hostname("hostname", getServerHostname());
00247 
00248 static sys_var_const_str sys_revid("vc_revid", DRIZZLE7_VC_REVID);
00249 static sys_var_const_str sys_branch("vc_branch", DRIZZLE7_VC_BRANCH);
00250 static sys_var_size_t_ptr_readonly sys_revno("vc_revno", &revno);
00251 static sys_var_size_t_ptr_readonly sys_release_id("vc_release_id", &release_id);
00252 
00253 bool sys_var::check(Session *session, set_var *var)
00254 {
00255   if (check_func)
00256   {
00257     int res= (*check_func)(session, var);
00258     if (res < 0)
00259       my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
00260     return res;
00261   }
00262   var->updateValue();
00263   return 0;
00264 }
00265 
00266 bool sys_var_str::check(Session *session, set_var *var)
00267 {
00268   if (not check_func)
00269     return 0;
00270 
00271   int res= (*check_func)(session, var);
00272   if (res < 0)
00273     my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
00274   return res;
00275 }
00276 
00277 bool sys_var_std_string::check(Session *session, set_var *var)
00278 {
00279   if (not check_func)
00280     return false;
00281 
00282   if ((*check_func)(session, var))
00283   {
00284     my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), getName().c_str(), var->value->str_value.ptr());
00285     return true;
00286   }
00287   return false;
00288 }
00289 
00290 /*
00291   Functions to check and update variables
00292 */
00293 
00294 
00299 static void fix_max_join_size(Session *session, sql_var_t type)
00300 {
00301   if (type != OPT_GLOBAL)
00302   {
00303     if (session->variables.max_join_size == HA_POS_ERROR)
00304       session->options|= OPTION_BIG_SELECTS;
00305     else
00306       session->options&= ~OPTION_BIG_SELECTS;
00307   }
00308 }
00309 
00310 
00315 static int check_tx_isolation(Session *session, set_var *var)
00316 {
00317   if (var->type == OPT_DEFAULT && (session->server_status & SERVER_STATUS_IN_TRANS))
00318   {
00319     my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
00320     return 1;
00321   }
00322   return 0;
00323 }
00324 
00325 /*
00326   If one doesn't use the SESSION modifier, the isolation level
00327   is only active for the next command.
00328 */
00329 static void fix_tx_isolation(Session *session, sql_var_t type)
00330 {
00331   if (type == OPT_SESSION)
00332     session->session_tx_isolation= (enum_tx_isolation) session->variables.tx_isolation;
00333 }
00334 
00335 static int check_completion_type(Session *, set_var *var)
00336 {
00337   int64_t val= var->value->val_int();
00338   if (val < 0 || val > 2)
00339   {
00340     char buf[64];
00341     my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->getName().c_str(), internal::llstr(val, buf));
00342     return 1;
00343   }
00344   return 0;
00345 }
00346 
00347 
00348 static void fix_session_mem_root(Session *session, sql_var_t type)
00349 {
00350   if (type != OPT_GLOBAL)
00351     session->mem.reset_defaults(session->variables.query_alloc_block_size, session->variables.query_prealloc_size);
00352 }
00353 
00354 
00355 void throw_bounds_warning(Session *session, bool fixed, bool unsignd, const std::string &name, int64_t val)
00356 {
00357   if (not fixed)
00358     return;
00359   char buf[DECIMAL_LONGLONG_DIGITS];
00360 
00361   if (unsignd)
00362     internal::ullstr((uint64_t) val, buf);
00363   else
00364     internal::llstr(val, buf);
00365 
00366   push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00367     ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), name.c_str(), buf);
00368 }
00369 
00370 uint64_t fix_unsigned(Session *session, uint64_t num, const option& option_limits)
00371 {
00372   bool fixed= false;
00373   uint64_t out= getopt_ull_limit_value(num, option_limits, &fixed);
00374 
00375   throw_bounds_warning(session, fixed, true, option_limits.name, (int64_t) num);
00376   return out;
00377 }
00378 
00379 
00380 static size_t fix_size_t(Session *session, size_t num, const option& option_limits)
00381 {
00382   bool fixed= false;
00383   size_t out= (size_t)getopt_ull_limit_value(num, option_limits, &fixed);
00384 
00385   throw_bounds_warning(session, fixed, true, option_limits.name, (int64_t) num);
00386   return out;
00387 }
00388 
00389 bool sys_var_uint32_t_ptr::check(Session *, set_var *var)
00390 {
00391   var->updateValue();
00392   return 0;
00393 }
00394 
00395 bool sys_var_uint32_t_ptr::update(Session *session, set_var *var)
00396 {
00397   uint64_t tmp= var->getInteger();
00398   boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00399 
00400   if (option_limits)
00401   {
00402     uint32_t newvalue= (uint32_t) fix_unsigned(session, tmp, *option_limits);
00403     if (static_cast<uint64_t>(newvalue) == tmp)
00404       *value= newvalue;
00405   }
00406   else
00407   {
00408     *value= static_cast<uint32_t>(tmp);
00409   }
00410 
00411   return 0;
00412 }
00413 
00414 
00415 void sys_var_uint32_t_ptr::set_default(Session *session, sql_var_t)
00416 {
00417   bool not_used;
00418   boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00419   *value= (uint32_t)getopt_ull_limit_value((uint32_t) option_limits->def_value, *option_limits, &not_used);
00420 }
00421 
00422 
00423 bool sys_var_uint64_t_ptr::update(Session *session, set_var *var)
00424 {
00425   uint64_t tmp= var->getInteger();
00426   boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00427 
00428   if (option_limits)
00429   {
00430     uint64_t newvalue= fix_unsigned(session, tmp, *option_limits);
00431     if (newvalue==tmp)
00432       *value= newvalue;
00433   }
00434   else
00435   {
00436     *value= tmp;
00437   }
00438 
00439   return 0;
00440 }
00441 
00442 
00443 void sys_var_uint64_t_ptr::set_default(Session *session, sql_var_t)
00444 {
00445   if (have_default_value)
00446   {
00447     *value= default_value;
00448   }
00449   else
00450   {
00451     bool not_used;
00452     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00453     *value= getopt_ull_limit_value((uint64_t) option_limits->def_value, *option_limits, &not_used);
00454   }
00455 }
00456 
00457 
00458 bool sys_var_size_t_ptr::update(Session *session, set_var *var)
00459 {
00460   size_t tmp= size_t(var->getInteger());
00461 
00462   boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00463 
00464   if (option_limits)
00465     *value= fix_size_t(session, tmp, *option_limits);
00466   else
00467     *value= tmp;
00468 
00469   return 0;
00470 }
00471 
00472 
00473 void sys_var_size_t_ptr::set_default(Session *session, sql_var_t)
00474 {
00475   bool not_used;
00476   boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00477   *value= (size_t)getopt_ull_limit_value((size_t) option_limits->def_value, *option_limits, &not_used);
00478 }
00479 
00480 bool sys_var_bool_ptr::check(Session *session, set_var *var)
00481 {
00482   return check_enum(session, var, &bool_typelib);
00483 }
00484 
00485 bool sys_var_bool_ptr::update(Session *, set_var *var)
00486 {
00487   *value= bool(var->getInteger());
00488   return 0;
00489 }
00490 
00491 
00492 void sys_var_bool_ptr::set_default(Session *, sql_var_t)
00493 {
00494   *value= default_value;
00495 }
00496 
00497 
00498 /*
00499   32 bit types for session variables
00500 */
00501 bool sys_var_session_uint32_t::check(Session *session, set_var *var)
00502 {
00503   var->updateValue();
00504   return (check_func && (*check_func)(session, var));
00505 }
00506 
00507 bool sys_var_session_uint32_t::update(Session *session, set_var *var)
00508 {
00509   uint64_t tmp= var->getInteger();
00510 
00511   /* Don't use bigger value than given with --maximum-variable-name=.. */
00512   if ((uint32_t) tmp > max_system_variables.*offset)
00513   {
00514     throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
00515     tmp= max_system_variables.*offset;
00516   }
00517 
00518   if (option_limits)
00519     tmp= (uint32_t) fix_unsigned(session, tmp, *option_limits);
00520   else if (tmp > UINT32_MAX)
00521   {
00522     tmp= UINT32_MAX;
00523     throw_bounds_warning(session, true, true, getName(), int64_t(var->getInteger()));
00524   }
00525 
00526   if (var->type == OPT_GLOBAL)
00527      global_system_variables.*offset= (uint32_t) tmp;
00528    else
00529      session->variables.*offset= (uint32_t) tmp;
00530 
00531    return 0;
00532  }
00533 
00534 
00535  void sys_var_session_uint32_t::set_default(Session *session, sql_var_t type)
00536  {
00537    if (type == OPT_GLOBAL)
00538    {
00539      bool not_used;
00540      /* We will not come here if option_limits is not set */
00541      global_system_variables.*offset=
00542        (uint32_t) getopt_ull_limit_value((uint32_t) option_limits->def_value, *option_limits, &not_used);
00543    }
00544    else
00545      session->variables.*offset= global_system_variables.*offset;
00546  }
00547 
00548 
00549 unsigned char *sys_var_session_uint32_t::value_ptr(Session *session, sql_var_t type)
00550 {
00551   return type == OPT_GLOBAL
00552     ? (unsigned char*) &(global_system_variables.*offset)
00553     : (unsigned char*) &(session->variables.*offset);
00554 }
00555 
00556 
00557 bool sys_var_session_ha_rows::update(Session *session, set_var *var)
00558 {
00559   uint64_t tmp= var->getInteger();
00560 
00561   /* Don't use bigger value than given with --maximum-variable-name=.. */
00562   if ((ha_rows) tmp > max_system_variables.*offset)
00563     tmp= max_system_variables.*offset;
00564 
00565   if (option_limits)
00566     tmp= (ha_rows) fix_unsigned(session, tmp, *option_limits);
00567   if (var->type == OPT_GLOBAL)
00568   {
00569     /* Lock is needed to make things safe on 32 bit systems */
00570     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00571     global_system_variables.*offset= (ha_rows) tmp;
00572   }
00573   else
00574   {
00575     session->variables.*offset= (ha_rows) tmp;
00576   }
00577 
00578   return 0;
00579 }
00580 
00581 
00582 void sys_var_session_ha_rows::set_default(Session *session, sql_var_t type)
00583 {
00584   if (type == OPT_GLOBAL)
00585   {
00586     bool not_used;
00587     /* We will not come here if option_limits is not set */
00588     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00589     global_system_variables.*offset=
00590       (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value, *option_limits, &not_used);
00591   }
00592   else
00593   {
00594     session->variables.*offset= global_system_variables.*offset;
00595   }
00596 }
00597 
00598 
00599 unsigned char *sys_var_session_ha_rows::value_ptr(Session *session, sql_var_t type)
00600 {
00601   return type == OPT_GLOBAL
00602     ? (unsigned char*) &(global_system_variables.*offset)
00603     : (unsigned char*) &(session->variables.*offset);
00604 }
00605 
00606 bool sys_var_session_uint64_t::check(Session *session, set_var *var)
00607 {
00608   var->updateValue();
00609   return (check_func && (*check_func)(session, var));
00610 }
00611 
00612 bool sys_var_session_uint64_t::update(Session *session,  set_var *var)
00613 {
00614   uint64_t tmp= var->getInteger();
00615 
00616   if (tmp > max_system_variables.*offset)
00617   {
00618     throw_bounds_warning(session, true, true, getName(), (int64_t) tmp);
00619     tmp= max_system_variables.*offset;
00620   }
00621 
00622   if (option_limits)
00623     tmp= fix_unsigned(session, tmp, *option_limits);
00624   if (var->type == OPT_GLOBAL)
00625   {
00626     /* Lock is needed to make things safe on 32 bit systems */
00627     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00628     global_system_variables.*offset= (uint64_t) tmp;
00629   }
00630   else
00631   {
00632     session->variables.*offset= (uint64_t) tmp;
00633   }
00634 
00635   return 0;
00636 }
00637 
00638 
00639 void sys_var_session_uint64_t::set_default(Session *session, sql_var_t type)
00640 {
00641   if (type == OPT_GLOBAL)
00642   {
00643     bool not_used;
00644     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00645     global_system_variables.*offset=
00646       getopt_ull_limit_value((uint64_t) option_limits->def_value, *option_limits, &not_used);
00647   }
00648   else
00649   {
00650     session->variables.*offset= global_system_variables.*offset;
00651   }
00652 }
00653 
00654 
00655 unsigned char *sys_var_session_uint64_t::value_ptr(Session *session, sql_var_t type)
00656 {
00657   return type == OPT_GLOBAL
00658     ? (unsigned char*) &(global_system_variables.*offset)
00659     : (unsigned char*) &(session->variables.*offset);
00660 }
00661 
00662 bool sys_var_session_size_t::check(Session *session, set_var *var)
00663 {
00664   var->updateValue();
00665   return (check_func && (*check_func)(session, var));
00666 }
00667 
00668 bool sys_var_session_size_t::update(Session *session,  set_var *var)
00669 {
00670   size_t tmp= size_t(var->getInteger());
00671 
00672   if (tmp > max_system_variables.*offset)
00673     tmp= max_system_variables.*offset;
00674 
00675   if (option_limits)
00676     tmp= fix_size_t(session, tmp, *option_limits);
00677   if (var->type == OPT_GLOBAL)
00678   {
00679     /* Lock is needed to make things safe on 32 bit systems */
00680     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00681     global_system_variables.*offset= tmp;
00682   }
00683   else
00684   {
00685     session->variables.*offset= tmp;
00686   }
00687 
00688   return 0;
00689 }
00690 
00691 
00692 void sys_var_session_size_t::set_default(Session *session, sql_var_t type)
00693 {
00694   if (type == OPT_GLOBAL)
00695   {
00696     bool not_used;
00697     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
00698     global_system_variables.*offset=
00699       (size_t)getopt_ull_limit_value((size_t) option_limits->def_value, *option_limits, &not_used);
00700   }
00701   else
00702   {
00703     session->variables.*offset= global_system_variables.*offset;
00704   }
00705 }
00706 
00707 
00708 unsigned char *sys_var_session_size_t::value_ptr(Session *session, sql_var_t type)
00709 {
00710   return type == OPT_GLOBAL
00711     ? (unsigned char*) &(global_system_variables.*offset) 
00712     : (unsigned char*) &(session->variables.*offset);
00713 }
00714 
00715 bool sys_var_session_bool::check(Session *session, set_var *var)
00716 {
00717   return check_enum(session, var, &bool_typelib);
00718 }
00719 
00720 bool sys_var_session_bool::update(Session *session,  set_var *var)
00721 {
00722   if (var->type == OPT_GLOBAL)
00723     global_system_variables.*offset= bool(var->getInteger());
00724   else
00725     session->variables.*offset= bool(var->getInteger());
00726 
00727   return 0;
00728 }
00729 
00730 
00731 void sys_var_session_bool::set_default(Session *session,  sql_var_t type)
00732 {
00733   if (type == OPT_GLOBAL)
00734     global_system_variables.*offset= (bool) option_limits->def_value;
00735   else
00736     session->variables.*offset= global_system_variables.*offset;
00737 }
00738 
00739 
00740 unsigned char *sys_var_session_bool::value_ptr(Session *session, sql_var_t type)
00741 {
00742   return type == OPT_GLOBAL
00743     ? (unsigned char*) &(global_system_variables.*offset)
00744     : (unsigned char*) &(session->variables.*offset);
00745 }
00746 
00747 
00748 bool sys_var::check_enum(Session *, set_var *var, const TYPELIB *enum_names)
00749 {
00750   char buff[STRING_BUFFER_USUAL_SIZE];
00751   const char *value;
00752   String str(buff, sizeof(buff), system_charset_info), *res;
00753 
00754   if (var->value->result_type() == STRING_RESULT)
00755   {
00756     res= var->value->val_str(&str);
00757     if (res == NULL)
00758     {
00759       value= "NULL";
00760       goto err;
00761     }
00762 
00763     uint64_t tmp_val= enum_names->find_type(res->ptr(), res->length(), true);
00764     if (tmp_val == 0)
00765     {
00766       value= res->c_ptr();
00767       goto err;
00768     }
00769     var->setValue(tmp_val-1);
00770   }
00771   else
00772   {
00773     uint64_t tmp= var->value->val_int();
00774     if (tmp >= enum_names->count)
00775     {
00776       internal::llstr(tmp,buff);
00777       value=buff;       // Wrong value is here
00778       goto err;
00779     }
00780     var->setValue(tmp); // Save for update
00781   }
00782   return 0;
00783 
00784 err:
00785   my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), value);
00786   return 1;
00787 }
00788 
00789 
00798 Item *sys_var::item(Session *session, sql_var_t var_type)
00799 {
00800   if (check_type(var_type))
00801   {
00802     if (var_type != OPT_DEFAULT)
00803     {
00804       my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), name.c_str(), var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
00805       return 0;
00806     }
00807     /* As there was no local variable, return the global value */
00808     var_type= OPT_GLOBAL;
00809   }
00810   boost::mutex::scoped_lock lock(session->catalog().systemVariableLock());
00811   switch (show_type()) 
00812   {
00813   case SHOW_LONG:
00814   case SHOW_INT:
00815   {
00816     uint32_t value= *(uint*) value_ptr(session, var_type);
00817     return new Item_uint((uint64_t) value);
00818   }
00819   case SHOW_LONGLONG:
00820   {
00821     int64_t value= *(int64_t*) value_ptr(session, var_type);
00822     return new Item_int(value);
00823   }
00824   case SHOW_DOUBLE:
00825   {
00826     double value= *(double*) value_ptr(session, var_type);
00827     /* 6, as this is for now only used with microseconds */
00828     return new Item_float(value, 6);
00829   }
00830   case SHOW_HA_ROWS:
00831   {
00832     ha_rows value= *(ha_rows*) value_ptr(session, var_type);
00833     return new Item_int((uint64_t) value);
00834   }
00835   case SHOW_SIZE:
00836   {
00837     size_t value= *(size_t*) value_ptr(session, var_type);
00838     return new Item_int((uint64_t) value);
00839   }
00840   case SHOW_MY_BOOL:
00841   {
00842     int32_t value= *(bool*) value_ptr(session, var_type);
00843     return new Item_int(value, 1);
00844   }
00845   case SHOW_CHAR_PTR:
00846   {
00847     if (const char *str= *(char**) value_ptr(session, var_type))
00848     {
00849       uint32_t length= strlen(str);
00850       return new Item_string(session->mem.strdup(str, length), length, system_charset_info, DERIVATION_SYSCONST);
00851     }
00852     Item* tmp= new Item_null();
00853     tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
00854     return tmp;
00855   }
00856   case SHOW_CHAR:
00857   {
00858     if (const char* str= (char*) value_ptr(session, var_type))
00859       return new Item_string(str_ref(str), system_charset_info, DERIVATION_SYSCONST);
00860     Item* tmp= new Item_null();
00861     tmp->collation.set(system_charset_info, DERIVATION_SYSCONST);
00862     return tmp;
00863   }
00864   default:
00865     my_error(ER_VAR_CANT_BE_READ, MYF(0), name.c_str());
00866   }
00867   return NULL;
00868 }
00869 
00870 
00871 bool sys_var_session_enum::update(Session *session, set_var *var)
00872 {
00873   if (var->type == OPT_GLOBAL)
00874     global_system_variables.*offset= var->getInteger();
00875   else
00876     session->variables.*offset= var->getInteger();
00877   return 0;
00878 }
00879 
00880 
00881 void sys_var_session_enum::set_default(Session *session, sql_var_t type)
00882 {
00883   if (type == OPT_GLOBAL)
00884     global_system_variables.*offset= (uint32_t) option_limits->def_value;
00885   else
00886     session->variables.*offset= global_system_variables.*offset;
00887 }
00888 
00889 
00890 unsigned char *sys_var_session_enum::value_ptr(Session *session, sql_var_t type)
00891 {
00892   uint32_t tmp= type == OPT_GLOBAL ? global_system_variables.*offset : session->variables.*offset;
00893   return (unsigned char*) enum_names->type_names[tmp];
00894 }
00895 
00896 bool sys_var_session_bit::check(Session *session, set_var *var)
00897 {
00898   return check_enum(session, var, &bool_typelib) || (check_func && (*check_func)(session, var));
00899 }
00900 
00901 bool sys_var_session_bit::update(Session *session, set_var *var)
00902 {
00903   return (*update_func)(session, var);
00904 }
00905 
00906 
00907 unsigned char *sys_var_session_bit::value_ptr(Session *session, sql_var_t)
00908 {
00909   /*
00910     If reverse is 0 (default) return 1 if bit is set.
00911     If reverse is 1, return 0 if bit is set
00912   */
00913   session->sys_var_tmp.bool_value= (session->options & bit_flag) ? !reverse : reverse;
00914   return (unsigned char*) &session->sys_var_tmp.bool_value;
00915 }
00916 
00917 
00918 bool sys_var_collation_sv::update(Session *session, set_var *var)
00919 {
00920   const charset_info_st *tmp;
00921 
00922   if (var->value->result_type() == STRING_RESULT)
00923   {
00924     char buff[STRING_BUFFER_USUAL_SIZE];
00925     String str(buff,sizeof(buff), system_charset_info), *res;
00926     if (!(res=var->value->val_str(&str)))
00927     {
00928       boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string("NULL")));
00929       return 1;
00930     }
00931     if (!(tmp=get_charset_by_name(res->c_ptr())))
00932     {
00933       my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
00934       boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(std::string(res->c_ptr())));
00935       return 1;
00936     }
00937   }
00938   else // INT_RESULT
00939   {
00940     if (!(tmp=get_charset((int) var->value->val_int())))
00941     {
00942       char buf[20];
00943       internal::int10_to_str((int) var->value->val_int(), buf, -10);
00944       my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
00945       boost::throw_exception(invalid_option_value(var->var->getName()) << invalid_value(boost::lexical_cast<std::string>(var->value->val_int())));
00946       return 1;
00947     }
00948   }
00949   if (var->type == OPT_GLOBAL)
00950     global_system_variables.*offset= tmp;
00951   else
00952   {
00953     session->variables.*offset= tmp;
00954   }
00955   return 0;
00956 }
00957 
00958 
00959 void sys_var_collation_sv::set_default(Session *session, sql_var_t type)
00960 {
00961   if (type == OPT_GLOBAL)
00962     global_system_variables.*offset= *global_default;
00963   else
00964   {
00965     session->variables.*offset= global_system_variables.*offset;
00966   }
00967 }
00968 
00969 
00970 unsigned char *sys_var_collation_sv::value_ptr(Session *session, sql_var_t type)
00971 {
00972   const charset_info_st *cs= type == OPT_GLOBAL ? global_system_variables.*offset : session->variables.*offset;
00973   return cs ? (unsigned char*) cs->name : (unsigned char*) "NULL";
00974 }
00975 
00976 /****************************************************************************/
00977 
00978 bool sys_var_timestamp::update(Session *session,  set_var *var)
00979 {
00980   session->times.set_time(time_t(var->getInteger()));
00981   return 0;
00982 }
00983 
00984 
00985 void sys_var_timestamp::set_default(Session *session, sql_var_t)
00986 {
00987   session->times.resetUserTime();
00988 }
00989 
00990 
00991 unsigned char *sys_var_timestamp::value_ptr(Session *session, sql_var_t)
00992 {
00993   session->sys_var_tmp.int32_t_value= (int32_t) session->times.getCurrentTimestampEpoch();
00994   return (unsigned char*) &session->sys_var_tmp.int32_t_value;
00995 }
00996 
00997 
00998 bool sys_var_last_insert_id::update(Session *session, set_var *var)
00999 {
01000   session->first_successful_insert_id_in_prev_stmt= var->getInteger();
01001   return 0;
01002 }
01003 
01004 
01005 unsigned char *sys_var_last_insert_id::value_ptr(Session *session, sql_var_t)
01006 {
01007   /*
01008     this tmp var makes it robust againt change of type of
01009     read_first_successful_insert_id_in_prev_stmt().
01010   */
01011   session->sys_var_tmp.uint64_t_value=
01012     session->read_first_successful_insert_id_in_prev_stmt();
01013   return (unsigned char*) &session->sys_var_tmp.uint64_t_value;
01014 }
01015 
01016 bool sys_var_session_lc_time_names::update(Session *session, set_var *var)
01017 {
01018   MY_LOCALE *locale_match;
01019 
01020   if (var->value->result_type() == INT_RESULT)
01021   {
01022     if (!(locale_match= my_locale_by_number((uint32_t) var->value->val_int())))
01023     {
01024       char buf[DECIMAL_LONGLONG_DIGITS];
01025       internal::int10_to_str((int) var->value->val_int(), buf, -10);
01026       my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
01027       return 1;
01028     }
01029   }
01030   else // STRING_RESULT
01031   {
01032     char buff[6];
01033     String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
01034     if (!(res=var->value->val_str(&str)))
01035     {
01036       my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.c_str(), "NULL");
01037       return 1;
01038     }
01039     const char *locale_str= res->c_ptr();
01040     if (!(locale_match= my_locale_by_name(locale_str)))
01041     {
01042       my_printf_error(ER_UNKNOWN_ERROR,
01043                       "Unknown locale: '%s'", MYF(0), locale_str);
01044       return 1;
01045     }
01046   }
01047 
01048   if (var->type == OPT_GLOBAL)
01049     global_system_variables.lc_time_names= locale_match;
01050   else
01051     session->variables.lc_time_names= locale_match;
01052   return 0;
01053 }
01054 
01055 
01056 unsigned char *sys_var_session_lc_time_names::value_ptr(Session *session, sql_var_t type)
01057 {
01058   return type == OPT_GLOBAL 
01059     ? (unsigned char *) global_system_variables.lc_time_names->name 
01060     : (unsigned char *) session->variables.lc_time_names->name;
01061 }
01062 
01063 
01064 void sys_var_session_lc_time_names::set_default(Session *session, sql_var_t type)
01065 {
01066   if (type == OPT_GLOBAL)
01067     global_system_variables.lc_time_names= my_default_lc_time_names;
01068   else
01069     session->variables.lc_time_names= global_system_variables.lc_time_names;
01070 }
01071 
01072 /*
01073   Handling of microseoncds given as seconds.part_seconds
01074 
01075   NOTES
01076     The argument to long query time is in seconds in decimal
01077     which is converted to uint64_t integer holding microseconds for storage.
01078     This is used for handling long_query_time
01079 */
01080 
01081 bool sys_var_microseconds::update(Session *session, set_var *var)
01082 {
01083   double num= var->value->val_real();
01084   int64_t microseconds;
01085   if (num > (double) option_limits->max_value)
01086     num= (double) option_limits->max_value;
01087   if (num < (double) option_limits->min_value)
01088     num= (double) option_limits->min_value;
01089   microseconds= (int64_t) (num * 1000000.0 + 0.5);
01090   if (var->type == OPT_GLOBAL)
01091   {
01092     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
01093     (global_system_variables.*offset)= microseconds;
01094   }
01095   else
01096     session->variables.*offset= microseconds;
01097   return 0;
01098 }
01099 
01100 
01101 void sys_var_microseconds::set_default(Session *session, sql_var_t type)
01102 {
01103   int64_t microseconds= (int64_t) (option_limits->def_value * 1000000.0);
01104   if (type == OPT_GLOBAL)
01105   {
01106     boost::mutex::scoped_lock scopedLock(session->catalog().systemVariableLock());
01107     global_system_variables.*offset= microseconds;
01108   }
01109   else
01110     session->variables.*offset= microseconds;
01111 }
01112 
01113 /*
01114   Functions to update session->options bits
01115 */
01116 
01117 static bool set_option_bit(Session *session, set_var *var)
01118 {
01119   sys_var_session_bit *sys_var= ((sys_var_session_bit*) var->var);
01120   if ((var->getInteger() != 0) == sys_var->reverse)
01121     session->options&= ~sys_var->bit_flag;
01122   else
01123     session->options|= sys_var->bit_flag;
01124   return 0;
01125 }
01126 
01127 
01128 static bool set_option_autocommit(Session *session, set_var *var)
01129 {
01130   bool success= true;
01131   /* The test is negative as the flag we use is NOT autocommit */
01132 
01133   uint64_t org_options= session->options;
01134   uint64_t new_options= session->options;
01135 
01136   if (var->getInteger() != 0)
01137     new_options&= ~((sys_var_session_bit*) var->var)->bit_flag;
01138   else
01139     new_options|= ((sys_var_session_bit*) var->var)->bit_flag;
01140 
01141   if ((org_options ^ new_options) & OPTION_NOT_AUTOCOMMIT)
01142   {
01143     if ((org_options & OPTION_NOT_AUTOCOMMIT))
01144     {
01145       success= session->endActiveTransaction();
01146       /* We changed to auto_commit mode */
01147       session->options&= ~(uint64_t) (OPTION_BEGIN);
01148       session->server_status|= SERVER_STATUS_AUTOCOMMIT;
01149     }
01150     else
01151     {
01152       session->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
01153     }
01154   }
01155 
01156   if (var->getInteger() != 0)
01157     session->options&= ~((sys_var_session_bit*) var->var)->bit_flag;
01158   else
01159     session->options|= ((sys_var_session_bit*) var->var)->bit_flag;
01160 
01161   return not success;
01162 }
01163 
01164 static int check_pseudo_thread_id(Session *, set_var *var)
01165 {
01166   var->updateValue();
01167   return 0;
01168 }
01169 
01170 static unsigned char *get_warning_count(Session *session)
01171 {
01172   session->sys_var_tmp.uint32_t_value=
01173     (session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_NOTE] +
01174      session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR] +
01175      session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_WARN]);
01176   return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
01177 }
01178 
01179 static unsigned char *get_error_count(Session *session)
01180 {
01181   session->sys_var_tmp.uint32_t_value=
01182     session->warn_count[(uint32_t) DRIZZLE_ERROR::WARN_LEVEL_ERROR];
01183   return (unsigned char*) &session->sys_var_tmp.uint32_t_value;
01184 }
01185 
01186 
01201 static unsigned char *get_tmpdir(Session *)
01202 {
01203   assert(drizzle_tmpdir.size());
01204   return (unsigned char*)drizzle_tmpdir.c_str();
01205 }
01206 
01207 /****************************************************************************
01208   Main handling of variables:
01209   - Initialisation
01210   - Searching during parsing
01211   - Update loop
01212 ****************************************************************************/
01213 
01227 static option* find_option(struct option *opt, const char *name)
01228 {
01229   uint32_t length= strlen(name);
01230   for (; opt->name; opt++)
01231   {
01232     if (not getopt_compare_strings(opt->name, name, length) and not opt->name[length])
01233     {
01234       /*
01235       Only accept the option if one can set values through it.
01236       If not, there is no default value or limits in the option.
01237       */
01238       return opt->value ? opt : NULL;
01239     }
01240   }
01241   return NULL;
01242 }
01243 
01244 
01245 
01246 
01247 
01248 /*
01249   Constructs an array of system variables for display to the user.
01250 
01251   SYNOPSIS
01252     enumerate_sys_vars()
01253     session         current thread
01254 
01255   RETURN VALUES
01256     pointer     Array of drizzle_show_var elements for display
01257     NULL        FAILURE
01258 */
01259 
01260 drizzle_show_var* enumerate_sys_vars(Session *session)
01261 {
01262   drizzle_show_var *result= new (session->mem) drizzle_show_var[system_variable_map.size() + 1];
01263   drizzle_show_var *show= result;
01264   BOOST_FOREACH(SystemVariableMap::const_reference iter, system_variable_map)
01265   {
01266     sys_var *var= iter.second;
01267     show->name= var->getName().c_str();
01268     show->value= (char*) var;
01269     show->type= SHOW_SYS;
01270     ++show;
01271   }
01272 
01273   /* make last element empty */
01274   memset(show, 0, sizeof(drizzle_show_var));
01275   return result;
01276 }
01277 
01278 void add_sys_var_to_list(sys_var *var)
01279 {
01280   string lower_name(var->getName());
01281   boost::to_lower(lower_name);
01282 
01283   /* this fails if there is a conflicting variable name. */
01284   if (system_variable_map.count(lower_name))
01285   {
01286     errmsg_printf(error::ERROR, _("Variable named %s already exists!\n"), var->getName().c_str());
01287     throw exception();
01288   } 
01289 
01290   pair<SystemVariableMap::iterator, bool> ret= system_variable_map.insert(make_pair(lower_name, var));
01291   if (ret.second == false)
01292   {
01293     errmsg_printf(error::ERROR, _("Could not add Variable: %s\n"), var->getName().c_str());
01294     throw exception();
01295   }
01296 }
01297 
01298 void add_sys_var_to_list(sys_var *var, struct option *long_options)
01299 {
01300   add_sys_var_to_list(var);
01301   var->setOptionLimits(find_option(long_options, var->getName().c_str()));
01302 }
01303 
01304 /*
01305   Initialize the system variables
01306 
01307   SYNOPSIS
01308     sys_var_init()
01309 
01310   RETURN VALUES
01311     0           SUCCESS
01312     otherwise   FAILURE
01313 */
01314 
01315 int sys_var_init()
01316 {
01317   try
01318   {
01319     add_sys_var_to_list(&sys_auto_increment_increment, my_long_options);
01320     add_sys_var_to_list(&sys_auto_increment_offset, my_long_options);
01321     add_sys_var_to_list(&sys_autocommit, my_long_options);
01322     add_sys_var_to_list(&sys_back_log, my_long_options);
01323     add_sys_var_to_list(&sys_basedir, my_long_options);
01324     add_sys_var_to_list(&sys_big_selects, my_long_options);
01325     add_sys_var_to_list(&sys_branch, my_long_options);
01326     add_sys_var_to_list(&sys_buffer_results, my_long_options);
01327     add_sys_var_to_list(&sys_bulk_insert_buff_size, my_long_options);
01328     add_sys_var_to_list(&sys_collation_server, my_long_options);
01329     add_sys_var_to_list(&sys_completion_type, my_long_options);
01330     add_sys_var_to_list(&sys_datadir, my_long_options);
01331     add_sys_var_to_list(&sys_div_precincrement, my_long_options);
01332     add_sys_var_to_list(&sys_error_count, my_long_options);
01333     add_sys_var_to_list(&sys_foreign_key_checks, my_long_options);
01334     add_sys_var_to_list(&sys_group_concat_max_len, my_long_options);
01335     add_sys_var_to_list(&sys_hostname, my_long_options);
01336     add_sys_var_to_list(&sys_identity, my_long_options);
01337     add_sys_var_to_list(&sys_join_buffer_size, my_long_options);
01338     add_sys_var_to_list(&sys_last_insert_id, my_long_options);
01339     add_sys_var_to_list(&sys_lc_time_names, my_long_options);
01340     add_sys_var_to_list(&sys_max_allowed_packet, my_long_options);
01341     add_sys_var_to_list(&sys_max_error_count, my_long_options);
01342     add_sys_var_to_list(&sys_max_heap_table_size, my_long_options);
01343     add_sys_var_to_list(&sys_max_join_size, my_long_options);
01344     add_sys_var_to_list(&sys_max_length_for_sort_data, my_long_options);
01345     add_sys_var_to_list(&sys_max_seeks_for_key, my_long_options);
01346     add_sys_var_to_list(&sys_max_sort_length, my_long_options);
01347     add_sys_var_to_list(&sys_max_write_lock_count, my_long_options);
01348     add_sys_var_to_list(&sys_min_examined_row_limit, my_long_options);
01349     add_sys_var_to_list(&sys_optimizer_prune_level, my_long_options);
01350     add_sys_var_to_list(&sys_optimizer_search_depth, my_long_options);
01351     add_sys_var_to_list(&sys_pid_file, my_long_options);
01352     add_sys_var_to_list(&sys_plugin_dir, my_long_options);
01353     add_sys_var_to_list(&sys_preload_buff_size, my_long_options);
01354     add_sys_var_to_list(&sys_pseudo_thread_id, my_long_options);
01355     add_sys_var_to_list(&sys_query_alloc_block_size, my_long_options);
01356     add_sys_var_to_list(&sys_query_prealloc_size, my_long_options);
01357     add_sys_var_to_list(&sys_range_alloc_block_size, my_long_options);
01358     add_sys_var_to_list(&sys_read_buff_size, my_long_options);
01359     add_sys_var_to_list(&sys_read_rnd_buff_size, my_long_options);
01360     add_sys_var_to_list(&sys_release_id, my_long_options);
01361     add_sys_var_to_list(&sys_replicate_query, my_long_options);
01362     add_sys_var_to_list(&sys_revid, my_long_options);
01363     add_sys_var_to_list(&sys_revno, my_long_options);
01364     add_sys_var_to_list(&sys_scheduler, my_long_options);
01365     add_sys_var_to_list(&sys_secure_file_priv, my_long_options);
01366     add_sys_var_to_list(&sys_select_limit, my_long_options);
01367     add_sys_var_to_list(&sys_server_id, my_long_options);
01368     add_sys_var_to_list(&sys_server_uuid, my_long_options);
01369     add_sys_var_to_list(&sys_sort_buffer, my_long_options);
01370     add_sys_var_to_list(&sys_sql_notes, my_long_options);
01371     add_sys_var_to_list(&sys_sql_warnings, my_long_options);
01372     add_sys_var_to_list(&sys_storage_engine, my_long_options);
01373     add_sys_var_to_list(&sys_table_cache_size, my_long_options);
01374     add_sys_var_to_list(&sys_table_def_size, my_long_options);
01375     add_sys_var_to_list(&sys_table_lock_wait_timeout, my_long_options);
01376     add_sys_var_to_list(&sys_thread_stack_size, my_long_options);
01377     add_sys_var_to_list(&sys_timed_mutexes, my_long_options);
01378     add_sys_var_to_list(&sys_timestamp, my_long_options);
01379     add_sys_var_to_list(&sys_tmp_table_size, my_long_options);
01380     add_sys_var_to_list(&sys_tmpdir, my_long_options);
01381     add_sys_var_to_list(&sys_transaction_message_threshold, my_long_options);
01382     add_sys_var_to_list(&sys_tx_isolation, my_long_options);
01383     add_sys_var_to_list(&sys_unique_checks, my_long_options);
01384     add_sys_var_to_list(&sys_version, my_long_options);
01385     add_sys_var_to_list(&sys_version_comment, my_long_options);
01386     add_sys_var_to_list(&sys_version_compile_machine, my_long_options);
01387     add_sys_var_to_list(&sys_version_compile_os, my_long_options);
01388     add_sys_var_to_list(&sys_version_compile_vendor, my_long_options);
01389     add_sys_var_to_list(&sys_warning_count, my_long_options);
01390   }
01391   catch (std::exception&)
01392   {
01393     errmsg_printf(error::ERROR, _("Failed to initialize system variables"));
01394     return 1;
01395   }
01396   return 0;
01397 }
01398 
01399 
01411 sys_var *find_sys_var(const std::string &name)
01412 {
01413   if (sys_var* ptr= find_ptr2(system_variable_map, boost::to_lower_copy(name)))
01414     return ptr;
01415   my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), name.c_str());
01416   return NULL;
01417 }
01418 
01419 
01420 /****************************************************************************
01421  Functions to handle table_type
01422 ****************************************************************************/
01423 
01424 unsigned char *sys_var_session_storage_engine::value_ptr(Session *session, sql_var_t type)
01425 {
01426   plugin::StorageEngine *engine= type == OPT_GLOBAL
01427     ? global_system_variables.*offset
01428     : session->variables.*offset;
01429   return (unsigned char *) session->mem.strdup(engine->getName());
01430 }
01431 
01432 
01433 void sys_var_session_storage_engine::set_default(Session *session, sql_var_t type)
01434 {
01435   plugin::StorageEngine *new_value, **value;
01436   if (type == OPT_GLOBAL)
01437   {
01438     value= &(global_system_variables.*offset);
01439     new_value= myisam_engine;
01440   }
01441   else
01442   {
01443     value= &(session->variables.*offset);
01444     new_value= global_system_variables.*offset;
01445   }
01446   assert(new_value);
01447   *value= new_value;
01448 }
01449 
01450 
01451 bool sys_var_session_storage_engine::update(Session *session, set_var *var)
01452 {
01453   char buff[STRING_BUFFER_USUAL_SIZE];
01454   const char *name_value;
01455   String str(buff, sizeof(buff), &my_charset_utf8_general_ci), *res;
01456 
01457   plugin::StorageEngine *tmp= NULL;
01458   plugin::StorageEngine **value= NULL;
01459     
01460   if (var->value->result_type() == STRING_RESULT)
01461   {
01462     res= var->value->val_str(&str);
01463     if (res == NULL || res->ptr() == NULL)
01464     {
01465       name_value= "NULL";
01466       goto err;
01467     }
01468     else
01469     {
01470       const std::string engine_name(res->ptr());
01471       tmp= plugin::StorageEngine::findByName(*session, engine_name);
01472       if (tmp == NULL)
01473       {
01474         name_value= res->c_ptr();
01475         goto err;
01476       }
01477     }
01478   }
01479   else
01480   {
01481     name_value= "unknown";
01482   }
01483 
01484   value= &(global_system_variables.*offset);
01485    if (var->type != OPT_GLOBAL)
01486      value= &(session->variables.*offset);
01487   if (*value != tmp)
01488   {
01489     *value= tmp;
01490   }
01491   return 0;
01492 err:
01493   my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name_value);
01494   return 1;
01495 }
01496 
01497 } /* namespace drizzled */