diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/ha_federated.cc | 8 | ||||
-rw-r--r-- | sql/handler.cc | 49 | ||||
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 17 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 6 | ||||
-rw-r--r-- | sql/item_func.cc | 8 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 13 | ||||
-rw-r--r-- | sql/item_timefunc.h | 1 | ||||
-rw-r--r-- | sql/my_decimal.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 5 | ||||
-rw-r--r-- | sql/nt_servc.cc | 12 | ||||
-rw-r--r-- | sql/nt_servc.h | 14 | ||||
-rw-r--r-- | sql/set_var.cc | 67 | ||||
-rw-r--r-- | sql/set_var.h | 47 | ||||
-rw-r--r-- | sql/sql_base.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 10 | ||||
-rw-r--r-- | sql/sql_show.cc | 10 | ||||
-rw-r--r-- | sql/sql_update.cc | 26 | ||||
-rw-r--r-- | sql/sql_view.cc | 13 | ||||
-rw-r--r-- | sql/tztime.cc | 22 | ||||
-rw-r--r-- | sql/tztime.h | 3 |
23 files changed, 283 insertions, 61 deletions
diff --git a/sql/field.cc b/sql/field.cc index 3d3f698f912..8188b51d4d1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5372,6 +5372,7 @@ int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_date((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1); @@ -5608,6 +5609,7 @@ int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { char buff[MAX_DATE_STRING_REP_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); + tmp= 0; make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, str.ptr(), str.length(), MYSQL_TIMESTAMP_DATETIME,1); diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index b4788dd9c87..d4144a41a2a 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -1320,6 +1320,14 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST); } + else + { + /* + Free tmp_share.scheme allocated in the parse_url() + as we found share in the hash and tmp_share isn't needed anymore. + */ + my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); + } share->use_count++; pthread_mutex_unlock(&federated_mutex); diff --git a/sql/handler.cc b/sql/handler.cc index 67ec5f3e759..71d184ad84b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1957,8 +1957,53 @@ bool handler::get_error_message(int error, String* buf) } +/** + Check for incompatible collation changes. + + @retval + HA_ADMIN_NEEDS_UPGRADE Table may have data requiring upgrade. + @retval + 0 No upgrade required. +*/ + +int handler::check_collation_compatibility() +{ + ulong mysql_version= table->s->mysql_version; + + if (mysql_version < 50048) + { + KEY *key= table->key_info; + KEY *key_end= key + table->s->keys; + for (; key < key_end; key++) + { + KEY_PART_INFO *key_part= key->key_part; + KEY_PART_INFO *key_part_end= key_part + key->key_parts; + for (; key_part < key_part_end; key_part++) + { + if (!key_part->fieldnr) + continue; + Field *field= table->field[key_part->fieldnr - 1]; + uint cs_number= field->charset()->number; + if (mysql_version < 50048 && + (cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */ + cs_number == 41 || /* latin7_general_ci - bug #29461 */ + cs_number == 42 || /* latin7_general_cs - bug #29461 */ + cs_number == 20 || /* latin7_estonian_cs - bug #29461 */ + cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */ + cs_number == 22 || /* koi8u_general_ci - bug #29461 */ + cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */ + cs_number == 26)) /* cp1250_general_ci - bug #29461 */ + return HA_ADMIN_NEEDS_UPGRADE; + } + } + } + return 0; +} + + int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) { + int error; KEY *keyinfo, *keyend; KEY_PART_INFO *keypart, *keypartend; @@ -1987,6 +2032,10 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } if (table->s->frm_version != FRM_VER_TRUE_VARCHAR) return HA_ADMIN_NEEDS_ALTER; + + if ((error= check_collation_compatibility())) + return error; + return check_for_upgrade(check_opt); } diff --git a/sql/handler.h b/sql/handler.h index aa3377c3868..8706aae5fce 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -787,6 +787,7 @@ protected: virtual int check_for_upgrade(HA_CHECK_OPT *check_opt) { return 0; } public: + int check_collation_compatibility(); int ha_check_for_upgrade(HA_CHECK_OPT *check_opt); int check_old_types(); /* to be actually called to get 'check()' functionality*/ diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0410c781590..3b1d18b4252 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -745,11 +745,11 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) obtained value */ -ulonglong +longlong get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null) { - ulonglong value; + longlong value; Item *item= **item_arg; MYSQL_TIME ltime; @@ -761,7 +761,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, else { *is_null= item->get_time(<ime); - value= !*is_null ? TIME_to_ulonglong_datetime(<ime) : 0; + value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(<ime) : 0; } /* Do not cache GET_USER_VAR() function as its const_item() may return TRUE @@ -886,11 +886,11 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) obtained value */ -ulonglong +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null) { - ulonglong value= 0; + longlong value= 0; String buf, *str= 0; Item *item= **item_arg; @@ -925,7 +925,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, enum_field_types f_type= warn_item->field_type(); timestamp_type t_type= f_type == MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME; - value= get_date_from_str(thd, str, t_type, warn_item->name, &error); + value= (longlong) get_date_from_str(thd, str, t_type, warn_item->name, &error); /* If str did not contain a valid date according to the current SQL_MODE, get_date_from_str() has already thrown a warning, @@ -979,7 +979,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int Arg_comparator::compare_datetime() { bool a_is_null, b_is_null; - ulonglong a_value, b_value; + longlong a_value, b_value; /* Get DATE/DATETIME/TIME value of the 'a' item. */ a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null); @@ -1434,7 +1434,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1bd60ff37d9..db831c7030c 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -42,8 +42,8 @@ class Arg_comparator: public Sql_alloc bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE, CMP_DATE_WITH_STR, CMP_STR_WITH_DATE }; - ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); + longlong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); public: DTCollation cmp_collation; @@ -1028,7 +1028,7 @@ public: */ class cmp_item_datetime :public cmp_item { - ulonglong value; + longlong value; public: THD *thd; /* Item used for issuing warnings. */ diff --git a/sql/item_func.cc b/sql/item_func.cc index dfe1082fd73..c0d08d9b213 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2275,7 +2275,7 @@ void Item_func_min_max::fix_length_and_dec() uint Item_func_min_max::cmp_datetimes(ulonglong *value) { - ulonglong min_max; + longlong min_max; uint min_max_idx= 0; LINT_INIT(min_max); @@ -2283,7 +2283,7 @@ uint Item_func_min_max::cmp_datetimes(ulonglong *value) { Item **arg= args + i; bool is_null; - ulonglong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); if ((null_value= args[i]->null_value)) return 0; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) @@ -5024,7 +5024,9 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->s->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->s->keys_in_use.is_set(keynr))) + (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) : + table->s->keys_in_use.is_set(keynr))) + { ft_to_key[fts]=keynr; ft_cnt[fts]=0; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0cb3c963dad..e9e92952908 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2550,6 +2550,8 @@ void Item_char_typecast::fix_length_and_dec() and thus avoid unnecessary character set conversion. - If the argument is not a number, then from_cs is set to the argument's charset. + + Note (TODO): we could use repertoire technique here. */ from_cs= (args[0]->result_type() == INT_RESULT || args[0]->result_type() == DECIMAL_RESULT || @@ -2557,12 +2559,13 @@ void Item_char_typecast::fix_length_and_dec() (cast_cs->mbminlen == 1 ? cast_cs : &my_charset_latin1) : args[0]->collation.collation; charset_conversion= (cast_cs->mbmaxlen > 1) || - !my_charset_same(from_cs, cast_cs) && - from_cs != &my_charset_bin && - cast_cs != &my_charset_bin; + (!my_charset_same(from_cs, cast_cs) && + from_cs != &my_charset_bin && + cast_cs != &my_charset_bin); collation.set(cast_cs, DERIVATION_IMPLICIT); - char_length= (cast_length >= 0) ? cast_length : - args[0]->max_length/from_cs->mbmaxlen; + char_length= (cast_length >= 0) ? + cast_length : + args[0]->max_length / args[0]->collation.collation->mbmaxlen; max_length= char_length * cast_cs->mbmaxlen; } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 7960c03d2e5..81a6c3e98bd 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -408,6 +408,7 @@ public: { return save_time_in_field(field); } + bool result_as_longlong() { return TRUE; } }; diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 31a5b09370a..a235edbd73c 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -216,7 +216,7 @@ my_decimal *date2my_decimal(MYSQL_TIME *ltime, my_decimal *dec) date = (ltime->year*100L + ltime->month)*100L + ltime->day; if (ltime->time_type > MYSQL_TIMESTAMP_DATE) date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second; - if (int2my_decimal(E_DEC_FATAL_ERROR, date, FALSE, dec)) + if (int2my_decimal(E_DEC_FATAL_ERROR, ltime->neg ? -date : date, FALSE, dec)) return dec; if (ltime->second_part) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1568f042b7e..520d97b5e9f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -435,6 +435,7 @@ MY_LOCALE *my_locale_by_number(uint number); #define UNCACHEABLE_PREPARE 16 /* For uncorrelated SELECT in an UNION with some correlated SELECTs */ #define UNCACHEABLE_UNITED 32 +#define UNCACHEABLE_CHECKOPTION 64 /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) @@ -1556,8 +1557,8 @@ void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, String *str); void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time, String *str); -ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, - Item *warn_item, bool *is_null); +longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c3e5449b22b..8232cefc880 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3035,12 +3035,14 @@ static int init_common_variables(const char *conf_file_name, int argc, sys_init_connect.value_length= strlen(opt_init_connect); else sys_init_connect.value=my_strdup("",MYF(0)); + sys_init_connect.is_os_charset= TRUE; sys_init_slave.value_length= 0; if ((sys_init_slave.value= opt_init_slave)) sys_init_slave.value_length= strlen(opt_init_slave); else sys_init_slave.value=my_strdup("",MYF(0)); + sys_init_slave.is_os_charset= TRUE; if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) return 1; @@ -3840,6 +3842,9 @@ we force server id to 2, but this MySQL server will not act as a slave."); : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); +#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) + Service.SetRunning(); +#endif #if defined(__NT__) || defined(HAVE_SMEM) handle_connections_methods(); diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index a04f284a3de..e570898f373 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -245,10 +245,6 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) if (!pService->StartService()) goto error; - // Check that the service is now running. - if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0)) - goto error; - // wait for exit event WaitForSingleObject (pService->hExitEvent, INFINITE); @@ -264,6 +260,14 @@ error: return; } + +void NTService::SetRunning() +{ + if (pService) + pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0); +} + + /* ------------------------------------------------------------------------ StartService() - starts the appliaction thread -------------------------------------------------------------------------- */ diff --git a/sql/nt_servc.h b/sql/nt_servc.h index a3c12569114..9b689e434e1 100644 --- a/sql/nt_servc.h +++ b/sql/nt_servc.h @@ -56,7 +56,19 @@ class NTService BOOL IsService(LPCSTR ServiceName); BOOL got_service_option(char **argv, char *service_option); BOOL is_super_user(); - void Stop(void); //to be called from app. to stop service + + /* + SetRunning() is to be called by the application + when initialization completes and it can accept + stop request + */ + void SetRunning(void); + + /* + Stop() is to be called by the application to stop + the service + */ + void Stop(void); protected: LPSTR ServiceName; diff --git a/sql/set_var.cc b/sql/set_var.cc index 6bc19f2e6eb..59741e5683d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -138,7 +138,7 @@ sys_var_thd_ulong sys_auto_increment_offset("auto_increment_offset", sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges", &sp_automatic_privileges); -sys_var_const_str sys_basedir("basedir", mysql_home); +sys_var_const_os_str sys_basedir("basedir", mysql_home); 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", @@ -151,6 +151,8 @@ 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_character_set_filesystem sys_character_set_filesystem("character_set_filesystem"); +sys_var_const_os_str sys_character_sets_dir("character_sets_dir", + mysql_charsets_dir); sys_var_thd_ulong sys_completion_type("completion_type", &SV::completion_type, check_completion_type, @@ -162,7 +164,7 @@ sys_var_long_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", &connect_timeout); -sys_var_const_str sys_datadir("datadir", mysql_real_data_home); +sys_var_const_os_str sys_datadir("datadir", mysql_real_data_home); sys_var_enum sys_delay_key_write("delay_key_write", &delay_key_write_options, &delay_key_write_typelib, @@ -311,6 +313,7 @@ sys_var_thd_ulong sys_optimizer_prune_level("optimizer_prune_level", &SV::optimizer_prune_level); sys_var_thd_ulong sys_optimizer_search_depth("optimizer_search_depth", &SV::optimizer_search_depth); +sys_var_const_os_str sys_plugin_dir("plugin_dir", opt_plugin_dir); 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", @@ -338,7 +341,7 @@ sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size", sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size", &SV::query_prealloc_size, 0, fix_thd_mem_root); -sys_var_readonly sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); +sys_var_readonly_os sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size", &SV::trans_alloc_block_size, 0, fix_trans_mem_root); @@ -363,9 +366,11 @@ sys_var_bool_ptr sys_secure_auth("secure_auth", &opt_secure_auth); sys_var_const_str_ptr sys_secure_file_priv("secure_file_priv", &opt_secure_file_priv); sys_var_long_ptr sys_server_id("server_id", &server_id, fix_server_id); +#ifdef HAVE_REPLICATION sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", &opt_slave_compressed_protocol); -#ifdef HAVE_REPLICATION +sys_var_const_os_str_ptr sys_slave_load_tmpdir("slave_load_tmpdir", + &slave_load_tmpdir); sys_var_long_ptr sys_slave_net_timeout("slave_net_timeout", &slave_net_timeout); sys_var_long_ptr sys_slave_trans_retries("slave_transaction_retries", @@ -380,17 +385,17 @@ sys_var_thd_sql_mode sys_sql_mode("sql_mode", #ifdef HAVE_OPENSSL extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key; -sys_var_const_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca); -sys_var_const_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath); -sys_var_const_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert); -sys_var_const_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher); -sys_var_const_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key); +sys_var_const_os_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca); +sys_var_const_os_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath); +sys_var_const_os_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert); +sys_var_const_os_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher); +sys_var_const_os_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key); #else -sys_var_const_str sys_ssl_ca("ssl_ca", NULL); -sys_var_const_str sys_ssl_capath("ssl_capath", NULL); -sys_var_const_str sys_ssl_cert("ssl_cert", NULL); -sys_var_const_str sys_ssl_cipher("ssl_cipher", NULL); -sys_var_const_str sys_ssl_key("ssl_key", NULL); +sys_var_const_os_str sys_ssl_ca("ssl_ca", NULL); +sys_var_const_os_str sys_ssl_capath("ssl_capath", NULL); +sys_var_const_os_str sys_ssl_cert("ssl_cert", NULL); +sys_var_const_os_str sys_ssl_cipher("ssl_cipher", NULL); +sys_var_const_os_str sys_ssl_key("ssl_key", NULL); #endif sys_var_thd_enum sys_updatable_views_with_limit("updatable_views_with_limit", @@ -460,6 +465,14 @@ sys_var_long_ptr sys_innodb_commit_concurrency("innodb_commit_concurrency", sys_var_long_ptr sys_innodb_flush_log_at_trx_commit( "innodb_flush_log_at_trx_commit", &srv_flush_log_at_trx_commit); +sys_var_const_os_str_ptr sys_innodb_data_file_path("innodb_data_file_path", + &innobase_data_file_path); +sys_var_const_os_str_ptr sys_innodb_data_home_dir("innodb_data_home_dir", + &innobase_data_home_dir); +sys_var_const_os_str_ptr sys_innodb_log_arch_dir("innodb_log_arch_dir", + &innobase_log_arch_dir); +sys_var_const_os_str_ptr sys_innodb_log_group_home_dir("innodb_log_group_home_dir", + &innobase_log_group_home_dir); #endif /* Condition pushdown to storage engine */ @@ -844,7 +857,7 @@ struct show_var_st init_vars[]= { {sys_character_set_results.name,(char*) &sys_character_set_results, SHOW_SYS}, {sys_character_set_server.name, (char*) &sys_character_set_server,SHOW_SYS}, {sys_charset_system.name, (char*) &sys_charset_system, SHOW_SYS}, - {"character_sets_dir", mysql_charsets_dir, SHOW_CHAR}, + {sys_character_sets_dir.name, (char *) &sys_character_sets_dir, 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}, @@ -905,8 +918,8 @@ struct show_var_st init_vars[]= { {"innodb_checksums", (char*) &innobase_use_checksums, SHOW_MY_BOOL}, {sys_innodb_commit_concurrency.name, (char*) &sys_innodb_commit_concurrency, SHOW_SYS}, {sys_innodb_concurrency_tickets.name, (char*) &sys_innodb_concurrency_tickets, SHOW_SYS}, - {"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR}, - {"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR}, + {sys_innodb_data_file_path.name, (char*) &sys_innodb_data_file_path, SHOW_SYS}, + {sys_innodb_data_home_dir.name, (char*) &sys_innodb_data_home_dir, SHOW_SYS}, {"innodb_adaptive_hash_index", (char*) &innobase_adaptive_hash_index, SHOW_MY_BOOL}, {"innodb_doublewrite", (char*) &innobase_use_doublewrite, SHOW_MY_BOOL}, {sys_innodb_fast_shutdown.name,(char*) &sys_innodb_fast_shutdown, SHOW_SYS}, @@ -917,12 +930,12 @@ struct show_var_st init_vars[]= { {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, {"innodb_lock_wait_timeout", (char*) &innobase_lock_wait_timeout, SHOW_LONG }, {"innodb_locks_unsafe_for_binlog", (char*) &innobase_locks_unsafe_for_binlog, SHOW_MY_BOOL}, - {"innodb_log_arch_dir", (char*) &innobase_log_arch_dir, SHOW_CHAR_PTR}, + {sys_innodb_log_arch_dir.name, (char*) &sys_innodb_log_arch_dir, SHOW_SYS}, {"innodb_log_archive", (char*) &innobase_log_archive, SHOW_MY_BOOL}, {"innodb_log_buffer_size", (char*) &innobase_log_buffer_size, SHOW_LONG }, {"innodb_log_file_size", (char*) &innobase_log_file_size, SHOW_LONGLONG}, {"innodb_log_files_in_group", (char*) &innobase_log_files_in_group, SHOW_LONG}, - {"innodb_log_group_home_dir", (char*) &innobase_log_group_home_dir, SHOW_CHAR_PTR}, + {sys_innodb_log_group_home_dir.name, (char*) &sys_innodb_log_group_home_dir, SHOW_SYS}, {sys_innodb_max_dirty_pages_pct.name, (char*) &sys_innodb_max_dirty_pages_pct, SHOW_SYS}, {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS}, {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG}, @@ -1026,7 +1039,7 @@ struct show_var_st init_vars[]= { {sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth, SHOW_SYS}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, - {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR}, + {sys_plugin_dir.name, (char*) &sys_plugin_dir, SHOW_SYS}, {"port", (char*) &mysqld_port, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, @@ -1068,7 +1081,7 @@ struct show_var_st init_vars[]= { #ifdef HAVE_REPLICATION {sys_slave_compressed_protocol.name, (char*) &sys_slave_compressed_protocol, SHOW_SYS}, - {"slave_load_tmpdir", (char*) &slave_load_tmpdir, SHOW_CHAR_PTR}, + {sys_slave_load_tmpdir.name,(char*) &sys_slave_load_tmpdir, SHOW_SYS}, {sys_slave_net_timeout.name,(char*) &sys_slave_net_timeout, SHOW_SYS}, {"slave_skip_errors", (char*) &slave_error_mask, SHOW_SLAVE_SKIP_ERRORS}, {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries, SHOW_SYS}, @@ -1175,6 +1188,7 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex, old_value= var_str->value; var_str->value= res; var_str->value_length= new_length; + var_str->is_os_charset= FALSE; rw_unlock(var_mutex); my_free(old_value, MYF(MY_ALLOW_ZERO_PTR)); return 0; @@ -1914,11 +1928,11 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) char *str= (char*) value_ptr(thd, var_type, base); if (str) tmp= new Item_string(str, strlen(str), - system_charset_info, DERIVATION_SYSCONST); + charset(thd), DERIVATION_SYSCONST); else { tmp= new Item_null(); - tmp->collation.set(system_charset_info, DERIVATION_SYSCONST); + tmp->collation.set(charset(thd), DERIVATION_SYSCONST); } pthread_mutex_unlock(&LOCK_global_system_variables); return tmp; @@ -1930,6 +1944,13 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) } +CHARSET_INFO *sys_var::charset(THD *thd) +{ + return is_os_charset ? thd->variables.character_set_filesystem : + system_charset_info; +} + + bool sys_var_thd_enum::update(THD *thd, set_var *var) { if (var->type == OPT_GLOBAL) diff --git a/sql/set_var.h b/sql/set_var.h index c37cc400e43..f43d3b75cee 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -46,9 +46,17 @@ public: sys_after_update_func after_update; bool no_support_one_shot; + /* + true if the value is in character_set_filesystem, + false otherwise. + Note that we can't use a pointer to the charset as the system var is + instantiated in global scope and the charset pointers are initialized + later. + */ + bool is_os_charset; sys_var(const char *name_arg, sys_after_update_func func= NULL) :name(name_arg), after_update(func) - , no_support_one_shot(1) + , no_support_one_shot(1), is_os_charset(FALSE) {} virtual ~sys_var() {} virtual bool check(THD *thd, set_var *var); @@ -68,6 +76,7 @@ public: Item *item(THD *thd, enum_var_type type, LEX_STRING *base); virtual bool is_struct() { return 0; } virtual bool is_readonly() const { return 0; } + CHARSET_INFO *charset(THD *thd); }; @@ -247,6 +256,17 @@ public: }; +class sys_var_const_os_str: public sys_var_const_str +{ +public: + sys_var_const_os_str(const char *name_arg, const char *value_arg) + :sys_var_const_str(name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_const_str_ptr :public sys_var { public: @@ -276,6 +296,17 @@ public: }; +class sys_var_const_os_str_ptr :public sys_var_const_str_ptr +{ +public: + sys_var_const_os_str_ptr(const char *name_arg, char **value_arg) + :sys_var_const_str_ptr(name_arg, value_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_enum :public sys_var { uint *value; @@ -791,6 +822,20 @@ public: bool is_readonly() const { return 1; } }; + +class sys_var_readonly_os: public sys_var_readonly +{ +public: + sys_var_readonly_os(const char *name_arg, enum_var_type type, + SHOW_TYPE show_type_arg, + sys_value_ptr_func value_ptr_func_arg) + :sys_var_readonly(name_arg, type, show_type_arg, value_ptr_func_arg) + { + is_os_charset= TRUE; + } +}; + + class sys_var_thd_time_zone :public sys_var_thd { public: diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 873a3eac24e..881c6a421e8 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2102,7 +2102,10 @@ bool reopen_table(TABLE *table,bool locked) for (key=0 ; key < table->s->keys ; key++) { for (part=0 ; part < table->key_info[key].usable_key_parts ; part++) + { table->key_info[key].key_part[part].field->table= table; + table->key_info[key].key_part[part].field->orig_table= table; + } } if (table->triggers) table->triggers->set_table(table); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 428d1709f94..2ac33c4e07f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -390,11 +390,21 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, { int res; nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + /* + Need to save the value, so we can turn off only the new NON_AGG_FIELD + additions coming from the WHERE + */ + uint8 saved_flag= thd->lex->current_select->full_group_by_flag; DBUG_ENTER("setup_without_group"); thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); res= setup_conds(thd, tables, leaves, conds); + /* it's not wrong to have non-aggregated columns in a WHERE */ + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) + thd->lex->current_select->full_group_by_flag= saved_flag | + (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED); + thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5a4772e9847..4e3d209f674 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1441,6 +1441,7 @@ static bool show_status_array(THD *thd, const char *wild, char name_buffer[80]; int len; LEX_STRING null_lex_str; + CHARSET_INFO *charset= system_charset_info; DBUG_ENTER("show_status_array"); null_lex_str.str= 0; // For sys_var->value_ptr() @@ -1469,9 +1470,10 @@ static bool show_status_array(THD *thd, const char *wild, long nr; if (show_type == SHOW_SYS) { - show_type= ((sys_var*) value)->show_type(); - value= (char*) ((sys_var*) value)->value_ptr(thd, value_type, - &null_lex_str); + sys_var *var= ((sys_var *) value); + show_type= var->show_type(); + value= (char*) var->value_ptr(thd, value_type, &null_lex_str); + charset= var->charset(thd); } pos= end= buff; @@ -1794,7 +1796,7 @@ static bool show_status_array(THD *thd, const char *wild, restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), system_charset_info); - table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); + table->field[1]->store(pos, (uint32) (end - pos), charset); if (schema_table_store_record(thd, table)) DBUG_RETURN(TRUE); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index eb4e9b7ed73..f15db220a3b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1249,6 +1249,32 @@ multi_update::initialize_tables(JOIN *join) } } + /* + enable uncacheable flag if we update a view with check option + and check option has a subselect, otherwise, the check option + can be evaluated after the subselect was freed as independent + (See full_local in JOIN::join_free()). + */ + if (table_ref->check_option && !join->select_lex->uncacheable) + { + SELECT_LEX_UNIT *tmp_unit; + SELECT_LEX *sl; + for (tmp_unit= join->select_lex->first_inner_unit(); + tmp_unit; + tmp_unit= tmp_unit->next_unit()) + { + for (sl= tmp_unit->first_select(); sl; sl= sl->next_select()) + { + if (sl->master_unit()->item) + { + join->select_lex->uncacheable|= UNCACHEABLE_CHECKOPTION; + goto loop_end; + } + } + } + } +loop_end: + if (table == first_table_for_update && table_ref->check_option) { table_map unupdated_tables= table_ref->check_option->used_tables() & diff --git a/sql/sql_view.cc b/sql/sql_view.cc index f65a62bed75..41a638b2618 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -980,13 +980,14 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, DBUG_RETURN(0); } - if (table->use_index || table->ignore_index) + List<String> *index_list= table->use_index ? table->use_index + : table->ignore_index; + if (index_list) { - my_error(ER_WRONG_USAGE, MYF(0), - table->ignore_index ? "IGNORE INDEX" : - (table->force_index ? "FORCE INDEX" : "USE INDEX"), - "VIEW"); - DBUG_RETURN(TRUE); + DBUG_ASSERT(index_list->head()); // should never fail + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), index_list->head()->c_ptr(), + table->table_name); + DBUG_RETURN(TRUE); } /* check loop via view definition */ diff --git a/sql/tztime.cc b/sql/tztime.cc index 709e3b64752..d3d952e3c1e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1073,6 +1073,7 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1157,6 +1158,7 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const gmtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); tmp->time_type= MYSQL_TIMESTAMP_DATETIME; + adjust_leap_second(tmp); } @@ -1260,6 +1262,7 @@ void Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { ::gmt_sec_to_TIME(tmp, t, tz_info); + adjust_leap_second(tmp); } @@ -2373,6 +2376,25 @@ Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name) DBUG_RETURN(tz); } + +/** + Convert leap seconds into non-leap + + This function will convert the leap seconds added by the OS to + non-leap seconds, e.g. 23:59:59, 23:59:60 -> 23:59:59, 00:00:01 ... + This check is not checking for years on purpose : although it's not a + complete check this way it doesn't require looking (and having installed) + the leap seconds table. + + @param[in,out] broken down time structure as filled in by the OS +*/ + +void Time_zone::adjust_leap_second(MYSQL_TIME *t) +{ + if (t->second == 60 || t->second == 61) + t->second= 59; +} + #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */ diff --git a/sql/tztime.h b/sql/tztime.h index 32a942a26e1..750b8dacbe1 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -55,6 +55,9 @@ public: allocated on MEM_ROOT and should not require destruction. */ virtual ~Time_zone() {}; + +protected: + static inline void adjust_leap_second(MYSQL_TIME *t); }; extern Time_zone * my_tz_UTC; |