diff options
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index c2143b0d5dd..dc38580f3b6 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1395,44 +1395,72 @@ 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. + Prepare table list with time zone related tables from preallocated array + and add to global table list. SYNOPSIS tz_init_table_list() - tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects. + tz_tabs - pointer to preallocated array of 4 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. + 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). */ -void -tz_init_table_list(TABLE_LIST *tz_tabs) +static void +tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr) { bzero(tz_tabs, sizeof(TABLE_LIST) * 4); tz_tabs[0].alias= tz_tabs[0].real_name= (char*)"time_zone_name"; tz_tabs[1].alias= tz_tabs[1].real_name= (char*)"time_zone"; tz_tabs[2].alias= tz_tabs[2].real_name= (char*)"time_zone_transition_type"; tz_tabs[3].alias= tz_tabs[3].real_name= (char*)"time_zone_transition"; - tz_tabs[0].next= tz_tabs+1; - tz_tabs[1].next= tz_tabs+2; - tz_tabs[2].next= tz_tabs+3; + tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1; + tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2; + tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3; tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type= tz_tabs[3].lock_type= TL_READ; tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql"; + + /* Link into global list */ + tz_tabs[0].prev_global= *global_next_ptr; + tz_tabs[1].prev_global= &tz_tabs[0].next_global; + tz_tabs[2].prev_global= &tz_tabs[1].next_global; + tz_tabs[3].prev_global= &tz_tabs[2].next_global; + + **global_next_ptr= tz_tabs; + /* Update last-global-pointer to point to pointer in last table */ + *global_next_ptr= &tz_tabs[3].next_global; } /* - Create table list with time zone related tables. + 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 + 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. + 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 @@ -1444,19 +1472,20 @@ tz_init_table_list(TABLE_LIST *tz_tabs) */ TABLE_LIST * -my_tz_get_table_list(THD *thd) +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) - return 0; + DBUG_RETURN(0); if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4))) - return &fake_time_zone_tables_list; + DBUG_RETURN(&fake_time_zone_tables_list); - tz_init_table_list(tz_tabs); + tz_init_table_list(tz_tabs, global_next_ptr); - return tz_tabs; + DBUG_RETURN(tz_tabs); } @@ -1490,7 +1519,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; TABLE_LIST *tables= 0; - TABLE_LIST tables_buff[5]; + TABLE_LIST tables_buff[5], **last_global_next_ptr; TABLE *table; TZ_NAMES_ENTRY *tmp_tzname; my_bool return_val= 1; @@ -1557,9 +1586,12 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) (char*)"time_zone_leap_second"; tables_buff[0].lock_type= TL_READ; tables_buff[0].db= thd->db; - tables_buff[0].next= tables_buff + 1; - /* Fill TABLE_LIST for rest of the time zone describing tables */ - tz_init_table_list(tables_buff + 1); + /* + Fill TABLE_LIST for the rest of the time zone describing tables + and link it to first one. + */ + last_global_next_ptr= &(tables_buff[0].next_global); + tz_init_table_list(tables_buff + 1, &last_global_next_ptr); if (open_tables(thd, tables_buff, &counter) || lock_tables(thd, tables_buff, counter)) @@ -1761,8 +1793,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) and it is specifically for this purpose). */ table= tz_tables->table; - tz_tables= tz_tables->next; - table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); + tz_tables= tz_tables->next_local; + table->field[0]->store(tz_name->ptr(), tz_name->length(), + &my_charset_latin1); /* 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 @@ -1773,7 +1806,10 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Can't find description of time zone."); +#ifdef EXTRA_DEBUG + sql_print_error("Can't find description of time zone '%.*s'", tz_name->length(), + tz_name->ptr()); +#endif goto end; } @@ -1787,14 +1823,14 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) using the only index in this table). */ table= tz_tables->table; - tz_tables= tz_tables->next; + tz_tables= tz_tables->next_local; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Can't find description of time zone."); + sql_print_error("Can't find description of time zone '%u'", tzid); goto end; } @@ -1814,7 +1850,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Right - using special index. */ table= tz_tables->table; - tz_tables= tz_tables->next; + tz_tables= tz_tables->next_local; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); |