diff options
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r-- | sql/set_var.cc | 1400 |
1 files changed, 1292 insertions, 108 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc index 475beb798e6..93de5333f6b 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,11 +21,14 @@ - If the variable is thread specific, add it to 'system_variables' struct. If not, add it to mysqld.cc and an declaration in 'mysql_priv.h' + - Don't forget to initialize new fields in global_system_variables and + max_system_variables! - Use one of the 'sys_var... classes from set_var.h or write a specific one for the variable type. - Define it in the 'variable definition list' in this file. - - If the variable should be changeable, it should be added to the - 'list of all variables' list in this file. + - If the variable should be changeable or one should be able to access it + with @@variable_name, it should be added to the 'list of all variables' + list in this file. - If the variable should be changed from the command line, add a definition of it in the my_option structure list in mysqld.dcc - If the variable should show up in 'show variables' add it to the @@ -44,6 +47,7 @@ #endif #include "mysql_priv.h" +#include <mysql.h> #include "slave.h" #include "sql_acl.h" #include <my_getopt.h> @@ -72,6 +76,10 @@ TYPELIB delay_key_write_typelib= static bool sys_check_charset(THD *thd, set_var *var); static bool sys_update_charset(THD *thd, set_var *var); static void sys_set_default_charset(THD *thd, enum_var_type type); +static bool sys_update_init_connect(THD*, set_var*); +static void sys_default_init_connect(THD*, enum_var_type type); +static bool sys_update_init_slave(THD*, set_var*); +static void sys_default_init_slave(THD*, enum_var_type type); static bool set_option_bit(THD *thd, set_var *var); static bool set_option_autocommit(THD *thd, set_var *var); static bool set_log_update(THD *thd, set_var *var); @@ -82,7 +90,7 @@ static void fix_net_write_timeout(THD *thd, enum_var_type type); static void fix_net_retry_count(THD *thd, enum_var_type type); static void fix_max_join_size(THD *thd, enum_var_type type); static void fix_query_cache_size(THD *thd, enum_var_type type); -static void fix_key_buffer_size(THD *thd, enum_var_type type); +static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type); static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type); static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); static void fix_max_binlog_size(THD *thd, enum_var_type type); @@ -90,6 +98,10 @@ static void fix_max_relay_log_size(THD *thd, enum_var_type type); static void fix_max_connections(THD *thd, enum_var_type type); static void fix_thd_mem_root(THD *thd, enum_var_type type); static void fix_trans_mem_root(THD *thd, enum_var_type type); +static KEY_CACHE *create_key_cache(const char *name, uint length); +void fix_sql_mode_var(THD *thd, enum_var_type type); +static byte *get_error_count(THD *thd); +static byte *get_warning_count(THD *thd); /* Variable definition list @@ -102,11 +114,24 @@ sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size", &binlog_cache_size); sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size", &SV::bulk_insert_buff_size); -sys_var_str sys_charset("character_set", +sys_var_character_set_server sys_character_set_server("character_set_server"); +sys_var_str sys_charset_system("character_set_system", sys_check_charset, sys_update_charset, sys_set_default_charset); -sys_var_thd_conv_charset sys_convert_charset("convert_character_set"); +sys_var_str sys_init_connect("init_connect", 0, + sys_update_init_connect, + sys_default_init_connect); +sys_var_str sys_init_slave("init_slave", 0, + sys_update_init_slave, + sys_default_init_slave); +sys_var_character_set_database sys_character_set_database("character_set_database"); +sys_var_character_set_client sys_character_set_client("character_set_client"); +sys_var_character_set_connection sys_character_set_connection("character_set_connection"); +sys_var_character_set_results sys_character_set_results("character_set_results"); +sys_var_collation_connection sys_collation_connection("collation_connection"); +sys_var_collation_database sys_collation_database("collation_database"); +sys_var_collation_server sys_collation_server("collation_server"); sys_var_bool_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", @@ -121,15 +146,24 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout", &delayed_insert_timeout); sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size", &delayed_queue_size); +sys_var_long_ptr sys_expire_logs_days("expire_logs_days", + &expire_logs_days); sys_var_bool_ptr sys_flush("flush", &myisam_flush); sys_var_long_ptr sys_flush_time("flush_time", &flush_time); sys_var_thd_ulong sys_interactive_timeout("interactive_timeout", &SV::net_interactive_timeout); sys_var_thd_ulong sys_join_buffer_size("join_buffer_size", &SV::join_buff_size); -sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size", - &keybuff_size, - fix_key_buffer_size); +sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size"); +sys_var_key_cache_long sys_key_cache_block_size("key_cache_block_size", + offsetof(KEY_CACHE, + param_block_size)); +sys_var_key_cache_long sys_key_cache_division_limit("key_cache_division_limit", + offsetof(KEY_CACHE, + param_division_limit)); +sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold", + offsetof(KEY_CACHE, + param_age_threshold)); sys_var_bool_ptr sys_local_infile("local_infile", &opt_local_infile); sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings); @@ -158,13 +192,23 @@ sys_var_long_ptr sys_max_connect_errors("max_connect_errors", sys_var_long_ptr sys_max_delayed_threads("max_delayed_threads", &max_insert_delayed_threads, fix_max_connections); +sys_var_thd_ulong sys_max_error_count("max_error_count", + &SV::max_error_count); sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", &SV::max_heap_table_size); +/* + sys_pseudo_thread_id has its own class (instead of sys_var_thd_ulong) because + we want a check() function. +*/ +sys_var_pseudo_thread_id sys_pseudo_thread_id("pseudo_thread_id", + &SV::pseudo_thread_id); sys_var_thd_ha_rows sys_max_join_size("max_join_size", &SV::max_join_size, fix_max_join_size); sys_var_thd_ulong sys_max_seeks_for_key("max_seeks_for_key", &SV::max_seeks_for_key); +sys_var_thd_ulong sys_max_length_for_sort_data("max_length_for_sort_data", + &SV::max_length_for_sort_data); #ifndef TO_BE_DELETED /* Alias for max_join_size */ sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, @@ -197,11 +241,18 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count", &SV::net_retry_count, fix_net_retry_count); sys_var_thd_bool sys_new_mode("new", &SV::new_mode); +sys_var_thd_bool sys_old_passwords("old_passwords", &SV::old_passwords); +sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size", + &SV::preload_buff_size); sys_var_thd_ulong sys_read_buff_size("read_buffer_size", &SV::read_buff_size); sys_var_bool_ptr sys_readonly("read_only", &opt_readonly); sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size", &SV::read_rnd_buff_size); +#ifdef HAVE_REPLICATION +sys_var_bool_ptr sys_relay_log_purge("relay_log_purge", + &relay_log_purge); +#endif sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank", &rpl_recovery_rank); sys_var_long_ptr sys_query_cache_size("query_cache_size", @@ -226,21 +277,31 @@ sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size", #ifdef HAVE_QUERY_CACHE sys_var_long_ptr sys_query_cache_limit("query_cache_limit", &query_cache.query_cache_limit); +sys_var_long_ptr sys_query_cache_min_res_unit("query_cache_min_res_unit", + &query_cache_min_res_unit, + fix_query_cache_min_res_unit); sys_var_thd_enum sys_query_cache_type("query_cache_type", &SV::query_cache_type, &query_cache_type_typelib); #endif /* HAVE_QUERY_CACHE */ +sys_var_bool_ptr sys_secure_auth("secure_auth", &opt_secure_auth); sys_var_long_ptr sys_server_id("server_id",&server_id); sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", &opt_slave_compressed_protocol); +#ifdef HAVE_REPLICATION sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout", &slave_net_timeout); +#endif sys_var_long_ptr sys_slow_launch_time("slow_launch_time", &slow_launch_time); sys_var_thd_ulong sys_sort_buffer("sort_buffer_size", &SV::sortbuff_size); -sys_var_thd_enum sys_table_type("table_type", &SV::table_type, - &ha_table_typelib); +sys_var_thd_sql_mode sys_sql_mode("sql_mode", + &SV::sql_mode); +sys_var_thd_table_type sys_table_type("table_type", + &SV::table_type); +sys_var_thd_storage_engine sys_storage_engine("storage_engine", + &SV::table_type); sys_var_long_ptr sys_table_cache_size("table_cache", &table_cache_size); sys_var_long_ptr sys_thread_cache_size("thread_cache_size", @@ -253,16 +314,25 @@ sys_var_thd_ulong sys_tmp_table_size("tmp_table_size", &SV::tmp_table_size); sys_var_thd_ulong sys_net_wait_timeout("wait_timeout", &SV::net_wait_timeout); - + #ifdef HAVE_INNOBASE_DB sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_pct", &srv_max_buf_pool_modified_pct); #endif +/* Time/date/datetime formats */ -/* - Variables that are bits in THD -*/ +sys_var_thd_date_time_format sys_time_format("time_format", + &SV::time_format, + TIMESTAMP_TIME); +sys_var_thd_date_time_format sys_date_format("date_format", + &SV::date_format, + TIMESTAMP_DATE); +sys_var_thd_date_time_format sys_datetime_format("datetime_format", + &SV::datetime_format, + TIMESTAMP_DATETIME); + +/* Variables that are bits in THD */ static sys_var_thd_bit sys_autocommit("autocommit", set_option_autocommit, @@ -312,7 +382,6 @@ static sys_var_thd_bit sys_unique_checks("unique_checks", OPTION_RELAXED_UNIQUE_CHECKS, 1); - /* Local state variables */ static sys_var_thd_ha_rows sys_select_limit("sql_select_limit", @@ -321,13 +390,27 @@ static sys_var_timestamp sys_timestamp("timestamp"); static sys_var_last_insert_id sys_last_insert_id("last_insert_id"); static sys_var_last_insert_id sys_identity("identity"); static sys_var_insert_id sys_insert_id("insert_id"); +static sys_var_readonly sys_error_count("error_count", + OPT_SESSION, + SHOW_LONG, + get_error_count); +static sys_var_readonly sys_warning_count("warning_count", + OPT_SESSION, + SHOW_LONG, + get_warning_count); + /* alias for last_insert_id() to be compatible with Sybase */ +#ifdef HAVE_REPLICATION static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter"); +#endif static sys_var_rand_seed1 sys_rand_seed1("rand_seed1"); static sys_var_rand_seed2 sys_rand_seed2("rand_seed2"); static sys_var_thd_ulong sys_default_week_format("default_week_format", - &SV::default_week_format); + &SV::default_week_format); + +sys_var_thd_ulong sys_group_concat_max_len("group_concat_max_len", + &SV::group_concat_max_len); /* List of all variables for initialisation and storage in hash @@ -346,22 +429,39 @@ sys_var *sys_variables[]= &sys_binlog_cache_size, &sys_buffer_results, &sys_bulk_insert_buff_size, + &sys_character_set_server, + &sys_character_set_database, + &sys_character_set_client, + &sys_character_set_connection, + &sys_character_set_results, + &sys_collation_connection, + &sys_collation_database, + &sys_collation_server, &sys_concurrent_insert, &sys_connect_timeout, + &sys_date_format, + &sys_datetime_format, &sys_default_week_format, - &sys_convert_charset, &sys_delay_key_write, &sys_delayed_insert_limit, &sys_delayed_insert_timeout, &sys_delayed_queue_size, + &sys_error_count, + &sys_expire_logs_days, &sys_flush, &sys_flush_time, &sys_foreign_key_checks, + &sys_group_concat_max_len, &sys_identity, + &sys_init_connect, + &sys_init_slave, &sys_insert_id, &sys_interactive_timeout, &sys_join_buffer_size, &sys_key_buffer_size, + &sys_key_cache_block_size, + &sys_key_cache_division_limit, + &sys_key_cache_age_threshold, &sys_last_insert_id, &sys_local_infile, &sys_log_binlog, @@ -376,8 +476,10 @@ sys_var *sys_variables[]= &sys_max_connect_errors, &sys_max_connections, &sys_max_delayed_threads, + &sys_max_error_count, &sys_max_heap_table_size, &sys_max_join_size, + &sys_max_length_for_sort_data, &sys_max_relay_log_size, &sys_max_seeks_for_key, &sys_max_sort_length, @@ -394,36 +496,49 @@ sys_var *sys_variables[]= &sys_net_wait_timeout, &sys_net_write_timeout, &sys_new_mode, + &sys_old_passwords, + &sys_preload_buff_size, + &sys_pseudo_thread_id, &sys_query_alloc_block_size, &sys_query_cache_size, &sys_query_prealloc_size, #ifdef HAVE_QUERY_CACHE &sys_query_cache_limit, + &sys_query_cache_min_res_unit, &sys_query_cache_type, #endif /* HAVE_QUERY_CACHE */ &sys_quote_show_create, &sys_rand_seed1, &sys_rand_seed2, &sys_range_alloc_block_size, + &sys_readonly, &sys_read_buff_size, &sys_read_rnd_buff_size, +#ifdef HAVE_REPLICATION + &sys_relay_log_purge, +#endif &sys_rpl_recovery_rank, &sys_safe_updates, + &sys_secure_auth, &sys_select_limit, &sys_server_id, +#ifdef HAVE_REPLICATION &sys_slave_compressed_protocol, &sys_slave_net_timeout, &sys_slave_skip_counter, - &sys_readonly, +#endif &sys_slow_launch_time, &sys_sort_buffer, &sys_sql_big_tables, &sys_sql_low_priority_updates, &sys_sql_max_join_size, + &sys_sql_mode, &sys_sql_warnings, + &sys_storage_engine, &sys_table_cache_size, &sys_table_type, &sys_thread_cache_size, + &sys_time_format, &sys_timestamp, &sys_tmp_table_size, &sys_trans_alloc_block_size, @@ -432,7 +547,8 @@ sys_var *sys_variables[]= #ifdef HAVE_INNOBASE_DB &sys_innodb_max_dirty_pages_pct, #endif - &sys_unique_checks + &sys_unique_checks, + &sys_warning_count }; @@ -451,47 +567,62 @@ struct show_var_st init_vars[]= { {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR}, {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL}, {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR}, - {"bdb_version", (char*) DB_VERSION_STRING, SHOW_CHAR}, #endif {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS}, {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS}, - {sys_charset.name, (char*) &sys_charset, SHOW_SYS}, - {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR}, + {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS}, + {sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS}, + {sys_character_set_database.name, (char*) &sys_character_set_database,SHOW_SYS}, + {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS}, + {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS}, + {"character-sets-dir", mysql_charsets_dir, SHOW_CHAR}, + {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS}, + {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS}, + {sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS}, + {sys_collation_server.name,(char*) &sys_collation_server, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, - {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS}, {"datadir", mysql_real_data_home, SHOW_CHAR}, - {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, + {sys_date_format.name, (char*) &sys_date_format, SHOW_SYS}, + {sys_datetime_format.name, (char*) &sys_datetime_format, SHOW_SYS}, + {sys_default_week_format.name, (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS}, {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS}, + {sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS}, {sys_flush.name, (char*) &sys_flush, SHOW_SYS}, {sys_flush_time.name, (char*) &sys_flush_time, SHOW_SYS}, {"ft_boolean_syntax", (char*) ft_boolean_syntax, SHOW_CHAR}, {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG}, {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG}, - {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, SHOW_LONG}, + {"ft_query_expansion_limit",(char*) &ft_query_expansion_limit, SHOW_LONG}, {"ft_stopword_file", (char*) &ft_stopword_file, SHOW_CHAR_PTR}, {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE}, {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_compress", (char*) &have_compress, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, - {"have_isam", (char*) &have_isam, SHOW_HAVE}, + {"have_isam", (char*) &have_isam, SHOW_HAVE}, {"have_raid", (char*) &have_raid, SHOW_HAVE}, - {"have_symlink", (char*) &have_symlink, SHOW_HAVE}, + {"have_symlink", (char*) &have_symlink, SHOW_HAVE}, {"have_openssl", (char*) &have_openssl, SHOW_HAVE}, {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE}, {"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR}, + {"init_connect", (char*) &sys_init_connect, SHOW_SYS}, + {"init_slave", (char*) &sys_init_slave, SHOW_SYS}, #ifdef HAVE_INNOBASE_DB {"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG }, {"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG }, + {"innodb_buffer_pool_awe_mem_mb", (char*) &innobase_buffer_pool_awe_mem_mb, SHOW_LONG }, {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR}, {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR}, {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG }, + {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG }, {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, {"innodb_thread_concurrency", (char*) &innobase_thread_concurrency, SHOW_LONG }, {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_INT}, {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL}, + {"innodb_file_per_table", (char*) &innobase_file_per_table, SHOW_MY_BOOL}, {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR}, {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG }, {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR}, @@ -506,6 +637,12 @@ struct show_var_st init_vars[]= { {sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS}, {sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS}, {sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS}, + {sys_key_cache_block_size.name, (char*) &sys_key_cache_block_size, + SHOW_SYS}, + {sys_key_cache_division_limit.name, (char*) &sys_key_cache_division_limit, + SHOW_SYS}, + {sys_key_cache_age_threshold.name, (char*) &sys_key_cache_age_threshold, + SHOW_SYS}, {"language", language, SHOW_CHAR}, {"large_files_support", (char*) &opt_large_files, SHOW_BOOL}, {sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS}, @@ -515,7 +652,9 @@ struct show_var_st init_vars[]= { {"log", (char*) &opt_log, SHOW_BOOL}, {"log_update", (char*) &opt_update_log, SHOW_BOOL}, {"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, +#ifdef HAVE_REPLICATION {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL}, +#endif {"log_slow_queries", (char*) &opt_slow_log, SHOW_BOOL}, {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS}, {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS}, @@ -526,11 +665,14 @@ struct show_var_st init_vars[]= { {sys_max_binlog_size.name, (char*) &sys_max_binlog_size, SHOW_SYS}, {sys_max_connections.name, (char*) &sys_max_connections, SHOW_SYS}, {sys_max_connect_errors.name, (char*) &sys_max_connect_errors, SHOW_SYS}, + {sys_max_error_count.name, (char*) &sys_max_error_count, SHOW_SYS}, {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size, SHOW_SYS}, {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS}, + {sys_max_length_for_sort_data.name, (char*) &sys_max_length_for_sort_data, + SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS}, @@ -552,17 +694,23 @@ struct show_var_st init_vars[]= { {sys_net_retry_count.name, (char*) &sys_net_retry_count, SHOW_SYS}, {sys_net_write_timeout.name,(char*) &sys_net_write_timeout, SHOW_SYS}, {sys_new_mode.name, (char*) &sys_new_mode, SHOW_SYS}, + {sys_old_passwords.name, (char*) &sys_old_passwords, SHOW_SYS}, {"open_files_limit", (char*) &open_files_limit, SHOW_LONG}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"log_error", (char*) log_error_file, SHOW_CHAR}, - {"port", (char*) &mysql_port, SHOW_INT}, + {"port", (char*) &mysqld_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, + {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, + {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size, SHOW_SYS}, #ifdef HAVE_QUERY_CACHE {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS}, + {sys_query_cache_min_res_unit.name, (char*) &sys_query_cache_min_res_unit, + SHOW_SYS}, {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, + {"secure_auth", (char*) &sys_secure_auth, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS}, {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size, @@ -570,18 +718,29 @@ struct show_var_st init_vars[]= { {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, +#ifdef HAVE_REPLICATION + {sys_relay_log_purge.name, (char*) &sys_relay_log_purge, SHOW_SYS}, +#endif {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, +#ifdef HAVE_SMEM + {"shared_memory", (char*) &opt_enable_shared_memory, SHOW_MY_BOOL}, + {"shared_memory_base_name", (char*) &shared_memory_base_name, SHOW_CHAR_PTR}, +#endif {sys_server_id.name, (char*) &sys_server_id, SHOW_SYS}, +#ifdef HAVE_REPLICATION {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, +#endif + {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {"skip_external_locking", (char*) &my_disable_locking, SHOW_MY_BOOL}, {"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL}, {"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL}, {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS}, #ifdef HAVE_SYS_UN_H - {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, + {"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR}, #endif {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, - {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG}, + {sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS}, + {sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS}, {"table_cache", (char*) &table_cache_size, SHOW_LONG}, {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS}, {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS}, @@ -590,24 +749,96 @@ struct show_var_st init_vars[]= { #endif {"thread_stack", (char*) &thread_stack, SHOW_LONG}, {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS}, + {sys_time_format.name, (char*) &sys_time_format, SHOW_SYS}, #ifdef HAVE_TZNAME {"timezone", time_zone, SHOW_CHAR}, #endif {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, - {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR}, + {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR}, {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size, SHOW_SYS}, {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS}, {"version", server_version, SHOW_CHAR}, +#ifdef HAVE_BERKELEY_DB + {"version_bdb", (char*) DB_VERSION_STRING, SHOW_CHAR}, +#endif {"version_comment", (char*) MYSQL_COMPILATION_COMMENT, SHOW_CHAR}, + {"version_compile_machine", (char*) MACHINE_TYPE, SHOW_CHAR}, + {"version_compile_os", (char*) SYSTEM_TYPE, SHOW_CHAR}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {NullS, NullS, SHOW_LONG} }; + +bool sys_var::check(THD *thd, set_var *var) +{ + var->save_result.ulonglong_value= var->value->val_int(); + return 0; +} + /* Functions to check and update variables */ + +/* + Update variables 'init_connect, init_slave'. + + In case of 'DEFAULT' value + (for example: 'set GLOBAL init_connect=DEFAULT') + 'var' parameter is NULL pointer. +*/ + +bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex, + set_var *var) +{ + char *res= 0, *old_value; + uint new_length= 0; + /* If the string is "", delete old init command */ + if (var && (new_length= var->value->str_value.length())) + { + if (!(res= my_strdup_with_length((byte*) var->value->str_value.ptr(), + new_length, MYF(0)))) + return 1; + } + /* + Replace the old value in such a way that the any thread using + the value will work. + */ + rw_wrlock(var_mutex); + old_value= var_str->value; + var_str->value= res; + var_str->value_length= new_length; + rw_unlock(var_mutex); + my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); + return 0; +} + + +static bool sys_update_init_connect(THD *thd, set_var *var) +{ + return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var); +} + + +static void sys_default_init_connect(THD* thd, enum_var_type type) +{ + update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0); +} + + +static bool sys_update_init_slave(THD *thd, set_var *var) +{ + return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var); +} + + +static void sys_default_init_slave(THD* thd, enum_var_type type) +{ + update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0); +} + + /* The following 3 functions need to be changed in 4.1 when we allow one to change character sets @@ -691,6 +922,7 @@ static void fix_tx_isolation(THD *thd, enum_var_type type) If we are changing the thread variable, we have to copy it to NET too */ +#ifdef HAVE_REPLICATION static void fix_net_read_timeout(THD *thd, enum_var_type type) { if (type != OPT_GLOBAL) @@ -709,20 +941,39 @@ static void fix_net_retry_count(THD *thd, enum_var_type type) if (type != OPT_GLOBAL) thd->net.retry_count=thd->variables.net_retry_count; } +#else /* HAVE_REPLICATION */ +static void fix_net_read_timeout(THD *thd __attribute__(unused), + enum_var_type type __attribute__(unused)) +{} +static void fix_net_write_timeout(THD *thd __attribute__(unused), + enum_var_type type __attribute__(unused)) +{} +static void fix_net_retry_count(THD *thd __attribute__(unused), + enum_var_type type __attribute__(unused)) +{} +#endif /* HAVE_REPLICATION */ static void fix_query_cache_size(THD *thd, enum_var_type type) { #ifdef HAVE_QUERY_CACHE + ulong requested= query_cache_size; query_cache.resize(query_cache_size); + if (requested != query_cache_size) + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE), + requested, query_cache_size); #endif } -static void fix_key_buffer_size(THD *thd, enum_var_type type) +#ifdef HAVE_QUERY_CACHE +static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type) { - ha_resize_key_cache(); + query_cache_min_res_unit= + query_cache.set_min_res_unit(query_cache_min_res_unit); } +#endif extern void fix_delay_key_write(THD *thd, enum_var_type type) @@ -747,8 +998,10 @@ static void fix_max_binlog_size(THD *thd, enum_var_type type) DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", max_binlog_size, max_relay_log_size)); mysql_bin_log.set_max_size(max_binlog_size); +#ifdef HAVE_REPLICATION if (!max_relay_log_size) active_mi->rli.relay_log.set_max_size(max_binlog_size); +#endif DBUG_VOID_RETURN; } @@ -757,8 +1010,10 @@ static void fix_max_relay_log_size(THD *thd, enum_var_type type) DBUG_ENTER("fix_max_relay_log_size"); DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", max_binlog_size, max_relay_log_size)); +#ifdef HAVE_REPLICATION active_mi->rli.relay_log.set_max_size(max_relay_log_size ? max_relay_log_size: max_binlog_size); +#endif DBUG_VOID_RETURN; } @@ -786,10 +1041,9 @@ static void fix_trans_mem_root(THD *thd, enum_var_type type) thd->variables.trans_prealloc_size); } - bool sys_var_long_ptr::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); + ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(&LOCK_global_system_variables); if (option_limits) *value= (ulong) getopt_ull_limit_value(tmp, option_limits); @@ -808,7 +1062,7 @@ void sys_var_long_ptr::set_default(THD *thd, enum_var_type type) bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); + ulonglong tmp= var->save_result.ulonglong_value; pthread_mutex_lock(&LOCK_global_system_variables); if (option_limits) *value= (ulonglong) getopt_ull_limit_value(tmp, option_limits); @@ -847,7 +1101,7 @@ bool sys_var_enum::update(THD *thd, set_var *var) } -byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) { return (byte*) enum_names->type_names[*value]; } @@ -855,7 +1109,7 @@ byte *sys_var_enum::value_ptr(THD *thd, enum_var_type type) bool sys_var_thd_ulong::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); + ulonglong tmp= var->save_result.ulonglong_value; /* Don't use bigger value than given with --maximum-variable-name=.. */ if ((ulong) tmp > max_system_variables.*offset) @@ -883,7 +1137,8 @@ void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -893,7 +1148,7 @@ byte *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type) bool sys_var_thd_ha_rows::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); + ulonglong tmp= var->save_result.ulonglong_value; /* Don't use bigger value than given with --maximum-variable-name=.. */ if ((ha_rows) tmp > max_system_variables.*offset) @@ -928,17 +1183,17 @@ void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); return (byte*) &(thd->variables.*offset); } - bool sys_var_thd_ulonglong::update(THD *thd, set_var *var) { - ulonglong tmp= var->value->val_int(); + ulonglong tmp= var->save_result.ulonglong_value; if ((ulonglong) tmp > max_system_variables.*offset) tmp= max_system_variables.*offset; @@ -963,7 +1218,7 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) { pthread_mutex_lock(&LOCK_global_system_variables); - global_system_variables.*offset= (ulong) option_limits->def_value; + global_system_variables.*offset= (ulonglong) option_limits->def_value; pthread_mutex_unlock(&LOCK_global_system_variables); } else @@ -971,7 +1226,8 @@ void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -998,7 +1254,8 @@ void sys_var_thd_bool::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { if (type == OPT_GLOBAL) return (byte*) &(global_system_variables.*offset); @@ -1010,14 +1267,14 @@ bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) { char buff[80]; const char *value; - String str(buff,sizeof(buff)), *res; + String str(buff, sizeof(buff), system_charset_info), *res; if (var->value->result_type() == STRING_RESULT) { if (!(res=var->value->val_str(&str)) || ((long) (var->save_result.ulong_value= - (ulong) find_type(res->c_ptr(), enum_names, 3)-1)) - < 0) + (ulong) find_type(enum_names, res->ptr(), + res->length(),1)-1)) < 0) { value= res ? res->c_ptr() : "NULL"; goto err; @@ -1041,6 +1298,46 @@ err: return 1; } + +bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) +{ + bool not_used; + char buff[80], *error= 0; + uint error_len= 0; + String str(buff, sizeof(buff), system_charset_info), *res; + + if (var->value->result_type() == STRING_RESULT) + { + if (!(res= var->value->val_str(&str))) + goto err; + var->save_result.ulong_value= ((ulong) + find_set(enum_names, res->c_ptr(), + res->length(), &error, &error_len, + ¬_used)); + if (error_len) + { + strmake(buff, error, min(sizeof(buff), error_len)); + goto err; + } + } + else + { + ulonglong tmp= var->value->val_int(); + if (tmp >= enum_names->count) + { + llstr(tmp, buff); + goto err; + } + var->save_result.ulong_value= (ulong) tmp; // Save for update + } + return 0; + +err: + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff); + return 1; +} + + /* Return an Item for a variable. Used with @@[global.]variable_name @@ -1048,15 +1345,19 @@ err: We have to use netprintf() instead of my_error() here as this is called on the parsing stage. + + TODO: + With prepared statements/stored procedures this has to be fixed + to create an item that gets the current value at fix_fields() stage. */ -Item *sys_var::item(THD *thd, enum_var_type var_type) +Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (check_type(var_type)) { if (var_type != OPT_DEFAULT) { - net_printf(&thd->net,ER_INCORRECT_GLOBAL_LOCAL_VAR, + net_printf(thd, ER_INCORRECT_GLOBAL_LOCAL_VAR, name, var_type == OPT_GLOBAL ? "LOCAL" : "GLOBAL"); return 0; } @@ -1065,12 +1366,18 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) } switch (type()) { case SHOW_LONG: - return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type)); + { + ulong value; + pthread_mutex_lock(&LOCK_global_system_variables); + value= *(ulong*) value_ptr(thd, var_type, base); + pthread_mutex_unlock(&LOCK_global_system_variables); + return new Item_uint((int32) value); + } case SHOW_LONGLONG: { longlong value; pthread_mutex_lock(&LOCK_global_system_variables); - value= *(longlong*) value_ptr(thd, var_type); + value= *(longlong*) value_ptr(thd, var_type, base); pthread_mutex_unlock(&LOCK_global_system_variables); return new Item_int(value); } @@ -1078,19 +1385,23 @@ Item *sys_var::item(THD *thd, enum_var_type var_type) { ha_rows value; pthread_mutex_lock(&LOCK_global_system_variables); - value= *(ha_rows*) value_ptr(thd, var_type); + value= *(ha_rows*) value_ptr(thd, var_type, base); pthread_mutex_unlock(&LOCK_global_system_variables); return new Item_int((longlong) value); } case SHOW_MY_BOOL: - return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type),1); + return new Item_int((int32) *(my_bool*) value_ptr(thd, var_type, base),1); case SHOW_CHAR: { - char *str= (char*) value_ptr(thd, var_type); - return new Item_string(str,strlen(str)); + Item_string *tmp; + pthread_mutex_lock(&LOCK_global_system_variables); + char *str= (char*) value_ptr(thd, var_type, base); + tmp= new Item_string(str, strlen(str), system_charset_info); + pthread_mutex_unlock(&LOCK_global_system_variables); + return tmp; } default: - net_printf(&thd->net, ER_VAR_CANT_BE_READ, name); + net_printf(thd, ER_VAR_CANT_BE_READ, name); } return 0; } @@ -1115,7 +1426,8 @@ void sys_var_thd_enum::set_default(THD *thd, enum_var_type type) } -byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { ulong tmp= ((type == OPT_GLOBAL) ? global_system_variables.*offset : @@ -1127,12 +1439,12 @@ byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type) bool sys_var_thd_bit::update(THD *thd, set_var *var) { int res= (*update_func)(thd, var); - thd->lex.select_lex.options=thd->options; return res; } -byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { /* If reverse is 0 (default) return 1 if bit is set. @@ -1144,61 +1456,607 @@ byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type) } -bool sys_var_thd_conv_charset::check(THD *thd, set_var *var) +/* Update a date_time format variable based on given value */ + +void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type, + DATE_TIME_FORMAT *new_value) +{ + DATE_TIME_FORMAT *old; + DBUG_ENTER("sys_var_date_time_format::update2"); + DBUG_DUMP("positions",(char*) new_value->positions, + sizeof(new_value->positions)); + + if (type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_global_system_variables); + old= (global_system_variables.*offset); + (global_system_variables.*offset)= new_value; + pthread_mutex_unlock(&LOCK_global_system_variables); + } + else + { + old= (thd->variables.*offset); + (thd->variables.*offset)= new_value; + } + my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR)); + DBUG_VOID_RETURN; +} + + +bool sys_var_thd_date_time_format::update(THD *thd, set_var *var) +{ + DATE_TIME_FORMAT *new_value; + /* We must make a copy of the last value to get it into normal memory */ + new_value= date_time_format_copy((THD*) 0, + var->save_result.date_time_format); + if (!new_value) + return 1; // Out of memory + update2(thd, var->type, new_value); // Can't fail + return 0; +} + + +bool sys_var_thd_date_time_format::check(THD *thd, set_var *var) { - CONVERT *tmp; char buff[80]; - String str(buff,sizeof(buff)), *res; + String str(buff,sizeof(buff), system_charset_info), *res; + DATE_TIME_FORMAT *format; + + if (!(res=var->value->val_str(&str))) + res= &my_empty_string; - if (!var->value) // Default value + if (!(format= date_time_format_make(date_time_type, + res->ptr(), res->length()))) { - var->save_result.convert= (var->type != OPT_GLOBAL ? - global_system_variables.convert_set - : (CONVERT*) 0); - return 0; + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr()); + return 1; } + + /* + We must copy result to thread space to not get a memory leak if + update is aborted + */ + var->save_result.date_time_format= date_time_format_copy(thd, format); + my_free((char*) format, MYF(0)); + return var->save_result.date_time_format == 0; +} + + +void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type) +{ + DATE_TIME_FORMAT *res= 0; + + if (type == OPT_GLOBAL) + { + const char *format; + if ((format= opt_date_time_formats[date_time_type])) + res= date_time_format_make(date_time_type, format, strlen(format)); + } + else + { + /* Make copy with malloc */ + res= date_time_format_copy((THD *) 0, global_system_variables.*offset); + } + + if (res) // Should always be true + update2(thd, type, res); +} + + +byte *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + if (type == OPT_GLOBAL) + { + char *res; + /* + We do a copy here just to be sure things will work even if someone + is modifying the original string while the copy is accessed + (Can't happen now in SQL SHOW, but this is a good safety for the future) + */ + res= thd->strmake((global_system_variables.*offset)->format.str, + (global_system_variables.*offset)->format.length); + return (byte*) res; + } + return (byte*) (thd->variables.*offset)->format.str; +} + + +typedef struct old_names_map_st +{ + const char *old_name; + const char *new_name; +} my_old_conv; + +static my_old_conv old_conv[]= +{ + { "cp1251_koi8" , "cp1251" }, + { "cp1250_latin2" , "cp1250" }, + { "kam_latin2" , "keybcs2" }, + { "mac_latin2" , "MacRoman" }, + { "macce_latin2" , "MacCE" }, + { "pc2_latin2" , "pclatin2" }, + { "vga_latin2" , "pclatin1" }, + { "koi8_cp1251" , "koi8r" }, + { "win1251ukr_koi8_ukr" , "win1251ukr" }, + { "koi8_ukr_win1251ukr" , "koi8u" }, + { NULL , NULL } +}; + +CHARSET_INFO *get_old_charset_by_name(const char *name) +{ + my_old_conv *conv; + + for (conv= old_conv; conv->old_name; conv++) + { + if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name)) + return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0)); + } + return NULL; +} + + +bool sys_var_collation::check(THD *thd, set_var *var) +{ + CHARSET_INFO *tmp; + char buff[80]; + String str(buff,sizeof(buff), system_charset_info), *res; + if (!(res=var->value->val_str(&str))) - res= &empty_string; + res= &my_empty_string; - if (!(tmp=get_convert_set(res->c_ptr()))) + if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0)))) + { + my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr()); + return 1; + } + var->save_result.charset= tmp; // Save for update + return 0; +} + + +bool sys_var_character_set::check(THD *thd, set_var *var) +{ + CHARSET_INFO *tmp; + char buff[80]; + String str(buff,sizeof(buff), system_charset_info), *res; + + if (!(res=var->value->val_str(&str))) + { + if (!nullable) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "NULL"); + return 1; + } + tmp= NULL; + } + else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && + !(tmp=get_old_charset_by_name(res->c_ptr()))) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); return 1; } - var->save_result.convert=tmp; // Save for update + var->save_result.charset= tmp; // Save for update + return 0; +} + + +bool sys_var_character_set::update(THD *thd, set_var *var) +{ + ci_ptr(thd,var->type)[0]= var->save_result.charset; + thd->update_charset(); + return 0; +} + + +byte *sys_var_character_set::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + CHARSET_INFO *cs= ci_ptr(thd,type)[0]; + return cs ? (byte*) cs->csname : (byte*) "NULL"; +} + + +CHARSET_INFO ** sys_var_character_set_connection::ci_ptr(THD *thd, + enum_var_type type) +{ + if (type == OPT_GLOBAL) + return &global_system_variables.collation_connection; + else + return &thd->variables.collation_connection; +} + + +void sys_var_character_set_connection::set_default(THD *thd, + enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_connection= default_charset_info; + else + { + thd->variables.collation_connection= global_system_variables.collation_connection; + thd->update_charset(); + } +} + + +CHARSET_INFO ** sys_var_character_set_client::ci_ptr(THD *thd, + enum_var_type type) +{ + if (type == OPT_GLOBAL) + return &global_system_variables.character_set_client; + else + return &thd->variables.character_set_client; +} + + +void sys_var_character_set_client::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.character_set_client= default_charset_info; + else + { + thd->variables.character_set_client= (global_system_variables. + character_set_client); + thd->update_charset(); + } +} + + +CHARSET_INFO ** +sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + return &global_system_variables.character_set_results; + else + return &thd->variables.character_set_results; +} + + +void sys_var_character_set_results::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.character_set_results= default_charset_info; + else + { + thd->variables.character_set_results= (global_system_variables. + character_set_results); + thd->update_charset(); + } +} + + +CHARSET_INFO ** +sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + return &global_system_variables.collation_server; + else + return &thd->variables.collation_server; +} + + +void sys_var_character_set_server::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_server= default_charset_info; + else + { + thd->variables.collation_server= global_system_variables.collation_server; + thd->update_charset(); + } +} + + +CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd, + enum_var_type type) +{ + if (type == OPT_GLOBAL) + return &global_system_variables.collation_database; + else + return &thd->variables.collation_database; +} + + +void sys_var_character_set_database::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_database= default_charset_info; + else + { + thd->variables.collation_database= thd->db_charset; + thd->update_charset(); + } +} + + +bool sys_var_collation_connection::update(THD *thd, set_var *var) +{ + if (var->type == OPT_GLOBAL) + global_system_variables.collation_connection= var->save_result.charset; + else + { + thd->variables.collation_connection= var->save_result.charset; + thd->update_charset(); + } + return 0; +} + + +byte *sys_var_collation_connection::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? + global_system_variables.collation_connection : + thd->variables.collation_connection); + return cs ? (byte*) cs->name : (byte*) "NULL"; +} + + +void sys_var_collation_connection::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_connection= default_charset_info; + else + { + thd->variables.collation_connection= (global_system_variables. + collation_connection); + thd->update_charset(); + } +} + +bool sys_var_collation_database::update(THD *thd, set_var *var) +{ + if (var->type == OPT_GLOBAL) + global_system_variables.collation_database= var->save_result.charset; + else + { + thd->variables.collation_database= var->save_result.charset; + thd->update_charset(); + } return 0; } -bool sys_var_thd_conv_charset::update(THD *thd, set_var *var) +byte *sys_var_collation_database::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? + global_system_variables.collation_database : + thd->variables.collation_database); + return cs ? (byte*) cs->name : (byte*) "NULL"; +} + + +void sys_var_collation_database::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_database= default_charset_info; + else + { + thd->variables.collation_database= (global_system_variables. + collation_database); + thd->update_charset(); + } +} + + +bool sys_var_collation_server::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) - global_system_variables.convert_set= var->save_result.convert; + global_system_variables.collation_server= var->save_result.charset; else - thd->lex.convert_set= thd->variables.convert_set= - var->save_result.convert; + { + thd->variables.collation_server= var->save_result.charset; + thd->update_charset(); + } return 0; } -byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_collation_server::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? + global_system_variables.collation_server : + thd->variables.collation_server); + return cs ? (byte*) cs->name : (byte*) "NULL"; +} + + +void sys_var_collation_server::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.collation_server= default_charset_info; + else + { + thd->variables.collation_server= (global_system_variables. + collation_server); + thd->update_charset(); + } +} + + +LEX_STRING default_key_cache_base= {(char *) "default", 7 }; + +static KEY_CACHE zero_key_cache; + +KEY_CACHE *get_key_cache(LEX_STRING *cache_name) +{ + safe_mutex_assert_owner(&LOCK_global_system_variables); + if (!cache_name || ! cache_name->length) + cache_name= &default_key_cache_base; + return ((KEY_CACHE*) find_named(&key_caches, + cache_name->str, cache_name->length, 0)); +} + + +byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + KEY_CACHE *key_cache= get_key_cache(base); + if (!key_cache) + key_cache= &zero_key_cache; + return (byte*) key_cache + offset ; +} + + +bool sys_var_key_buffer_size::update(THD *thd, set_var *var) +{ + ulonglong tmp= var->save_result.ulonglong_value; + LEX_STRING *base_name= &var->base; + KEY_CACHE *key_cache; + bool error= 0; + + /* If no basename, assume it's for the key cache named 'default' */ + if (!base_name->length) + base_name= &default_key_cache_base; + + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache= get_key_cache(base_name); + + if (!key_cache) + { + /* Key cache didn't exists */ + if (!tmp) // Tried to delete cache + goto end; // Ok, nothing to do + if (!(key_cache= create_key_cache(base_name->str, base_name->length))) + { + error= 1; + goto end; + } + } + + /* + Abort if some other thread is changing the key cache + TODO: This should be changed so that we wait until the previous + assignment is done and then do the new assign + */ + if (key_cache->in_init) + goto end; + + if (!tmp) // Zero size means delete + { + if (key_cache == sql_key_cache) + goto end; // Ignore default key cache + + if (key_cache->key_cache_inited) // If initied + { + /* + Move tables using this key cache to the default key cache + and clear the old key cache. + */ + NAMED_LIST *list; + key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str, + base_name->length, &list); + key_cache->in_init= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); + error= reassign_keycache_tables(thd, key_cache, sql_key_cache); + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; + } + /* + We don't delete the key cache as some running threads my still be + in the key cache code with a pointer to the deleted (empty) key cache + */ + goto end; + } + + key_cache->param_buff_size= + (ulonglong) getopt_ull_limit_value(tmp, option_limits); + + /* If key cache didn't existed initialize it, else resize it */ + key_cache->in_init= 1; + pthread_mutex_unlock(&LOCK_global_system_variables); + + if (!key_cache->key_cache_inited) + error= (bool) (ha_init_key_cache("", key_cache)); + else + error= (bool)(ha_resize_key_cache(key_cache)); + + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; + +end: + pthread_mutex_unlock(&LOCK_global_system_variables); + return error; +} + + +bool sys_var_key_cache_long::update(THD *thd, set_var *var) { - CONVERT *conv= ((type == OPT_GLOBAL) ? - global_system_variables.convert_set : - thd->variables.convert_set); - return conv ? (byte*) conv->name : (byte*) ""; + ulong tmp= (ulong) var->value->val_int(); + LEX_STRING *base_name= &var->base; + bool error= 0; + + if (!base_name->length) + base_name= &default_key_cache_base; + + pthread_mutex_lock(&LOCK_global_system_variables); + KEY_CACHE *key_cache= get_key_cache(base_name); + + if (!key_cache && !(key_cache= create_key_cache(base_name->str, + base_name->length))) + { + error= 1; + goto end; + } + + /* + Abort if some other thread is changing the key cache + TODO: This should be changed so that we wait until the previous + assignment is done and then do the new assign + */ + if (key_cache->in_init) + goto end; + + *((ulong*) (((char*) key_cache) + offset))= + (ulong) getopt_ull_limit_value(tmp, option_limits); + + /* + Don't create a new key cache if it didn't exist + (key_caches are created only when the user sets block_size) + */ + key_cache->in_init= 1; + + pthread_mutex_unlock(&LOCK_global_system_variables); + + error= (bool) (ha_resize_key_cache(key_cache)); + + pthread_mutex_lock(&LOCK_global_system_variables); + key_cache->in_init= 0; + +end: + pthread_mutex_unlock(&LOCK_global_system_variables); + return error; } -void sys_var_thd_conv_charset::set_default(THD *thd, enum_var_type type) +/***************************************************************************** + Functions to handle SET NAMES and SET CHARACTER SET +*****************************************************************************/ + +int set_var_collation_client::check(THD *thd) +{ + return 0; +} + +int set_var_collation_client::update(THD *thd) { - thd->variables.convert_set= global_system_variables.convert_set; + thd->variables.character_set_client= character_set_client; + thd->variables.character_set_results= character_set_results; + thd->variables.collation_connection= collation_connection; + thd->update_charset(); + thd->protocol_simple.init(thd); + thd->protocol_prep.init(thd); + return 0; } +/****************************************************************************/ bool sys_var_timestamp::update(THD *thd, set_var *var) { - thd->set_time((time_t) var->value->val_int()); + thd->set_time((time_t) var->save_result.ulonglong_value); return 0; } @@ -1209,7 +2067,8 @@ void sys_var_timestamp::set_default(THD *thd, enum_var_type type) } -byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { thd->sys_var_tmp.long_value= (long) thd->start_time; return (byte*) &thd->sys_var_tmp.long_value; @@ -1218,12 +2077,13 @@ byte *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type) bool sys_var_last_insert_id::update(THD *thd, set_var *var) { - thd->insert_id(var->value->val_int()); + thd->insert_id(var->save_result.ulonglong_value); return 0; } -byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { thd->sys_var_tmp.long_value= (long) thd->insert_id(); return (byte*) &thd->last_insert_id; @@ -1232,17 +2092,35 @@ byte *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type) bool sys_var_insert_id::update(THD *thd, set_var *var) { - thd->next_insert_id=var->value->val_int(); + thd->next_insert_id= var->save_result.ulonglong_value; return 0; } -byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type) +byte *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) { return (byte*) &thd->current_insert_id; } +bool sys_var_pseudo_thread_id::check(THD *thd, set_var *var) +{ + var->save_result.ulonglong_value= var->value->val_int(); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (thd->master_access & SUPER_ACL) + return 0; + else + { + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); + return 1; + } +#else + return 0; +#endif +} + +#ifdef HAVE_REPLICATION bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) { int result= 0; @@ -1255,6 +2133,7 @@ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) } pthread_mutex_unlock(&active_mi->rli.run_lock); UNLOCK_ACTIVE_MI; + var->save_result.ulong_value= (ulong) var->value->val_int(); return result; } @@ -1271,24 +2150,24 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var) if (!active_mi->rli.slave_running) { pthread_mutex_lock(&active_mi->rli.data_lock); - active_mi->rli.slave_skip_counter= (ulong) var->value->val_int(); + active_mi->rli.slave_skip_counter= var->save_result.ulong_value; pthread_mutex_unlock(&active_mi->rli.data_lock); } pthread_mutex_unlock(&active_mi->rli.run_lock); UNLOCK_ACTIVE_MI; return 0; } - +#endif /* HAVE_REPLICATION */ bool sys_var_rand_seed1::update(THD *thd, set_var *var) { - thd->rand.seed1= (ulong) var->value->val_int(); + thd->rand.seed1= (ulong) var->save_result.ulonglong_value; return 0; } bool sys_var_rand_seed2::update(THD *thd, set_var *var) { - thd->rand.seed2= (ulong) var->value->val_int(); + thd->rand.seed2= (ulong) var->save_result.ulonglong_value; return 0; } @@ -1348,6 +2227,21 @@ static bool set_log_update(THD *thd, set_var *var) return 0; } +static byte *get_warning_count(THD *thd) +{ + thd->sys_var_tmp.long_value= + (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] + + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]); + return (byte*) &thd->sys_var_tmp.long_value; +} + +static byte *get_error_count(THD *thd) +{ + thd->sys_var_tmp.long_value= + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR]; + return (byte*) &thd->sys_var_tmp.long_value; +} + /**************************************************************************** Main handling of variables: @@ -1407,10 +2301,9 @@ static byte *get_sys_var_length(const sys_var *var, uint *length, void set_var_init() { - extern struct my_option my_long_options[]; // From mysqld - - hash_init(&system_variable_hash,array_elements(sys_variables),0,0, - (hash_get_key) get_sys_var_length,0, HASH_CASE_INSENSITIVE); + hash_init(&system_variable_hash, system_charset_info, + array_elements(sys_variables),0,0, + (hash_get_key) get_sys_var_length,0,0); sys_var **var, **end; for (var= sys_variables, end= sys_variables+array_elements(sys_variables) ; var < end; @@ -1418,9 +2311,8 @@ void set_var_init() { (*var)->name_length= strlen((*var)->name); (*var)->option_limits= find_option(my_long_options, (*var)->name); - hash_insert(&system_variable_hash, (byte*) *var); + my_hash_insert(&system_variable_hash, (byte*) *var); } - /* Special cases Needed because MySQL can't find the limits for a variable it it has @@ -1461,7 +2353,7 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - net_printf(¤t_thd->net, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); + net_printf(current_thd, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); return var; } @@ -1491,18 +2383,21 @@ sys_var *find_sys_var(const char *str, uint length) int sql_set_variables(THD *thd, List<set_var_base> *var_list) { int error= 0; - List_iterator<set_var_base> it(*var_list); + List_iterator_fast<set_var_base> it(*var_list); + DBUG_ENTER("sql_set_variables"); set_var_base *var; while ((var=it++)) { if ((error=var->check(thd))) - return error; + DBUG_RETURN(error); } + if (thd->net.report_error) + DBUG_RETURN(1); it.rewind(); while ((var=it++)) error|= var->update(thd); // Returns 0, -1 or 1 - return error; + DBUG_RETURN(error); } @@ -1521,7 +2416,6 @@ int set_var::check(THD *thd) } if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) return 1; - /* value is a NULL pointer if we are using SET ... = DEFAULT */ if (!value) { @@ -1533,7 +2427,7 @@ int set_var::check(THD *thd) return 0; } - if (value->fix_fields(thd,0)) + if (value->fix_fields(thd, 0, &value) || value->check_cols(1)) return -1; if (var->check_update_type(value->result_type())) { @@ -1562,7 +2456,12 @@ int set_var::update(THD *thd) int set_var_user::check(THD *thd) { - return user_var_item->fix_fields(thd,0) ? -1 : 0; + /* + Item_func_set_user_var can't substitute something else on its place => + 0 can be passed as last argument + */ + return (user_var_item->fix_fields(thd, 0, (Item**) 0) || + user_var_item->check()) ? -1 : 0; } @@ -1584,24 +2483,309 @@ int set_var_user::update(THD *thd) int set_var_password::check(THD *thd) { +#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!user->host.str) user->host.str= (char*) thd->host_or_ip; /* Returns 1 as the function sends error to client */ return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0; +#else + return 0; +#endif } int set_var_password::update(THD *thd) { +#ifndef NO_EMBEDDED_ACCESS_CHECKS /* Returns 1 as the function sends error to client */ return (change_password(thd, user->host.str, user->user.str, password) ? 1 : 0); +#else + return 0; +#endif } /**************************************************************************** + Functions to handle table_type +****************************************************************************/ + +/* Based upon sys_var::check_enum() */ + +bool sys_var_thd_storage_engine::check(THD *thd, set_var *var) +{ + char buff[80]; + const char *value; + String str(buff, sizeof(buff), &my_charset_latin1), *res; + + if (var->value->result_type() == STRING_RESULT) + { + if (!(res=var->value->val_str(&str)) || + !(var->save_result.ulong_value= + (ulong) ha_resolve_by_name(res->ptr(), res->length()))) + { + value= res ? res->c_ptr() : "NULL"; + goto err; + } + return 0; + } + value= "unknown"; + +err: + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value); + return 1; +} + + +byte *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + ulong val; + val= ((type == OPT_GLOBAL) ? global_system_variables.*offset : + thd->variables.*offset); + const char *table_type= ha_get_storage_engine((enum db_type)val); + return (byte *) table_type; +} + + +void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.*offset= (ulong) DB_TYPE_MYISAM; + else + thd->variables.*offset= (ulong) (global_system_variables.*offset); +} + + +bool sys_var_thd_storage_engine::update(THD *thd, set_var *var) +{ + if (var->type == OPT_GLOBAL) + global_system_variables.*offset= var->save_result.ulong_value; + else + thd->variables.*offset= var->save_result.ulong_value; + return 0; +} + +void sys_var_thd_table_type::warn_deprecated(THD *thd) +{ + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DEPRECATED_SYNTAX, + ER(ER_WARN_DEPRECATED_SYNTAX), "table_type", "storage_engine"); +} + +void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type) +{ + warn_deprecated(thd); + sys_var_thd_storage_engine::set_default(thd, type); +} + +bool sys_var_thd_table_type::update(THD *thd, set_var *var) +{ + warn_deprecated(thd); + return sys_var_thd_storage_engine::update(thd, var); +} + + +/**************************************************************************** + Functions to handle sql_mode +****************************************************************************/ + +byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + ulong val; + char buff[256]; + String tmp(buff, sizeof(buff), &my_charset_latin1); + + tmp.length(0); + val= ((type == OPT_GLOBAL) ? global_system_variables.*offset : + thd->variables.*offset); + for (uint i= 0; val; val>>= 1, i++) + { + if (val & 1) + { + tmp.append(enum_names->type_names[i]); + tmp.append(','); + } + } + if (tmp.length()) + tmp.length(tmp.length() - 1); + return (byte*) thd->strmake(tmp.ptr(), tmp.length()); +} + + +void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.*offset= 0; + else + thd->variables.*offset= global_system_variables.*offset; +} + +void fix_sql_mode_var(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.sql_mode= + fix_sql_mode(global_system_variables.sql_mode); + else + thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode); +} + +/* Map database specific bits to function bits */ + +ulong fix_sql_mode(ulong sql_mode) +{ + /* + Note that we dont set + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS + to allow one to get full use of MySQL in this mode. + */ + + if (sql_mode & MODE_ANSI) + sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | MODE_ONLY_FULL_GROUP_BY); + if (sql_mode & MODE_ORACLE) + sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | + MODE_NO_FIELD_OPTIONS); + if (sql_mode & MODE_MSSQL) + sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | + MODE_NO_FIELD_OPTIONS); + if (sql_mode & MODE_POSTGRESQL) + sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | + MODE_NO_FIELD_OPTIONS); + if (sql_mode & MODE_DB2) + sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | + MODE_NO_FIELD_OPTIONS); + if (sql_mode & MODE_MAXDB) + sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | + MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | + MODE_NO_FIELD_OPTIONS); + if (sql_mode & MODE_MYSQL40) + sql_mode|= MODE_NO_FIELD_OPTIONS; + if (sql_mode & MODE_MYSQL323) + sql_mode|= MODE_NO_FIELD_OPTIONS; + return sql_mode; +} + + +/**************************************************************************** + Named list handling +****************************************************************************/ + +gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length, + NAMED_LIST **found) +{ + I_List_iterator<NAMED_LIST> it(*list); + NAMED_LIST *element; + while ((element= it++)) + { + if (element->cmp(name, length)) + { + if (found) + *found= element; + return element->data; + } + } + return 0; +} + + +void delete_elements(I_List<NAMED_LIST> *list, + void (*free_element)(const char *name, gptr)) +{ + NAMED_LIST *element; + DBUG_ENTER("delete_elements"); + while ((element= list->get())) + { + (*free_element)(element->name, element->data); + delete element; + } + DBUG_VOID_RETURN; +} + + +/* Key cache functions */ + +static KEY_CACHE *create_key_cache(const char *name, uint length) +{ + KEY_CACHE *key_cache; + DBUG_ENTER("create_key_cache"); + DBUG_PRINT("enter",("name: %.*s", length, name)); + + if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE), + MYF(MY_ZEROFILL | MY_WME)))) + { + if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache)) + { + my_free((char*) key_cache, MYF(0)); + key_cache= 0; + } + else + { + /* + Set default values for a key cache + The values in dflt_key_cache_var is set by my_getopt() at startup + + We don't set 'buff_size' as this is used to enable the key cache + */ + key_cache->param_block_size= dflt_key_cache_var.param_block_size; + key_cache->param_division_limit= dflt_key_cache_var.param_division_limit; + key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold; + } + } + DBUG_RETURN(key_cache); +} + + +KEY_CACHE *get_or_create_key_cache(const char *name, uint length) +{ + LEX_STRING key_cache_name; + KEY_CACHE *key_cache; + + key_cache_name.str= (char *) name; + key_cache_name.length= length; + pthread_mutex_lock(&LOCK_global_system_variables); + if (!(key_cache= get_key_cache(&key_cache_name))) + key_cache= create_key_cache(name, length); + pthread_mutex_unlock(&LOCK_global_system_variables); + return key_cache; +} + + +void free_key_cache(const char *name, KEY_CACHE *key_cache) +{ + ha_end_key_cache(key_cache); + my_free((char*) key_cache, MYF(0)); +} + + +bool process_key_caches(int (* func) (const char *name, KEY_CACHE *)) +{ + I_List_iterator<NAMED_LIST> it(key_caches); + NAMED_LIST *element; + + while ((element= it++)) + { + KEY_CACHE *key_cache= (KEY_CACHE *) element->data; + func(element->name, key_cache); + } + return 0; +} + + +/**************************************************************************** Used templates ****************************************************************************/ #ifdef __GNUC__ template class List<set_var_base>; -template class List_iterator<set_var_base>; +template class List_iterator_fast<set_var_base>; +template class I_List_iterator<NAMED_LIST>; #endif |