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