Commit 4f4c45e1 authored by Staale Smedseng's avatar Staale Smedseng

Merge from 5.0-bugteam

parents db08d4f6 4ecbd0b5
...@@ -1825,6 +1825,13 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1825,6 +1825,13 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#ifdef ABBR_ARE_USED #ifdef ABBR_ARE_USED
char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
#endif #endif
/*
Used as a temporary tz_info until we decide that we actually want to
allocate and keep the tz info and tz name in tz_storage.
*/
TIME_ZONE_INFO tmp_tz_info;
memset(&tmp_tz_info, 0, sizeof(TIME_ZONE_INFO));
DBUG_ENTER("tz_load_from_open_tables"); DBUG_ENTER("tz_load_from_open_tables");
/* Prepare tz_info for loading also let us make copy of time zone name */ /* Prepare tz_info for loading also let us make copy of time zone name */
...@@ -1866,7 +1873,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1866,7 +1873,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
Most probably user has mistyped time zone name, so no need to bark here Most probably user has mistyped time zone name, so no need to bark here
unless we need it for debugging. unless we need it for debugging.
*/ */
sql_print_error("Can't find description of time zone '%s'", tz_name_buff); sql_print_error("Can't find description of time zone '%.*s'",
tz_name->length(), tz_name->ptr());
#endif #endif
goto end; goto end;
} }
...@@ -1895,8 +1903,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1895,8 +1903,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
/* If Uses_leap_seconds == 'Y' */ /* If Uses_leap_seconds == 'Y' */
if (table->field[1]->val_int() == 1) if (table->field[1]->val_int() == 1)
{ {
tz_info->leapcnt= tz_leapcnt; tmp_tz_info.leapcnt= tz_leapcnt;
tz_info->lsis= tz_lsis; tmp_tz_info.lsis= tz_lsis;
} }
(void)table->file->ha_index_end(); (void)table->file->ha_index_end();
...@@ -1932,18 +1940,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1932,18 +1940,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#ifdef ABBR_ARE_USED #ifdef ABBR_ARE_USED
// FIXME should we do something with duplicates here ? // FIXME should we do something with duplicates here ?
table->field[4]->val_str(&abbr, &abbr); table->field[4]->val_str(&abbr, &abbr);
if (tz_info->charcnt + abbr.length() + 1 > sizeof(chars)) if (tmp_tz_info.charcnt + abbr.length() + 1 > sizeof(chars))
{ {
sql_print_error("Error while loading time zone description from " sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition_type table: not enough " "mysql.time_zone_transition_type table: not enough "
"room for abbreviations"); "room for abbreviations");
goto end; goto end;
} }
ttis[ttid].tt_abbrind= tz_info->charcnt; ttis[ttid].tt_abbrind= tmp_tz_info.charcnt;
memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length());
tz_info->charcnt+= abbr.length(); tmp_tz_info.charcnt+= abbr.length();
chars[tz_info->charcnt]= 0; chars[tmp_tz_info.charcnt]= 0;
tz_info->charcnt++; tmp_tz_info.charcnt++;
DBUG_PRINT("info", DBUG_PRINT("info",
("time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld " ("time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld "
...@@ -1956,9 +1964,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1956,9 +1964,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
#endif #endif
/* ttid is increasing because we are reading using index */ /* ttid is increasing because we are reading using index */
DBUG_ASSERT(ttid >= tz_info->typecnt); DBUG_ASSERT(ttid >= tmp_tz_info.typecnt);
tz_info->typecnt= ttid + 1; tmp_tz_info.typecnt= ttid + 1;
res= table->file->index_next_same(table->record[0], res= table->file->index_next_same(table->record[0],
table->field[0]->ptr, 4); table->field[0]->ptr, 4);
...@@ -1990,14 +1998,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -1990,14 +1998,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
ttime= (my_time_t)table->field[1]->val_int(); ttime= (my_time_t)table->field[1]->val_int();
ttid= (uint)table->field[2]->val_int(); ttid= (uint)table->field[2]->val_int();
if (tz_info->timecnt + 1 > TZ_MAX_TIMES) if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES)
{ {
sql_print_error("Error while loading time zone description from " sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition table: " "mysql.time_zone_transition table: "
"too much transitions"); "too much transitions");
goto end; goto end;
} }
if (ttid + 1 > tz_info->typecnt) if (ttid + 1 > tmp_tz_info.typecnt)
{ {
sql_print_error("Error while loading time zone description from " sql_print_error("Error while loading time zone description from "
"mysql.time_zone_transition table: " "mysql.time_zone_transition table: "
...@@ -2005,9 +2013,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -2005,9 +2013,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
goto end; goto end;
} }
ats[tz_info->timecnt]= ttime; ats[tmp_tz_info.timecnt]= ttime;
types[tz_info->timecnt]= ttid; types[tmp_tz_info.timecnt]= ttid;
tz_info->timecnt++; tmp_tz_info.timecnt++;
DBUG_PRINT("info", DBUG_PRINT("info",
("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u",
...@@ -2031,6 +2039,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -2031,6 +2039,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
(void)table->file->ha_index_end(); (void)table->file->ha_index_end();
table= 0; table= 0;
/*
Let us check how correct our time zone description is. We don't check for
tz->timecnt < 1 since it is ok for GMT.
*/
if (tmp_tz_info.typecnt < 1)
{
sql_print_error("loading time zone without transition types");
goto end;
}
/* Allocate memory for the timezone info and timezone name in tz_storage. */
if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) +
tz_name->length() + 1)))
{
sql_print_error("Out of memory while loading time zone description");
return 0;
}
/* Move the temporary tz_info into the allocated area */
tz_info= (TIME_ZONE_INFO *)alloc_buff;
memcpy(tz_info, &tmp_tz_info, sizeof(TIME_ZONE_INFO));
tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO);
/*
By writing zero to the end we guarantee that we can call ptr()
instead of c_ptr() for time zone name.
*/
strmake(tz_name_buff, tz_name->ptr(), tz_name->length());
/* /*
Now we will allocate memory and init TIME_ZONE_INFO structure. Now we will allocate memory and init TIME_ZONE_INFO structure.
*/ */
...@@ -2062,15 +2098,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) ...@@ -2062,15 +2098,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
tz_info->ttis= (TRAN_TYPE_INFO *)alloc_buff; tz_info->ttis= (TRAN_TYPE_INFO *)alloc_buff;
memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO)); memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO));
/* /* Build reversed map. */
Let us check how correct our time zone description and build
reversed map. We don't check for tz->timecnt < 1 since it ok for GMT.
*/
if (tz_info->typecnt < 1)
{
sql_print_error("loading time zone without transition types");
goto end;
}
if (prepare_tz_info(tz_info, &tz_storage)) if (prepare_tz_info(tz_info, &tz_storage))
{ {
sql_print_error("Unable to build mktime map for time zone"); sql_print_error("Unable to build mktime map for time zone");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment