diff options
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 332 |
1 files changed, 119 insertions, 213 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 73e68ee2b29..c7a4ad049ec 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -106,7 +106,7 @@ typedef struct st_time_zone_info uint revcnt; // Number of transition descr. for TIME->my_time_t conversion /* The following are dynamical arrays are allocated in MEM_ROOT */ my_time_t *ats; // Times of transitions between time types - unsigned char *types; // Local time types for transitions + uchar *types; // Local time types for transitions TRAN_TYPE_INFO *ttis; // Local time types descriptions #ifdef ABBR_ARE_USED /* Storage for local time types abbreviations. They are stored as ASCIIZ */ @@ -153,7 +153,7 @@ static my_bool prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage); static my_bool tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) { - char *p; + uchar *p; int read_from_file; uint i; FILE *file; @@ -164,8 +164,8 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) union { struct tzhead tzhead; - char buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES + - TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES + + uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES + + TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES + #ifdef ABBR_ARE_USED max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) + #endif @@ -189,7 +189,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) sp->timecnt= int4net(u.tzhead.tzh_timecnt); sp->typecnt= int4net(u.tzhead.tzh_typecnt); sp->charcnt= int4net(u.tzhead.tzh_charcnt); - p= u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt; + p= u.tzhead.tzh_charcnt + sizeof(u.tzhead.tzh_charcnt); if (sp->leapcnt > TZ_MAX_LEAPS || sp->typecnt == 0 || sp->typecnt > TZ_MAX_TYPES || sp->timecnt > TZ_MAX_TIMES || @@ -221,7 +221,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) sp->ats= (my_time_t *)tzinfo_buf; tzinfo_buf+= ALIGN_SIZE(sp->timecnt * sizeof(my_time_t)); - sp->types= (unsigned char *)tzinfo_buf; + sp->types= (uchar *)tzinfo_buf; tzinfo_buf+= ALIGN_SIZE(sp->timecnt); sp->ttis= (TRAN_TYPE_INFO *)tzinfo_buf; tzinfo_buf+= ALIGN_SIZE(sp->typecnt * sizeof(TRAN_TYPE_INFO)); @@ -236,7 +236,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) for (i= 0; i < sp->timecnt; i++) { - sp->types[i]= (unsigned char) *p++; + sp->types[i]= (uchar) *p++; if (sp->types[i] >= sp->typecnt) return 1; } @@ -247,10 +247,10 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage) ttisp= &sp->ttis[i]; ttisp->tt_gmtoff= int4net(p); p+= 4; - ttisp->tt_isdst= (unsigned char) *p++; + ttisp->tt_isdst= (uchar) *p++; if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) return 1; - ttisp->tt_abbrind= (unsigned char) *p++; + ttisp->tt_abbrind= (uchar) *p++; if (ttisp->tt_abbrind > sp->charcnt) return 1; } @@ -546,8 +546,8 @@ sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset) int yleap; const uint *ip; - days= t / SECS_PER_DAY; - rem= t % SECS_PER_DAY; + days= (long) (t / SECS_PER_DAY); + rem= (long) (t % SECS_PER_DAY); /* We do this as separate step after dividing t, because this @@ -807,7 +807,6 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) SECS_PER_MIN + sec; } - /* Converts local time in broken down MYSQL_TIME representation to my_time_t representation. @@ -1416,7 +1415,9 @@ Time_zone_offset::get_name() const static Time_zone_utc tz_UTC; static Time_zone_system tz_SYSTEM; +static Time_zone_offset tz_OFFSET0(0); +Time_zone *my_tz_OFFSET0= &tz_OFFSET0; Time_zone *my_tz_UTC= &tz_UTC; Time_zone *my_tz_SYSTEM= &tz_SYSTEM; @@ -1456,15 +1457,15 @@ static bool time_zone_tables_exist= 1; static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]= { - {(char *) STRING_WITH_LEN("time_zone_name")}, - {(char *) STRING_WITH_LEN("time_zone")}, - {(char *) STRING_WITH_LEN("time_zone_transition_type")}, - {(char *) STRING_WITH_LEN("time_zone_transition")} + { C_STRING_WITH_LEN("time_zone_name")}, + { C_STRING_WITH_LEN("time_zone")}, + { C_STRING_WITH_LEN("time_zone_transition_type")}, + { C_STRING_WITH_LEN("time_zone_transition")} }; /* Name of database to which those tables belong. */ -static const LEX_STRING tz_tables_db_name= {(char *) STRING_WITH_LEN("mysql")}; +static const LEX_STRING tz_tables_db_name= { C_STRING_WITH_LEN("mysql")}; class Tz_names_entry: public Sql_alloc @@ -1480,42 +1481,39 @@ public: they should obey C calling conventions. */ -extern "C" byte* my_tz_names_get_key(Tz_names_entry *entry, uint *length, - my_bool not_used __attribute__((unused))) +extern "C" uchar * +my_tz_names_get_key(Tz_names_entry *entry, size_t *length, + my_bool not_used __attribute__((unused))) { *length= entry->name.length(); - return (byte*) entry->name.ptr(); + return (uchar*) entry->name.ptr(); } -extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, - my_bool not_used __attribute__((unused))) +extern "C" uchar * +my_offset_tzs_get_key(Time_zone_offset *entry, + size_t *length, + my_bool not_used __attribute__((unused))) { *length= sizeof(long); - return (byte*) &entry->offset; + return (uchar*) &entry->offset; } /* - 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); @@ -1532,64 +1530,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); } @@ -1622,8 +1562,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; @@ -1638,10 +1578,11 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) DBUG_RETURN(1); thd->thread_stack= (char*) &thd; thd->store_globals(); + lex_start(thd); /* Init all memory structures that require explicit destruction */ if (hash_init(&tz_names, &my_charset_latin1, 20, - 0, 0, (hash_get_key)my_tz_names_get_key, 0, 0)) + 0, 0, (hash_get_key) my_tz_names_get_key, 0, 0)) { sql_print_error("Fatal error: OOM while initializing time zones"); goto end; @@ -1665,7 +1606,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) } tmp_tzname->name.set(STRING_WITH_LEN("SYSTEM"), &my_charset_latin1); tmp_tzname->tz= my_tz_SYSTEM; - if (my_hash_insert(&tz_names, (const byte *)tmp_tzname)) + if (my_hash_insert(&tz_names, (const uchar *)tmp_tzname)) { sql_print_error("Fatal error: OOM while initializing time zones"); goto end_with_cleanup; @@ -1685,27 +1626,30 @@ 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); + "trying to live without them", thd->main_da.message()); /* We will try emulate that everything is ok */ 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 @@ -1721,13 +1665,15 @@ 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 for MyISAM. */ - (void)table->file->ha_index_init(0); + (void)table->file->ha_index_init(0, 1); + table->use_all_columns(); + tz_leapcnt= 0; res= table->file->index_first(table->record[0]); @@ -1748,7 +1694,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) tz_leapcnt++; DBUG_PRINT("info", - ("time_zone_leap_second table: tz_leapcnt: %u tt_time: %lu offset=%ld", + ("time_zone_leap_second table: tz_leapcnt: %u tt_time: %lu offset: %ld", tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans, tz_lsis[tz_leapcnt-1].ls_corr)); @@ -1776,7 +1722,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); @@ -1785,8 +1736,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: @@ -1866,7 +1820,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) TIME_ZONE_INFO structure */ my_time_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; + uchar types[TZ_MAX_TIMES]; TRAN_TYPE_INFO ttis[TZ_MAX_TYPES]; #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; @@ -1880,10 +1834,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) DBUG_ENTER("tz_load_from_open_tables"); - /* Prepare tz_info for loading also let us make copy of time zone name */ - if (!(alloc_buff= alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + - tz_name->length() + 1))) + 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; @@ -1910,12 +1863,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) mysql.time_zone* tables are MyISAM and these operations always succeed for MyISAM. */ - (void)table->file->ha_index_init(0); + (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)) + if (table->file->index_read_map(table->record[0], table->field[0]->ptr, + 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. @@ -1938,10 +1891,10 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0); + (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)) + if (table->file->index_read_map(table->record[0], table->field[0]->ptr, + HA_WHOLE_KEY, HA_READ_KEY_EXACT)) { sql_print_error("Can't find description of time zone '%u'", tzid); goto end; @@ -1965,11 +1918,10 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0); + (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); + res= table->file->index_read_map(table->record[0], table->field[0]->ptr, + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttid= (uint)table->field[1]->val_int(); @@ -2017,7 +1969,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tmp_tz_info.typecnt= ttid + 1; res= table->file->index_next_same(table->record[0], - (byte*)table->field[0]->ptr, 4); + table->field[0]->ptr, 4); } if (res != HA_ERR_END_OF_FILE) @@ -2037,11 +1989,10 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0); + (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); + res= table->file->index_read_map(table->record[0], table->field[0]->ptr, + (key_part_map)1, HA_READ_KEY_EXACT); while (!res) { ttime= (my_time_t)table->field[1]->val_int(); @@ -2067,11 +2018,11 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tmp_tz_info.timecnt++; DBUG_PRINT("info", - ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", - tzid, (ulong) ttime, ttid)); + ("time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u", + tzid, (ulong) ttime, ttid)); res= table->file->index_next_same(table->record[0], - (byte*)table->field[0]->ptr, 4); + table->field[0]->ptr, 4); } /* @@ -2119,24 +2070,24 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) /* Now we will allocate memory and init TIME_ZONE_INFO structure. */ - if (!(alloc_buff= alloc_root(&tz_storage, - ALIGN_SIZE(sizeof(my_time_t) * - tz_info->timecnt) + - ALIGN_SIZE(tz_info->timecnt) + + if (!(alloc_buff= (char*) alloc_root(&tz_storage, + ALIGN_SIZE(sizeof(my_time_t) * + tz_info->timecnt) + + ALIGN_SIZE(tz_info->timecnt) + #ifdef ABBR_ARE_USED - ALIGN_SIZE(tz_info->charcnt) + + ALIGN_SIZE(tz_info->charcnt) + #endif - sizeof(TRAN_TYPE_INFO) * tz_info->typecnt))) + sizeof(TRAN_TYPE_INFO) * + tz_info->typecnt))) { sql_print_error("Out of memory while loading time zone description"); goto end; } - - tz_info->ats= (my_time_t *)alloc_buff; + tz_info->ats= (my_time_t *) alloc_buff; memcpy(tz_info->ats, ats, tz_info->timecnt * sizeof(my_time_t)); alloc_buff+= ALIGN_SIZE(sizeof(my_time_t) * tz_info->timecnt); - tz_info->types= (unsigned char *)alloc_buff; + tz_info->types= (uchar *)alloc_buff; memcpy(tz_info->types, types, tz_info->timecnt); alloc_buff+= ALIGN_SIZE(tz_info->timecnt); #ifdef ABBR_ARE_USED @@ -2160,7 +2111,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) &(tmp_tzname->name))) || (tmp_tzname->name.set(tz_name_buff, tz_name->length(), &my_charset_latin1), - my_hash_insert(&tz_names, (const byte *)tmp_tzname))) + my_hash_insert(&tz_names, (const uchar *)tmp_tzname))) { sql_print_error("Out of memory while loading time zone"); goto end; @@ -2265,8 +2216,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, @@ -2288,11 +2239,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 @@ -2300,17 +2250,14 @@ 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; long offset; - 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); + name ? ((String *)name)->c_ptr_safe() : "NULL")); if (!name) DBUG_RETURN(0); @@ -2321,13 +2268,13 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) { if (!(result_tz= (Time_zone_offset *)hash_search(&offset_tzs, - (const byte *)&offset, + (const uchar *)&offset, sizeof(long)))) { DBUG_PRINT("info", ("Creating new Time_zone_offset object")); if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) || - my_hash_insert(&offset_tzs, (const byte *) result_tz)) + my_hash_insert(&offset_tzs, (const uchar *) result_tz)) { result_tz= 0; sql_print_error("Fatal error: Out of memory " @@ -2339,11 +2286,22 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) { result_tz= 0; if ((tmp_tzname= (Tz_names_entry *)hash_search(&tz_names, - (const byte *)name->ptr(), + (const uchar *)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)); @@ -2352,58 +2310,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); -} - - /** Convert leap seconds into non-leap |