diff options
author | Staale Smedseng <staale.smedseng@sun.com> | 2009-03-19 11:44:57 +0100 |
---|---|---|
committer | Staale Smedseng <staale.smedseng@sun.com> | 2009-03-19 11:44:57 +0100 |
commit | 6725f3efd6e406b0c35e9f841a9de4e72e1883a0 (patch) | |
tree | da936d324a86eba476ece9e6ef679493a4f4abc6 /sql/tztime.cc | |
parent | 169bf745401ac365564194f8d7fb2ea6e5e93fb8 (diff) | |
parent | 28f4090bda66bd4eb33ab0fd25fe2c29d24975a4 (diff) | |
download | mariadb-git-6725f3efd6e406b0c35e9f841a9de4e72e1883a0.tar.gz |
Merge from 5.0-bugteam
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 53870915973..2a94e179600 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1825,6 +1825,13 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; #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"); /* 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) Most probably user has mistyped time zone name, so no need to bark here 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 goto end; } @@ -1895,8 +1903,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) /* If Uses_leap_seconds == 'Y' */ if (table->field[1]->val_int() == 1) { - tz_info->leapcnt= tz_leapcnt; - tz_info->lsis= tz_lsis; + tmp_tz_info.leapcnt= tz_leapcnt; + tmp_tz_info.lsis= tz_lsis; } (void)table->file->ha_index_end(); @@ -1932,18 +1940,18 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #ifdef ABBR_ARE_USED // FIXME should we do something with duplicates here ? 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 " "mysql.time_zone_transition_type table: not enough " "room for abbreviations"); goto end; } - ttis[ttid].tt_abbrind= tz_info->charcnt; - memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); - tz_info->charcnt+= abbr.length(); - chars[tz_info->charcnt]= 0; - tz_info->charcnt++; + ttis[ttid].tt_abbrind= tmp_tz_info.charcnt; + memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length()); + tmp_tz_info.charcnt+= abbr.length(); + chars[tmp_tz_info.charcnt]= 0; + tmp_tz_info.charcnt++; DBUG_PRINT("info", ("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) #endif /* 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], table->field[0]->ptr, 4); @@ -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(); 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 " "mysql.time_zone_transition table: " "too much transitions"); 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 " "mysql.time_zone_transition table: " @@ -2005,9 +2013,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) goto end; } - ats[tz_info->timecnt]= ttime; - types[tz_info->timecnt]= ttid; - tz_info->timecnt++; + ats[tmp_tz_info.timecnt]= ttime; + types[tmp_tz_info.timecnt]= ttid; + tmp_tz_info.timecnt++; DBUG_PRINT("info", ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", @@ -2032,6 +2040,34 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) 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. */ if (!(alloc_buff= (char*) alloc_root(&tz_storage, @@ -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; memcpy(tz_info->ttis, ttis, tz_info->typecnt * sizeof(TRAN_TYPE_INFO)); - /* - 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; - } + /* Build reversed map. */ if (prepare_tz_info(tz_info, &tz_storage)) { sql_print_error("Unable to build mktime map for time zone"); |