Commit bf89dc06 authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/dlenev/src/mysql-4.1-tzbug


sql/item_timefunc.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/tztime.cc:
  Auto merged
parents 418a0630 20bd0bd6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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;
+17 −0
Original line number Diff line number Diff line
@@ -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;
+19 −11
Original line number Diff line number Diff line
@@ -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;
}


@@ -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;
}

@@ -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))
  {
@@ -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;
+6 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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();
};


+17 −11
Original line number Diff line number Diff line
@@ -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;
}

@@ -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);
   }
@@ -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