diff options
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 305 |
1 files changed, 101 insertions, 204 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 914c7be46de..08b93cfd203 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -77,7 +77,7 @@ typedef struct lsinfo /* Structure with information describing ranges of my_time_t shifted to local - time (my_time_t + offset). Used for local TIME -> my_time_t conversion. + time (my_time_t + offset). Used for local MYSQL_TIME -> my_time_t conversion. See comments for TIME_to_gmt_sec() for more info. */ typedef struct revtinfo @@ -292,9 +292,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) be used if there are no transitions or we have moment in time before any transitions. Second task is to build "shifted my_time_t" -> my_time_t map used in - TIME -> my_time_t conversion. + MYSQL_TIME -> my_time_t conversion. Note: See description of TIME_to_gmt_sec() function first. - In order to perform TIME -> my_time_t conversion we need to build table + In order to perform MYSQL_TIME -> my_time_t conversion we need to build table which defines "shifted by tz offset and leap seconds my_time_t" -> my_time_t function wich is almost the same (except ranges of ambiguity) as reverse function to piecewise linear function used for my_time_t -> @@ -531,14 +531,14 @@ static const uint year_lengths[2]= offset - local time zone offset DESCRIPTION - Convert my_time_t with offset to TIME struct. Differs from timesub + Convert my_time_t with offset to MYSQL_TIME struct. Differs from timesub (from elsie code) because doesn't contain any leap correction and TM_GMTOFF and is_dst setting and contains some MySQL specific initialization. Funny but with removing of these we almost have glibc's offtime function. */ static void -sec_to_TIME(TIME * tmp, my_time_t t, long offset) +sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset) { long days; long rem; @@ -594,7 +594,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset) tmp->month++; tmp->day= (uint)(days + 1); - /* filling MySQL specific TIME members */ + /* filling MySQL specific MYSQL_TIME members */ tmp->neg= 0; tmp->second_part= 0; tmp->time_type= MYSQL_TIMESTAMP_DATETIME; } @@ -686,7 +686,7 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp) /* Converts time in my_time_t representation (seconds in UTC since Epoch) to - broken down TIME representation in local time zone. + broken down MYSQL_TIME representation in local time zone. SYNOPSIS gmt_sec_to_TIME() @@ -701,12 +701,12 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp) (60th and 61st second, look how we calculate them as "hit" in this function). Under realistic assumptions about frequency of transitions the same array - can be used fot TIME -> my_time_t conversion. For this we need to + can be used fot MYSQL_TIME -> my_time_t conversion. For this we need to implement tweaked binary search which will take into account that some - TIME has two matching my_time_t ranges and some of them have none. + MYSQL_TIME has two matching my_time_t ranges and some of them have none. */ static void -gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp) +gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp) { const TRAN_TYPE_INFO *ttisp; const LS_INFO *lp; @@ -809,11 +809,11 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) /* - Works like sec_since_epoch but expects TIME structure as parameter. + Works like sec_since_epoch but expects MYSQL_TIME structure as parameter. */ my_time_t -sec_since_epoch_TIME(TIME *t) +sec_since_epoch_TIME(MYSQL_TIME *t) { return sec_since_epoch(t->year, t->month, t->day, t->hour, t->minute, t->second); @@ -821,7 +821,7 @@ sec_since_epoch_TIME(TIME *t) /* - Converts local time in broken down TIME representation to my_time_t + Converts local time in broken down MYSQL_TIME representation to my_time_t representation. SYNOPSIS @@ -863,7 +863,7 @@ sec_since_epoch_TIME(TIME *t) We use completely different approach. It is better since it is both faster than iterative implementations and fully determenistic. If you - look at my_time_t to TIME conversion then you'll find that it consist + look at my_time_t to MYSQL_TIME conversion then you'll find that it consist of two steps: The first is calculating shifted my_time_t value and the second - TIME calculation from shifted my_time_t value (well it is a bit simplified @@ -893,7 +893,7 @@ sec_since_epoch_TIME(TIME *t) 0 in case of error. */ static my_time_t -TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp, +TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, my_bool *in_dst_time_gap) { my_time_t local_t; @@ -1020,20 +1020,20 @@ class Time_zone_system : public Time_zone { public: Time_zone_system() {} /* Remove gcc warning */ - virtual my_time_t TIME_to_gmt_sec(const TIME *t, + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const; - virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const; + virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; }; /* - Converts local time in system time zone in TIME representation + Converts local time in system time zone in MYSQL_TIME representation to its my_time_t representation. SYNOPSIS TIME_to_gmt_sec() - t - pointer to TIME structure with local time in + t - pointer to MYSQL_TIME structure with local time in broken-down representation. in_dst_time_gap - pointer to bool which is set to true if datetime value passed doesn't really exist (i.e. falls into @@ -1041,7 +1041,7 @@ public: DESCRIPTION This method uses system function (localtime_r()) for conversion - local time in system time zone in TIME structure to its my_time_t + local time in system time zone in MYSQL_TIME structure to its my_time_t representation. Unlike the same function for Time_zone_db class it it won't handle unnormalized input properly. Still it will return lowest possible my_time_t in case of ambiguity or if we @@ -1053,7 +1053,7 @@ public: Corresponding my_time_t value or 0 in case of error */ my_time_t -Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const +Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const { long not_used; return my_system_gmt_sec(t, ¬_used, in_dst_time_gap); @@ -1066,7 +1066,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const SYNOPSIS gmt_sec_to_TIME() - tmp - pointer to TIME structure to fill-in + tmp - pointer to MYSQL_TIME structure to fill-in t - my_time_t value to be converted NOTE @@ -1077,7 +1077,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const the 1902 easily. */ void -Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const +Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { struct tm tmp_tm; time_t tmp_t= (time_t)t; @@ -1107,26 +1107,26 @@ Time_zone_system::get_name() const /* Instance of this class represents UTC time zone. It uses system gmtime_r function for conversions and is always available. It is used only for - my_time_t -> TIME conversions in various UTC_... functions, it is not - intended for TIME -> my_time_t conversions and shouldn't be exposed to user. + my_time_t -> MYSQL_TIME conversions in various UTC_... functions, it is not + intended for MYSQL_TIME -> my_time_t conversions and shouldn't be exposed to user. */ class Time_zone_utc : public Time_zone { public: Time_zone_utc() {} /* Remove gcc warning */ - virtual my_time_t TIME_to_gmt_sec(const TIME *t, + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const; - virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const; + virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; }; /* - Convert UTC time from TIME representation to its my_time_t representation. + Convert UTC time from MYSQL_TIME representation to its my_time_t representation. SYNOPSIS TIME_to_gmt_sec() - t - pointer to TIME structure with local time + t - pointer to MYSQL_TIME structure with local time in broken-down representation. in_dst_time_gap - pointer to bool which is set to true if datetime value passed doesn't really exist (i.e. falls into @@ -1141,7 +1141,7 @@ public: 0 */ my_time_t -Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const +Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const { /* Should be never called */ DBUG_ASSERT(0); @@ -1155,14 +1155,14 @@ Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const SYNOPSIS gmt_sec_to_TIME() - tmp - pointer to TIME structure to fill-in + tmp - pointer to MYSQL_TIME structure to fill-in t - my_time_t value to be converted NOTE See note for apropriate Time_zone_system method. */ void -Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const +Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { struct tm tmp_tm; time_t tmp_t= (time_t)t; @@ -1203,9 +1203,9 @@ class Time_zone_db : public Time_zone { public: Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg); - virtual my_time_t TIME_to_gmt_sec(const TIME *t, + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const; - virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const; + virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; private: TIME_ZONE_INFO *tz_info; @@ -1239,7 +1239,7 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg, SYNOPSIS TIME_to_gmt_sec() - t - pointer to TIME structure with local time + t - pointer to MYSQL_TIME structure with local time in broken-down representation. in_dst_time_gap - pointer to bool which is set to true if datetime value passed doesn't really exist (i.e. falls into @@ -1253,7 +1253,7 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg, Corresponding my_time_t value or 0 in case of error */ my_time_t -Time_zone_db::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const +Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const { return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap); } @@ -1265,11 +1265,11 @@ Time_zone_db::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const SYNOPSIS gmt_sec_to_TIME() - tmp - pointer to TIME structure to fill-in + tmp - pointer to MYSQL_TIME structure to fill-in t - my_time_t value to be converted */ void -Time_zone_db::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const +Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { ::gmt_sec_to_TIME(tmp, t, tz_info); } @@ -1299,9 +1299,9 @@ class Time_zone_offset : public Time_zone { public: Time_zone_offset(long tz_offset_arg); - virtual my_time_t TIME_to_gmt_sec(const TIME *t, + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const; - virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const; + virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; /* This have to be public because we want to be able to access it from @@ -1336,11 +1336,11 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg): /* Converts local time in time zone described as offset from UTC - from TIME representation to its my_time_t representation. + from MYSQL_TIME representation to its my_time_t representation. SYNOPSIS TIME_to_gmt_sec() - t - pointer to TIME structure with local time + t - pointer to MYSQL_TIME structure with local time in broken-down representation. in_dst_time_gap - pointer to bool which should be set to true if datetime value passed doesn't really exist @@ -1352,7 +1352,7 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg): Corresponding my_time_t value or 0 in case of error */ my_time_t -Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const +Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const { my_time_t local_t; int shift= 0; @@ -1397,11 +1397,11 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const SYNOPSIS gmt_sec_to_TIME() - tmp - pointer to TIME structure to fill-in + tmp - pointer to MYSQL_TIME structure to fill-in t - my_time_t value to be converted */ void -Time_zone_offset::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const +Time_zone_offset::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { sec_to_TIME(tmp, t, offset); } @@ -1505,26 +1505,20 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, /* - Prepare table list with time zone related tables from preallocated array - and add to global table list. + Prepare table list with time zone related tables from preallocated array. SYNOPSIS tz_init_table_list() tz_tabs - pointer to preallocated array of MY_TZ_TABLES_COUNT TABLE_LIST objects - global_next_ptr - pointer to variable which points to global_next member - of last element of global table list (or list root - then list is empty) (in/out). DESCRIPTION This function prepares list of TABLE_LIST objects which can be used - for opening of time zone tables from preallocated array. It also links - this list to the end of global table list (it will read and update - accordingly variable pointed by global_next_ptr for this). + for opening of time zone tables from preallocated array. */ static void -tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr) +tz_init_table_list(TABLE_LIST *tz_tabs) { bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT); @@ -1541,64 +1535,6 @@ tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr) if (i != 0) tz_tabs[i].prev_global= &tz_tabs[i-1].next_global; } - - /* Link into global list */ - tz_tabs[0].prev_global= *global_next_ptr; - **global_next_ptr= tz_tabs; - /* Update last-global-pointer to point to pointer in last table */ - *global_next_ptr= &tz_tabs[MY_TZ_TABLES_COUNT-1].next_global; -} - - -/* - Fake table list object, pointer to which is returned by - my_tz_get_tables_list() as indication of error. -*/ -TABLE_LIST fake_time_zone_tables_list; - -/* - Create table list with time zone related tables and add it to the end - of global table list. - - SYNOPSIS - my_tz_get_table_list() - thd - current thread object - global_next_ptr - pointer to variable which points to global_next member - of last element of global table list (or list root - then list is empty) (in/out). - - DESCRIPTION - This function creates list of TABLE_LIST objects allocated in thd's - memroot, which can be used for opening of time zone tables. It will also - link this list to the end of global table list (it will read and update - accordingly variable pointed by global_next_ptr for this). - - NOTE - my_tz_check_n_skip_implicit_tables() function depends on fact that - elements of list created are allocated as TABLE_LIST[MY_TZ_TABLES_COUNT] - array. - - RETURN VALUES - Returns pointer to first TABLE_LIST object, (could be 0 if time zone - tables don't exist) and &fake_time_zone_tables_list in case of error. -*/ - -TABLE_LIST * -my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr) -{ - TABLE_LIST *tz_tabs; - DBUG_ENTER("my_tz_get_table_list"); - - if (!time_zone_tables_exist) - DBUG_RETURN(0); - - if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * - MY_TZ_TABLES_COUNT))) - DBUG_RETURN(&fake_time_zone_tables_list); - - tz_init_table_list(tz_tabs, global_next_ptr); - - DBUG_RETURN(tz_tabs); } @@ -1631,8 +1567,8 @@ my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; - TABLE_LIST *tables= 0; - TABLE_LIST tables_buff[1+MY_TZ_TABLES_COUNT], **last_global_next_ptr; + TABLE_LIST tz_tables[1+MY_TZ_TABLES_COUNT]; + Open_tables_state open_tables_state_backup; TABLE *table; Tz_names_entry *tmp_tzname; my_bool return_val= 1; @@ -1694,19 +1630,23 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) */ thd->set_db(db, sizeof(db)-1); - bzero((char*) &tables_buff, sizeof(TABLE_LIST)); - tables_buff[0].alias= tables_buff[0].table_name= + bzero((char*) &tz_tables[0], sizeof(TABLE_LIST)); + tz_tables[0].alias= tz_tables[0].table_name= (char*)"time_zone_leap_second"; - tables_buff[0].lock_type= TL_READ; - tables_buff[0].db= db; + tz_tables[0].table_name_length= 21; + tz_tables[0].db= db; + tz_tables[0].db_length= sizeof(db)-1; + tz_tables[0].lock_type= TL_READ; + + tz_init_table_list(tz_tables+1); + tz_tables[0].next_global= tz_tables[0].next_local= &tz_tables[1]; + tz_tables[1].prev_global= &tz_tables[0].next_global; + /* - Fill TABLE_LIST for the rest of the time zone describing tables - and link it to first one. + We need to open only mysql.time_zone_leap_second, but we try to + open all time zone tables to see if they exist. */ - last_global_next_ptr= &(tables_buff[0].next_global); - tz_init_table_list(tables_buff + 1, &last_global_next_ptr); - - if (simple_open_n_lock_tables(thd, tables_buff)) + if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup)) { sql_print_warning("Can't open and lock time zone table: %s " "trying to live without them", thd->net.last_error); @@ -1714,7 +1654,6 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } - tables= tables_buff + 1; /* Now we are going to load leap seconds descriptions that are shared @@ -1730,7 +1669,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) goto end_with_close; } - table= tables_buff[0].table; + table= tz_tables[0].table; /* It is OK to ignore ha_index_init()/ha_index_end() return values since mysql.time_zone* tables are MyISAM and these operations always succeed @@ -1787,7 +1726,12 @@ end_with_setting_default_tz: if (default_tzname) { String tmp_tzname2(default_tzname, &my_charset_latin1); - if (!(global_system_variables.time_zone= my_tz_find(&tmp_tzname2, tables))) + /* + Time zone tables may be open here, and my_tz_find() may open + most of them once more, but this is OK for system tables open + for READ. + */ + if (!(global_system_variables.time_zone= my_tz_find(thd, &tmp_tzname2))) { sql_print_error("Fatal error: Illegal or unknown default time zone '%s'", default_tzname); @@ -1796,8 +1740,11 @@ end_with_setting_default_tz: } end_with_close: - thd->version--; /* Force close to free memory */ - close_thread_tables(thd); + if (time_zone_tables_exist) + { + thd->version--; /* Force close to free memory */ + close_system_tables(thd, &open_tables_state_backup); + } end_with_cleanup: @@ -1906,7 +1853,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; tz_tables= tz_tables->next_local; - table->use_all_columns(); table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); /* @@ -1917,9 +1863,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) (void)table->file->ha_index_init(0, 1); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, - 0, HA_READ_KEY_EXACT)) + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { -#ifdef EXTRA_DEBUG +#ifdef EXTRA_DEBUG /* Most probably user has mistyped time zone name, so no need to bark here unless we need it for debugging. @@ -1939,13 +1885,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) using the only index in this table). */ table= tz_tables->table; - table->use_all_columns(); tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0, 1); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, - 0, HA_READ_KEY_EXACT)) + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { sql_print_error("Can't find description of time zone '%u'", tzid); goto end; @@ -1967,14 +1912,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Right - using special index. */ table= tz_tables->table; - table->use_all_columns(); tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0, 1); - // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, - 4, HA_READ_KEY_EXACT); + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttid= (uint)table->field[1]->val_int(); @@ -2041,13 +1984,11 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) in ascending order by index scan also satisfies us. */ table= tz_tables->table; - table->use_all_columns(); table->field[0]->store((longlong) tzid, TRUE); (void)table->file->ha_index_init(0, 1); - // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, - 4, HA_READ_KEY_EXACT); + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttime= (my_time_t)table->field[1]->val_int(); @@ -2251,8 +2192,8 @@ str_to_offset(const char *str, uint length, long *offset) SYNOPSIS my_tz_find() + thd - pointer to thread THD structure name - time zone specification - tz_tables - list of opened'n'locked time zone describing tables DESCRIPTION This function checks if name is one of time zones described in db, @@ -2274,11 +2215,10 @@ str_to_offset(const char *str, uint length, long *offset) values as parameter without additional external check and this property is used by @@time_zone variable handling code). - It will perform lookup in system tables (mysql.time_zone*) if needed - using tz_tables as list of already opened tables (for info about this - list look at tz_load_from_open_tables() description). It won't perform - such lookup if no time zone describing tables were found during server - start up. + It will perform lookup in system tables (mysql.time_zone*), + opening and locking them, and closing afterwards. It won't perform + such lookup if no time zone describing tables were found during + server start up. RETURN VALUE Pointer to corresponding Time_zone object. 0 - in case of bad time zone @@ -2286,7 +2226,7 @@ str_to_offset(const char *str, uint length, long *offset) */ Time_zone * -my_tz_find(const String * name, TABLE_LIST *tz_tables) +my_tz_find(THD *thd, const String *name) { Tz_names_entry *tmp_tzname; Time_zone *result_tz= 0; @@ -2294,8 +2234,6 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) DBUG_ENTER("my_tz_find"); DBUG_PRINT("enter", ("time zone name='%s'", name ? ((String *)name)->c_ptr_safe() : "NULL")); - DBUG_ASSERT(!time_zone_tables_exist || tz_tables || - current_thd->slave_thread); if (!name) DBUG_RETURN(0); @@ -2327,8 +2265,19 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; - else if (time_zone_tables_exist && tz_tables) - result_tz= tz_load_from_open_tables(name, tz_tables); + else if (time_zone_tables_exist) + { + TABLE_LIST tz_tables[MY_TZ_TABLES_COUNT]; + Open_tables_state open_tables_state_backup; + + tz_init_table_list(tz_tables); + if (!open_system_tables_for_read(thd, tz_tables, + &open_tables_state_backup)) + { + result_tz= tz_load_from_open_tables(name, tz_tables); + close_system_tables(thd, &open_tables_state_backup); + } + } } VOID(pthread_mutex_unlock(&tz_LOCK)); @@ -2337,58 +2286,6 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) } -/* - A more standalone version of my_tz_find(): will open tz tables if needed. - This is so far only used by replication, where time zone setting does not - happen in the usual query context. - - SYNOPSIS - my_tz_find_with_opening_tz_tables() - thd - pointer to thread's THD structure - name - time zone specification - - DESCRIPTION - This function tries to find a time zone which matches the named passed in - argument. If it fails, it will open time zone tables and re-try the - search. - This function is needed for the slave SQL thread, which does not do the - addition of time zone tables which is usually done during query parsing - (as time zone setting by slave does not happen in mysql_parse() but - before). So it needs to open tz tables by itself if needed. - See notes of my_tz_find() as they also apply here. - - RETURN VALUE - Pointer to corresponding Time_zone object. 0 - in case of bad time zone - specification or other error. -*/ - -Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name) -{ - Time_zone *tz; - DBUG_ENTER("my_tz_find_with_opening_tables"); - DBUG_ASSERT(thd); - DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only - - if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist) - { - /* - Probably we have not loaded this time zone yet so let us look it up in - our time zone tables. Note that if we don't have tz tables on this - slave, we don't even try. - */ - TABLE_LIST tables[MY_TZ_TABLES_COUNT]; - TABLE_LIST *dummy; - TABLE_LIST **dummyp= &dummy; - tz_init_table_list(tables, &dummyp); - if (simple_open_n_lock_tables(thd, tables)) - DBUG_RETURN(0); - tz= my_tz_find(name, tables); - /* We need to close tables _now_ to not pollute coming query */ - close_thread_tables(thd); - } - DBUG_RETURN(tz); -} - #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */ @@ -2667,7 +2564,7 @@ main(int argc, char **argv) my_bool localtime_negative; TIME_ZONE_INFO tz_info; struct tm tmp; - TIME time_tmp; + MYSQL_TIME time_tmp; time_t t, t1, t2; char fullname[FN_REFLEN+1]; char *str_end; |