Loading mysql-test/r/timezone2.result +8 −0 Original line number Diff line number Diff line Loading @@ -303,3 +303,11 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; flush privileges; drop table t1, t2; select convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) from (select 'UTC' as custTimeZone) as tmp; convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) 2005-01-14 17:00:00 create table t1 select convert_tz(NULL, NULL, NULL); select * from t1; convert_tz(NULL, NULL, NULL) NULL drop table t1; mysql-test/t/timezone2.test +17 −0 Original line number Diff line number Diff line Loading @@ -266,3 +266,20 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; flush privileges; drop table t1, t2; # # Test for bug #7705 "CONVERT_TZ() crashes with subquery/WHERE on index # column". Queries in which one of time zone arguments of CONVERT_TZ() is # determined as constant only at val() stage (not at fix_fields() stage), # should not crash server. # select convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) from (select 'UTC' as custTimeZone) as tmp; # # Test for bug #7899 "CREATE TABLE .. SELECT .. and CONVERT_TZ() function # does not work well together". The following statement should return only # one NULL row and not result of full join. # create table t1 select convert_tz(NULL, NULL, NULL); select * from t1; drop table t1; sql/item_timefunc.cc +19 −11 Original line number Diff line number Diff line Loading @@ -1656,6 +1656,7 @@ void Item_func_convert_tz::fix_length_and_dec() collation.set(&my_charset_bin); decimals= 0; max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; maybe_null= 1; } Loading @@ -1668,12 +1669,6 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re tz_tables= thd_arg->lex->time_zone_tables_used; if (args[1]->const_item()) from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); if (args[2]->const_item()) to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); return 0; } Loading Loading @@ -1714,11 +1709,17 @@ bool Item_func_convert_tz::get_date(TIME *ltime, bool not_used; String str; if (!args[1]->const_item()) if (!from_tz_cached) { from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); from_tz_cached= args[1]->const_item(); } if (!args[2]->const_item()) if (!to_tz_cached) { to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); to_tz_cached= args[2]->const_item(); } if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, 0)) { Loading @@ -1741,6 +1742,13 @@ bool Item_func_convert_tz::get_date(TIME *ltime, } void Item_func_convert_tz::cleanup() { from_tz_cached= to_tz_cached= 0; Item_date_func::cleanup(); } void Item_date_add_interval::fix_length_and_dec() { enum_field_types arg0_field_type; Loading sql/item_timefunc.h +6 −2 Original line number Diff line number Diff line Loading @@ -545,12 +545,15 @@ class Item_func_convert_tz :public Item_date_func TABLE_LIST *tz_tables; /* If time zone parameters are constants we are caching objects that represent them. represent them (we use separate from_tz_cached/to_tz_cached members to indicate this fact, since NULL is legal value for from_tz/to_tz members. */ bool from_tz_cached, to_tz_cached; Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(Item *a, Item *b, Item *c): Item_date_func(a, b, c) {} Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} longlong val_int(); double val() { return (double) val_int(); } String *val_str(String *str); Loading @@ -558,6 +561,7 @@ class Item_func_convert_tz :public Item_date_func bool fix_fields(THD *, struct st_table_list *, Item **); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); void cleanup(); }; Loading sql/set_var.cc +17 −11 Original line number Diff line number Diff line Loading @@ -2438,8 +2438,15 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) bool sys_var_thd_time_zone::update(THD *thd, set_var *var) { /* We are using Time_zone object found during check() phase */ *get_tz_ptr(thd,var->type)= var->save_result.time_zone; /* We are using Time_zone object found during check() phase. */ if (var->type == OPT_GLOBAL) { pthread_mutex_lock(&LOCK_global_system_variables); global_system_variables.time_zone= var->save_result.time_zone; pthread_mutex_unlock(&LOCK_global_system_variables); } else thd->variables.time_zone= var->save_result.time_zone; return 0; } Loading @@ -2451,27 +2458,25 @@ byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type, We can use ptr() instead of c_ptr() here because String contaning time zone name is guaranteed to be zero ended. */ return (byte *)((*get_tz_ptr(thd,type))->get_name()->ptr()); } Time_zone** sys_var_thd_time_zone::get_tz_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.time_zone; return (byte *)(global_system_variables.time_zone->get_name()->ptr()); else return &thd->variables.time_zone; return (byte *)(thd->variables.time_zone->get_name()->ptr()); } void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) { pthread_mutex_lock(&LOCK_global_system_variables); if (type == OPT_GLOBAL) { if (default_tz_name) { String str(default_tz_name, &my_charset_latin1); /* We are guaranteed to find this time zone since its existence is checked during start-up. */ global_system_variables.time_zone= my_tz_find(&str, thd->lex->time_zone_tables_used); } Loading @@ -2480,6 +2485,7 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) } else thd->variables.time_zone= global_system_variables.time_zone; pthread_mutex_unlock(&LOCK_global_system_variables); } /* Loading Loading
mysql-test/r/timezone2.result +8 −0 Original line number Diff line number Diff line Loading @@ -303,3 +303,11 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; flush privileges; drop table t1, t2; select convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) from (select 'UTC' as custTimeZone) as tmp; convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) 2005-01-14 17:00:00 create table t1 select convert_tz(NULL, NULL, NULL); select * from t1; convert_tz(NULL, NULL, NULL) NULL drop table t1;
mysql-test/t/timezone2.test +17 −0 Original line number Diff line number Diff line Loading @@ -266,3 +266,20 @@ delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; flush privileges; drop table t1, t2; # # Test for bug #7705 "CONVERT_TZ() crashes with subquery/WHERE on index # column". Queries in which one of time zone arguments of CONVERT_TZ() is # determined as constant only at val() stage (not at fix_fields() stage), # should not crash server. # select convert_tz('2005-01-14 17:00:00', 'UTC', custTimeZone) from (select 'UTC' as custTimeZone) as tmp; # # Test for bug #7899 "CREATE TABLE .. SELECT .. and CONVERT_TZ() function # does not work well together". The following statement should return only # one NULL row and not result of full join. # create table t1 select convert_tz(NULL, NULL, NULL); select * from t1; drop table t1;
sql/item_timefunc.cc +19 −11 Original line number Diff line number Diff line Loading @@ -1656,6 +1656,7 @@ void Item_func_convert_tz::fix_length_and_dec() collation.set(&my_charset_bin); decimals= 0; max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; maybe_null= 1; } Loading @@ -1668,12 +1669,6 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re tz_tables= thd_arg->lex->time_zone_tables_used; if (args[1]->const_item()) from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); if (args[2]->const_item()) to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); return 0; } Loading Loading @@ -1714,11 +1709,17 @@ bool Item_func_convert_tz::get_date(TIME *ltime, bool not_used; String str; if (!args[1]->const_item()) if (!from_tz_cached) { from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); from_tz_cached= args[1]->const_item(); } if (!args[2]->const_item()) if (!to_tz_cached) { to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); to_tz_cached= args[2]->const_item(); } if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, 0)) { Loading @@ -1741,6 +1742,13 @@ bool Item_func_convert_tz::get_date(TIME *ltime, } void Item_func_convert_tz::cleanup() { from_tz_cached= to_tz_cached= 0; Item_date_func::cleanup(); } void Item_date_add_interval::fix_length_and_dec() { enum_field_types arg0_field_type; Loading
sql/item_timefunc.h +6 −2 Original line number Diff line number Diff line Loading @@ -545,12 +545,15 @@ class Item_func_convert_tz :public Item_date_func TABLE_LIST *tz_tables; /* If time zone parameters are constants we are caching objects that represent them. represent them (we use separate from_tz_cached/to_tz_cached members to indicate this fact, since NULL is legal value for from_tz/to_tz members. */ bool from_tz_cached, to_tz_cached; Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(Item *a, Item *b, Item *c): Item_date_func(a, b, c) {} Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} longlong val_int(); double val() { return (double) val_int(); } String *val_str(String *str); Loading @@ -558,6 +561,7 @@ class Item_func_convert_tz :public Item_date_func bool fix_fields(THD *, struct st_table_list *, Item **); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); void cleanup(); }; Loading
sql/set_var.cc +17 −11 Original line number Diff line number Diff line Loading @@ -2438,8 +2438,15 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) bool sys_var_thd_time_zone::update(THD *thd, set_var *var) { /* We are using Time_zone object found during check() phase */ *get_tz_ptr(thd,var->type)= var->save_result.time_zone; /* We are using Time_zone object found during check() phase. */ if (var->type == OPT_GLOBAL) { pthread_mutex_lock(&LOCK_global_system_variables); global_system_variables.time_zone= var->save_result.time_zone; pthread_mutex_unlock(&LOCK_global_system_variables); } else thd->variables.time_zone= var->save_result.time_zone; return 0; } Loading @@ -2451,27 +2458,25 @@ byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type, We can use ptr() instead of c_ptr() here because String contaning time zone name is guaranteed to be zero ended. */ return (byte *)((*get_tz_ptr(thd,type))->get_name()->ptr()); } Time_zone** sys_var_thd_time_zone::get_tz_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.time_zone; return (byte *)(global_system_variables.time_zone->get_name()->ptr()); else return &thd->variables.time_zone; return (byte *)(thd->variables.time_zone->get_name()->ptr()); } void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) { pthread_mutex_lock(&LOCK_global_system_variables); if (type == OPT_GLOBAL) { if (default_tz_name) { String str(default_tz_name, &my_charset_latin1); /* We are guaranteed to find this time zone since its existence is checked during start-up. */ global_system_variables.time_zone= my_tz_find(&str, thd->lex->time_zone_tables_used); } Loading @@ -2480,6 +2485,7 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) } else thd->variables.time_zone= global_system_variables.time_zone; pthread_mutex_unlock(&LOCK_global_system_variables); } /* Loading