27 #include <my_global.h>
30 #if !defined(TZINFO2SQL) && !defined(TESTTIME)
54 #if defined(TZINFO2SQL) || defined(TESTTIME)
57 #if !defined(DBUG_OFF)
97 #define MY_TZNAME_MAX TZNAME_MAX
100 #define MY_TZNAME_MAX 255
146 #if defined(TZINFO2SQL) || defined(TESTTIME)
174 uchar
buf[
sizeof(
struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
177 MY_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
179 sizeof(
LS_INFO) * TZ_MAX_LEAPS];
190 if (read_from_file < (
int)
sizeof(
struct tzhead))
193 ttisstdcnt= int4net(u.tzhead.tzh_ttisgmtcnt);
194 ttisgmtcnt= int4net(u.tzhead.tzh_ttisstdcnt);
195 sp->leapcnt= int4net(u.tzhead.tzh_leapcnt);
196 sp->timecnt= int4net(u.tzhead.tzh_timecnt);
197 sp->typecnt= int4net(u.tzhead.tzh_typecnt);
198 sp->charcnt= int4net(u.tzhead.tzh_charcnt);
199 p= u.tzhead.tzh_charcnt +
sizeof(u.tzhead.tzh_charcnt);
200 if (sp->leapcnt > TZ_MAX_LEAPS ||
201 sp->typecnt == 0 || sp->typecnt > TZ_MAX_TYPES ||
202 sp->timecnt > TZ_MAX_TIMES ||
203 sp->charcnt > TZ_MAX_CHARS ||
204 (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
205 (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
207 if ((uint)(read_from_file - (p - u.buf)) <
210 sp->typecnt * (4 + 2) +
212 sp->leapcnt * (4 + 4) +
217 if (!(tzinfo_buf= (
char *)alloc_root(storage,
218 ALIGN_SIZE(sp->timecnt *
220 ALIGN_SIZE(sp->timecnt) +
221 ALIGN_SIZE(sp->typecnt *
224 ALIGN_SIZE(sp->charcnt) +
226 sp->leapcnt *
sizeof(
LS_INFO))))
229 sp->ats= (my_time_t *)tzinfo_buf;
230 tzinfo_buf+= ALIGN_SIZE(sp->timecnt *
sizeof(my_time_t));
231 sp->types= (uchar *)tzinfo_buf;
232 tzinfo_buf+= ALIGN_SIZE(sp->timecnt);
236 sp->chars= tzinfo_buf;
237 tzinfo_buf+= ALIGN_SIZE(sp->charcnt);
239 sp->lsis= (
LS_INFO *)tzinfo_buf;
241 for (i= 0; i < sp->timecnt; i++, p+= 4)
242 sp->ats[i]= int4net(p);
244 for (i= 0; i < sp->timecnt; i++)
246 sp->types[
i]= (uchar) *p++;
247 if (sp->types[i] >= sp->typecnt)
250 for (i= 0; i < sp->typecnt; i++)
255 ttisp->tt_gmtoff= int4net(p);
257 ttisp->tt_isdst= (uchar) *p++;
258 if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
260 ttisp->tt_abbrind= (uchar) *p++;
261 if (ttisp->tt_abbrind > sp->charcnt)
264 for (i= 0; i < sp->charcnt; i++)
267 for (i= 0; i < sp->leapcnt; i++)
272 lsisp->ls_trans= int4net(p);
274 lsisp->ls_corr= int4net(p);
283 return prepare_tz_info(sp, storage);
323 my_time_t cur_t= MY_TIME_T_MIN;
324 my_time_t cur_l, end_t, end_l;
325 my_time_t cur_max_seen_l= MY_TIME_T_MIN;
326 long cur_offset, cur_corr, cur_off_and_corr;
327 uint next_trans_idx, next_leap_idx;
334 my_time_t revts[TZ_MAX_REV_RANGES];
345 for (i= 0; i < sp->typecnt && sp->ttis[
i].tt_isdst; i++)
347 if (i == sp->typecnt)
349 sp->fallback_tti= &(sp->ttis[
i]);
358 if (sp->timecnt == 0 || cur_t < sp->ats[0])
373 cur_offset= sp->ttis[
i].tt_gmtoff;
377 for (next_leap_idx= 0; next_leap_idx < sp->leapcnt &&
378 cur_t >= sp->lsis[next_leap_idx].ls_trans;
382 if (next_leap_idx > 0)
383 cur_corr= sp->lsis[next_leap_idx - 1].ls_corr;
388 while (sp->revcnt < TZ_MAX_REV_RANGES - 1)
390 cur_off_and_corr= cur_offset - cur_corr;
396 if (cur_off_and_corr < 0 &&
397 cur_t < MY_TIME_T_MIN - cur_off_and_corr)
398 cur_t= MY_TIME_T_MIN - cur_off_and_corr;
400 cur_l= cur_t + cur_off_and_corr;
406 end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
408 (next_leap_idx < sp->leapcnt) ?
409 sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
414 if (cur_off_and_corr > 0 &&
415 end_t > MY_TIME_T_MAX - cur_off_and_corr)
416 end_t= MY_TIME_T_MAX - cur_off_and_corr;
418 end_l= end_t + cur_off_and_corr;
421 if (end_l > cur_max_seen_l)
424 if (cur_max_seen_l == MY_TIME_T_MIN)
426 revts[sp->revcnt]= cur_l;
427 revtis[sp->revcnt].rt_offset= cur_off_and_corr;
428 revtis[sp->revcnt].rt_type= 0;
430 cur_max_seen_l= end_l;
434 if (cur_l > cur_max_seen_l + 1)
437 revts[sp->revcnt]= cur_max_seen_l + 1;
438 revtis[sp->revcnt].rt_offset= revtis[sp->revcnt-1].rt_offset;
439 revtis[sp->revcnt].rt_type= 1;
441 if (sp->revcnt == TZ_MAX_TIMES + TZ_MAX_LEAPS + 1)
443 cur_max_seen_l= cur_l - 1;
448 revts[sp->revcnt]= cur_max_seen_l + 1;
449 revtis[sp->revcnt].rt_offset= cur_off_and_corr;
450 revtis[sp->revcnt].rt_type= 0;
452 cur_max_seen_l= end_l;
456 if (end_t == MY_TIME_T_MAX ||
457 ((cur_off_and_corr > 0) &&
458 (end_t >= MY_TIME_T_MAX - cur_off_and_corr)))
469 if (sp->timecnt != 0 && cur_t >= sp->ats[0])
470 if (next_trans_idx < sp->timecnt &&
471 cur_t == sp->ats[next_trans_idx])
474 cur_offset= sp->ttis[sp->types[next_trans_idx]].tt_gmtoff;
478 if (next_leap_idx < sp->leapcnt &&
479 cur_t == sp->lsis[next_leap_idx].ls_trans)
482 cur_corr= sp->lsis[next_leap_idx].ls_corr;
488 if (sp->revcnt == TZ_MAX_REV_RANGES - 1)
492 revts[sp->revcnt]= end_l;
495 if (!(sp->revts= (my_time_t *)alloc_root(storage,
496 sizeof(my_time_t) * (sp->revcnt + 1))) ||
497 !(sp->revtis= (
REVT_INFO *)alloc_root(storage,
501 memcpy(sp->revts, revts,
sizeof(my_time_t) * (sp->revcnt + 1));
502 memcpy(sp->revtis, revtis,
sizeof(
REVT_INFO) * sp->revcnt);
508 #if !defined(TZINFO2SQL)
510 static const uint mon_lengths[2][MONS_PER_YEAR]=
512 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
513 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
516 static const uint mon_starts[2][MONS_PER_YEAR]=
518 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
519 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
522 static const uint year_lengths[2]=
524 DAYS_PER_NYEAR, DAYS_PER_LYEAR
527 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
556 days= (long) (t / SECS_PER_DAY);
557 rem= (long) (t % SECS_PER_DAY);
569 while (rem >= SECS_PER_DAY)
574 tmp->hour= (uint)(rem / SECS_PER_HOUR);
575 rem= rem % SECS_PER_HOUR;
576 tmp->minute= (uint)(rem / SECS_PER_MIN);
581 tmp->second= (uint)(rem % SECS_PER_MIN);
584 while (days < 0 || days >= (
long)year_lengths[yleap= isleap(y)])
588 newy= y + days / DAYS_PER_NYEAR;
591 days-= (newy - y) * DAYS_PER_NYEAR +
592 LEAPS_THRU_END_OF(newy - 1) -
593 LEAPS_THRU_END_OF(y - 1);
598 ip= mon_lengths[yleap];
599 for (tmp->month= 0; days >= (
long) ip[tmp->month]; tmp->month++)
600 days= days - (long) ip[tmp->month];
602 tmp->day= (uint)(days + 1);
606 tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
632 find_time_range(my_time_t t,
const my_time_t *range_boundaries,
635 uint
i, lower_bound= 0;
640 DBUG_ASSERT(higher_bound > 0 && t >= range_boundaries[0]);
649 while (higher_bound - lower_bound > 1)
651 i= (lower_bound + higher_bound) >> 1;
652 if (range_boundaries[i] <= t)
676 if (unlikely(sp->timecnt == 0 || t < sp->ats[0]))
682 return sp->fallback_tti;
690 return &(sp->ttis[sp->types[find_time_range(t, sp->ats, sp->timecnt)]]);
730 ttisp= find_transition_type(sec_in_utc, sp);
739 for ( i= sp->leapcnt; i-- > 0; )
742 if (sec_in_utc >= lp->ls_trans)
744 if (sec_in_utc == lp->ls_trans)
746 hit= ((i == 0 && lp->ls_corr > 0) ||
747 lp->ls_corr > sp->lsis[i - 1].ls_corr);
751 sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
752 sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1)
764 sec_to_TIME(tmp, sec_in_utc, ttisp->tt_gmtoff - corr);
788 sec_since_epoch(
int year,
int mon,
int mday,
int hour,
int min ,
int sec)
791 DBUG_ASSERT(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17));
792 #ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES
797 DBUG_ASSERT(mon > 0 && mon < 13);
798 long days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
799 LEAPS_THRU_END_OF(year - 1) -
800 LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
801 days+= mon_starts[isleap(year)][mon - 1];
803 long norm_month= (mon - 1) % MONS_PER_YEAR;
804 long a_year= year + (mon - 1)/MONS_PER_YEAR - (
int)(norm_month < 0);
805 long days= a_year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
806 LEAPS_THRU_END_OF(a_year - 1) -
807 LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
808 days+= mon_starts[isleap(a_year)]
809 [norm_month + (norm_month < 0 ? MONS_PER_YEAR : 0)];
813 return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) *
891 my_bool *in_dst_time_gap)
898 DBUG_ENTER(
"TIME_to_gmt_sec");
900 if (!validate_timestamp_range(t))
905 if (t->second < SECS_PER_MIN)
908 saved_seconds= t->second;
922 if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
933 local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
935 saved_seconds ? 0 : t->second);
938 DBUG_ASSERT(sp->revcnt >= 1);
940 if (local_t < sp->revts[0] || local_t > sp->revts[sp->revcnt])
950 i= find_time_range(local_t, sp->revts, sp->revcnt);
959 if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
960 sp->revtis[i].rt_offset - saved_seconds))
964 local_t+= shift * SECS_PER_DAY;
967 if (sp->revtis[i].rt_type)
976 local_t= sp->revts[
i] - sp->revtis[
i].rt_offset + saved_seconds;
979 local_t= local_t - sp->revtis[
i].rt_offset + saved_seconds;
982 if (local_t < TIMESTAMP_MIN_VALUE)
985 DBUG_RETURN(local_t);
995 #if !defined(TESTTIME) && !defined(TZINFO2SQL)
1000 static const String tz_SYSTEM_name(
"SYSTEM", 6, &my_charset_latin1);
1018 my_bool *in_dst_time_gap)
const;
1053 return my_system_gmt_sec(t, ¬_used, in_dst_time_gap);
1077 time_t tmp_t= (time_t)t;
1079 localtime_r(&tmp_t, &tmp_tm);
1080 localtime_to_TIME(tmp, &tmp_tm);
1081 tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
1098 return &tz_SYSTEM_name;
1113 my_bool *in_dst_time_gap)
const;
1163 time_t tmp_t= (time_t)t;
1164 gmtime_r(&tmp_t, &tmp_tm);
1165 localtime_to_TIME(tmp, &tmp_tm);
1166 tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
1203 my_bool *in_dst_time_gap)
const;
1226 const String *tz_name_arg):
1227 tz_info(tz_info_arg), tz_name(tz_name_arg)
1300 my_bool *in_dst_time_gap)
const;
1310 char name_buff[7+16];
1323 Time_zone_offset::Time_zone_offset(
long tz_offset_arg):
1324 offset(tz_offset_arg)
1326 uint hours= abs((
int)(offset / SECS_PER_HOUR));
1327 uint minutes= abs((
int)(offset % SECS_PER_HOUR / SECS_PER_MIN));
1328 ulong length= my_snprintf(name_buff,
sizeof(name_buff),
"%s%02d:%02d",
1329 (offset>=0) ?
"+" :
"-", hours, minutes);
1330 name.set(name_buff, length, &my_charset_latin1);
1361 if (!validate_timestamp_range(t))
1369 if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
1372 local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
1373 t->hour, t->minute, t->second) -
1379 local_t+= shift * SECS_PER_DAY;
1382 if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
1403 sec_to_TIME(tmp, t, offset);
1431 static HASH tz_names;
1432 static HASH offset_tzs;
1443 static bool tz_inited= 0;
1449 static uint tz_leapcnt= 0;
1457 static bool time_zone_tables_exist= 1;
1465 static const LEX_STRING tz_tables_names[MY_TZ_TABLES_COUNT]=
1467 { C_STRING_WITH_LEN(
"time_zone_name")},
1468 { C_STRING_WITH_LEN(
"time_zone")},
1469 { C_STRING_WITH_LEN(
"time_zone_transition_type")},
1470 { C_STRING_WITH_LEN(
"time_zone_transition")}
1475 static const LEX_STRING tz_tables_db_name= { C_STRING_WITH_LEN(
"mysql")};
1493 my_bool not_used __attribute__((unused)))
1495 *length= entry->name.length();
1496 return (uchar*) entry->name.ptr();
1502 my_bool not_used __attribute__((unused)))
1504 *length=
sizeof(long);
1505 return (uchar*) &entry->offset;
1525 memset(tz_tabs, 0,
sizeof(
TABLE_LIST) * MY_TZ_TABLES_COUNT);
1527 for (
int i= 0; i < MY_TZ_TABLES_COUNT; i++)
1529 tz_tabs[
i].alias= tz_tabs[
i].table_name= tz_tables_names[
i].str;
1530 tz_tabs[
i].table_name_length= tz_tables_names[
i].length;
1531 tz_tabs[
i].db= tz_tables_db_name.str;
1532 tz_tabs[
i].db_length= tz_tables_db_name.length;
1533 tz_tabs[
i].lock_type= TL_READ;
1535 if (i != MY_TZ_TABLES_COUNT - 1)
1536 tz_tabs[
i].next_global= tz_tabs[
i].next_local= &tz_tabs[i+1];
1538 tz_tabs[
i].prev_global= &tz_tabs[i-1].next_global;
1542 #ifdef HAVE_PSI_INTERFACE
1543 static PSI_mutex_key key_tz_LOCK;
1545 static PSI_mutex_info all_tz_mutexes[]=
1547 { & key_tz_LOCK,
"tz_LOCK", PSI_FLAG_GLOBAL}
1550 static void init_tz_psi_keys(
void)
1552 const char* category=
"sql";
1555 count= array_elements(all_tz_mutexes);
1587 my_tz_init(THD *org_thd,
const char *default_tzname, my_bool bootstrap)
1593 my_bool return_val= 1;
1596 DBUG_ENTER(
"my_tz_init");
1598 #ifdef HAVE_PSI_INTERFACE
1605 if (!(thd=
new THD))
1607 thd->thread_stack= (
char*) &thd;
1608 thd->store_globals();
1611 if (my_hash_init(&tz_names, &my_charset_latin1, 20,
1612 0, 0, (my_hash_get_key) my_tz_names_get_key, 0, 0))
1614 sql_print_error(
"Fatal error: OOM while initializing time zones");
1617 if (my_hash_init(&offset_tzs, &my_charset_latin1, 26, 0, 0,
1618 (my_hash_get_key)my_offset_tzs_get_key, 0, 0))
1620 sql_print_error(
"Fatal error: OOM while initializing time zones");
1621 my_hash_free(&tz_names);
1624 init_sql_alloc(&tz_storage, 32 * 1024, 0);
1631 sql_print_error(
"Fatal error: OOM while initializing time zones");
1632 goto end_with_cleanup;
1634 tmp_tzname->name.set(STRING_WITH_LEN(
"SYSTEM"), &my_charset_latin1);
1635 tmp_tzname->tz= my_tz_SYSTEM;
1636 if (my_hash_insert(&tz_names, (
const uchar *)tmp_tzname))
1638 sql_print_error(
"Fatal error: OOM while initializing time zones");
1639 goto end_with_cleanup;
1645 return_val= time_zone_tables_exist= 0;
1646 goto end_with_setting_default_tz;
1655 thd->set_db(db,
sizeof(db)-1);
1656 memset(&tz_tables[0], 0,
sizeof(
TABLE_LIST));
1657 tz_tables[0].alias= tz_tables[0].table_name=
1658 (
char*)
"time_zone_leap_second";
1659 tz_tables[0].table_name_length= 21;
1660 tz_tables[0].db= db;
1661 tz_tables[0].db_length=
sizeof(db)-1;
1662 tz_tables[0].lock_type= TL_READ;
1664 tz_init_table_list(tz_tables+1);
1665 tz_tables[0].next_global= tz_tables[0].next_local= &tz_tables[1];
1666 tz_tables[1].prev_global= &tz_tables[0].next_global;
1667 init_mdl_requests(tz_tables);
1674 MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT))
1676 sql_print_warning(
"Can't open and lock time zone table: %s "
1677 "trying to live without them", thd->get_stmt_da()->message());
1679 return_val= time_zone_tables_exist= 0;
1680 goto end_with_setting_default_tz;
1683 for (
TABLE_LIST *tl= tz_tables; tl; tl= tl->next_global)
1685 tl->table->use_all_columns();
1687 tl->table->m_needs_reopen= TRUE;
1696 if (!(tz_lsis= (
LS_INFO*) alloc_root(&tz_storage,
1697 sizeof(
LS_INFO) * TZ_MAX_LEAPS)))
1699 sql_print_error(
"Fatal error: Out of memory while loading "
1700 "mysql.time_zone_leap_second table");
1701 goto end_with_close;
1704 table= tz_tables[0].table;
1707 goto end_with_close;
1708 table->use_all_columns();
1716 if (tz_leapcnt + 1 > TZ_MAX_LEAPS)
1718 sql_print_error(
"Fatal error: While loading mysql.time_zone_leap_second"
1719 " table: too much leaps");
1721 goto end_with_close;
1724 tz_lsis[tz_leapcnt].ls_trans= (my_time_t)table->field[0]->val_int();
1725 tz_lsis[tz_leapcnt].ls_corr= (long)table->field[1]->val_int();
1730 (
"time_zone_leap_second table: tz_leapcnt: %u tt_time: %lu offset: %ld",
1731 tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans,
1732 tz_lsis[tz_leapcnt-1].ls_corr));
1739 if (res != HA_ERR_END_OF_FILE)
1741 sql_print_error(
"Fatal error: Error while loading "
1742 "mysql.time_zone_leap_second table");
1743 goto end_with_close;
1753 end_with_setting_default_tz:
1757 String tmp_tzname2(default_tzname, &my_charset_latin1);
1763 if (!(global_system_variables.time_zone= my_tz_find(thd, &tmp_tzname2)))
1765 sql_print_error(
"Fatal error: Illegal or unknown default time zone '%s'",
1772 if (time_zone_tables_exist)
1783 org_thd->store_globals();
1787 my_pthread_setspecific_ptr(THR_THD, 0);
1788 my_pthread_setspecific_ptr(THR_MALLOC, 0);
1791 default_tz= default_tz_name ? global_system_variables.time_zone
1794 DBUG_RETURN(return_val);
1811 my_hash_free(&offset_tzs);
1812 my_hash_free(&tz_names);
1813 free_root(&tz_storage, MYF(0));
1849 char buff[MAX_FIELD_WIDTH];
1850 String abbr(buff,
sizeof(buff), &my_charset_latin1);
1851 char *alloc_buff= NULL;
1852 char *tz_name_buff= NULL;
1857 my_time_t ats[TZ_MAX_TIMES];
1858 uchar types[TZ_MAX_TIMES];
1860 #ifdef ABBR_ARE_USED
1861 char chars[MY_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
1870 DBUG_ENTER(
"tz_load_from_open_tables");
1876 table= tz_tables->table;
1877 tz_tables= tz_tables->next_local;
1878 table->field[0]->store(tz_name->ptr(), tz_name->length(),
1879 &my_charset_latin1);
1885 HA_WHOLE_KEY, HA_READ_KEY_EXACT))
1892 sql_print_error(
"Can't find description of time zone '%.*s'",
1893 tz_name->length(), tz_name->ptr());
1898 tzid= (uint)table->field[1]->val_int();
1907 table= tz_tables->table;
1908 tz_tables= tz_tables->next_local;
1909 table->field[0]->store((longlong) tzid, TRUE);
1914 HA_WHOLE_KEY, HA_READ_KEY_EXACT))
1916 sql_print_error(
"Can't find description of time zone '%u'", tzid);
1921 if (table->field[1]->val_int() == 1)
1923 tmp_tz_info.leapcnt= tz_leapcnt;
1924 tmp_tz_info.lsis= tz_lsis;
1935 table= tz_tables->table;
1936 tz_tables= tz_tables->next_local;
1937 table->field[0]->store((longlong) tzid, TRUE);
1942 (key_part_map)1, HA_READ_KEY_EXACT);
1945 ttid= (uint)table->field[1]->val_int();
1947 if (ttid >= TZ_MAX_TYPES)
1949 sql_print_error(
"Error while loading time zone description from "
1950 "mysql.time_zone_transition_type table: too big "
1951 "transition type id");
1955 ttis[ttid].tt_gmtoff= (long)table->field[2]->val_int();
1956 ttis[ttid].tt_isdst= (table->field[3]->val_int() > 0);
1958 #ifdef ABBR_ARE_USED
1960 table->field[4]->val_str(&abbr, &abbr);
1961 if (tmp_tz_info.charcnt + abbr.length() + 1 >
sizeof(chars))
1963 sql_print_error(
"Error while loading time zone description from "
1964 "mysql.time_zone_transition_type table: not enough "
1965 "room for abbreviations");
1968 ttis[ttid].tt_abbrind= tmp_tz_info.charcnt;
1969 memcpy(chars + tmp_tz_info.charcnt, abbr.ptr(), abbr.length());
1970 tmp_tz_info.charcnt+= abbr.length();
1971 chars[tmp_tz_info.charcnt]= 0;
1972 tmp_tz_info.charcnt++;
1975 (
"time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld "
1976 "abbr='%s' tt_isdst=%u", tzid, ttid, ttis[ttid].tt_gmtoff,
1977 chars + ttis[ttid].tt_abbrind, ttis[ttid].tt_isdst));
1980 (
"time_zone_transition_type table: tz_id=%u tt_id=%u tt_gmtoff=%ld "
1981 "tt_isdst=%u", tzid, ttid, ttis[ttid].tt_gmtoff, ttis[ttid].tt_isdst));
1985 DBUG_ASSERT(ttid >= tmp_tz_info.typecnt);
1987 tmp_tz_info.typecnt= ttid + 1;
1990 table->field[0]->ptr, 4);
1993 if (res != HA_ERR_END_OF_FILE)
1995 sql_print_error(
"Error while loading time zone description from "
1996 "mysql.time_zone_transition_type table");
2008 table= tz_tables->table;
2009 table->field[0]->store((longlong) tzid, TRUE);
2014 (key_part_map)1, HA_READ_KEY_EXACT);
2017 ttime= (my_time_t)table->field[1]->val_int();
2018 ttid= (uint)table->field[2]->val_int();
2020 if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES)
2022 sql_print_error(
"Error while loading time zone description from "
2023 "mysql.time_zone_transition table: "
2024 "too much transitions");
2027 if (ttid + 1 > tmp_tz_info.typecnt)
2029 sql_print_error(
"Error while loading time zone description from "
2030 "mysql.time_zone_transition table: "
2031 "bad transition type id");
2035 ats[tmp_tz_info.timecnt]= ttime;
2036 types[tmp_tz_info.timecnt]= ttid;
2037 tmp_tz_info.timecnt++;
2040 (
"time_zone_transition table: tz_id: %u tt_time: %lu tt_id: %u",
2041 tzid, (ulong) ttime, ttid));
2044 table->field[0]->ptr, 4);
2051 if (res != HA_ERR_END_OF_FILE && res != HA_ERR_KEY_NOT_FOUND)
2053 sql_print_error(
"Error while loading time zone description from "
2054 "mysql.time_zone_transition table");
2065 if (tmp_tz_info.typecnt < 1)
2067 sql_print_error(
"loading time zone without transition types");
2072 if (!(alloc_buff= (
char*) alloc_root(&tz_storage,
sizeof(
TIME_ZONE_INFO) +
2073 tz_name->length() + 1)))
2075 sql_print_error(
"Out of memory while loading time zone description");
2087 strmake(tz_name_buff, tz_name->ptr(), tz_name->length());
2092 if (!(alloc_buff= (
char*) alloc_root(&tz_storage,
2093 ALIGN_SIZE(
sizeof(my_time_t) *
2095 ALIGN_SIZE(tz_info->timecnt) +
2096 #ifdef ABBR_ARE_USED
2097 ALIGN_SIZE(tz_info->charcnt) +
2102 sql_print_error(
"Out of memory while loading time zone description");
2106 tz_info->ats= (my_time_t *) alloc_buff;
2107 memcpy(tz_info->ats, ats, tz_info->timecnt *
sizeof(my_time_t));
2108 alloc_buff+= ALIGN_SIZE(
sizeof(my_time_t) * tz_info->timecnt);
2109 tz_info->types= (uchar *)alloc_buff;
2110 memcpy(tz_info->types, types, tz_info->timecnt);
2111 alloc_buff+= ALIGN_SIZE(tz_info->timecnt);
2112 #ifdef ABBR_ARE_USED
2113 tz_info->chars= alloc_buff;
2114 memcpy(tz_info->chars, chars, tz_info->charcnt);
2115 alloc_buff+= ALIGN_SIZE(tz_info->charcnt);
2118 memcpy(tz_info->ttis, ttis, tz_info->typecnt *
sizeof(
TRAN_TYPE_INFO));
2121 if (prepare_tz_info(tz_info, &tz_storage))
2123 sql_print_error(
"Unable to build mktime map for time zone");
2129 !(tmp_tzname->tz= new (&tz_storage)
Time_zone_db(tz_info,
2130 &(tmp_tzname->name))) ||
2131 (tmp_tzname->name.set(tz_name_buff, tz_name->length(),
2132 &my_charset_latin1),
2133 my_hash_insert(&tz_names, (
const uchar *)tmp_tzname)))
2135 sql_print_error(
"Out of memory while loading time zone");
2142 return_val= tmp_tzname->tz;
2146 if (table && table->file->inited)
2149 DBUG_RETURN(return_val);
2172 str_to_offset(
const char *str, uint length,
long *offset)
2174 const char *end= str + length;
2184 else if (*str ==
'-')
2192 while (str < end && my_isdigit(&my_charset_latin1, *str))
2194 number_tmp= number_tmp*10 + *str -
'0';
2198 if (str + 1 >= end || *str !=
':')
2202 offset_tmp = number_tmp * MINS_PER_HOUR; number_tmp= 0;
2204 while (str < end && my_isdigit(&my_charset_latin1, *str))
2206 number_tmp= number_tmp * 10 + *str -
'0';
2213 offset_tmp= (offset_tmp + number_tmp) * SECS_PER_MIN;
2216 offset_tmp= -offset_tmp;
2223 if (number_tmp > 59 || offset_tmp < -13 * SECS_PER_HOUR + 1 ||
2224 offset_tmp > 13 * SECS_PER_HOUR)
2227 *offset= offset_tmp;
2272 my_tz_find(THD *thd,
const String *name)
2277 DBUG_ENTER(
"my_tz_find");
2278 DBUG_PRINT(
"enter", (
"time zone name='%s'",
2279 name ? ((
String *)name)->c_ptr_safe() :
"NULL"));
2281 if (!name || name->is_empty())
2286 if (!str_to_offset(name->ptr(), name->length(), &
offset))
2290 (
const uchar *)&offset,
2293 DBUG_PRINT(
"info", (
"Creating new Time_zone_offset object"));
2296 my_hash_insert(&offset_tzs, (
const uchar *) result_tz))
2299 sql_print_error(
"Fatal error: Out of memory "
2300 "while setting new time zone");
2311 result_tz= tmp_tzname->tz;
2312 else if (time_zone_tables_exist)
2315 Open_tables_backup open_tables_state_backup;
2317 tz_init_table_list(tz_tables);
2318 init_mdl_requests(tz_tables);
2319 DEBUG_SYNC(thd,
"my_tz_find");
2320 if (!open_system_tables_for_read(thd, tz_tables,
2321 &open_tables_state_backup))
2323 result_tz= tz_load_from_open_tables(name, tz_tables);
2324 close_system_tables(thd, &open_tables_state_backup);
2331 DBUG_RETURN(result_tz);
2349 if (t->second == 60 || t->second == 61)
2379 printf(
"INSERT INTO time_zone (Use_leap_seconds) VALUES ('%s');\n",
2380 sp->leapcnt ?
"Y" :
"N");
2381 printf(
"SET @time_zone_id= LAST_INSERT_ID();\n");
2382 printf(
"INSERT INTO time_zone_name (Name, Time_zone_id) VALUES \
2383 ('%s', @time_zone_id);\n", tz_name);
2387 printf(
"INSERT INTO time_zone_transition \
2388 (Time_zone_id, Transition_time, Transition_type_id) VALUES\n");
2389 for (i= 0; i < sp->timecnt; i++)
2390 printf(
"%s(@time_zone_id, %ld, %u)\n", (i == 0 ?
" " :
","), sp->ats[i],
2391 (uint)sp->types[i]);
2395 printf(
"INSERT INTO time_zone_transition_type \
2396 (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES\n");
2398 for (i= 0; i < sp->typecnt; i++)
2399 printf(
"%s(@time_zone_id, %u, %ld, %d, '%s')\n", (i == 0 ?
" " :
","), i,
2400 sp->ttis[i].tt_gmtoff, sp->ttis[i].tt_isdst,
2401 sp->chars + sp->ttis[i].tt_abbrind);
2423 printf(
"TRUNCATE TABLE time_zone_leap_second;\n");
2427 printf(
"INSERT INTO time_zone_leap_second \
2428 (Transition_time, Correction) VALUES\n");
2429 for (i= 0; i < sp->leapcnt; i++)
2430 printf(
"%s(%ld, %ld)\n", (i == 0 ?
" " :
","),
2431 sp->lsis[i].ls_trans, sp->lsis[i].ls_corr);
2435 printf(
"ALTER TABLE time_zone_leap_second ORDER BY Transition_time;\n");
2445 char fullname[FN_REFLEN + 1];
2446 char *root_name_end;
2471 scan_tz_dir(
char * name_end)
2477 if (!(cur_dir= my_dir(fullname, MYF(MY_WANT_STAT))))
2480 name_end= strmake(name_end,
"/", FN_REFLEN - (name_end - fullname));
2482 for (i= 0; i < cur_dir->number_off_files; i++)
2484 if (cur_dir->dir_entry[i].name[0] !=
'.')
2486 name_end_tmp= strmake(name_end, cur_dir->dir_entry[i].name,
2487 FN_REFLEN - (name_end - fullname));
2489 if (MY_S_ISDIR(cur_dir->dir_entry[i].mystat->st_mode))
2491 if (scan_tz_dir(name_end_tmp))
2497 else if (MY_S_ISREG(cur_dir->dir_entry[i].mystat->st_mode))
2499 init_alloc_root(&tz_storage, 32768, 0);
2500 if (!tz_load(fullname, &tz_info, &tz_storage))
2501 print_tz_as_sql(root_name_end + 1, &tz_info);
2504 "Warning: Unable to load '%s' as time zone. Skipping it.\n",
2506 free_root(&tz_storage, MYF(0));
2509 fprintf(stderr,
"Warning: '%s' is not regular file or directory\n",
2521 main(
int argc,
char **argv)
2525 if (argc != 2 && argc != 3)
2527 fprintf(stderr,
"Usage:\n");
2528 fprintf(stderr,
" %s timezonedir\n", argv[0]);
2529 fprintf(stderr,
" %s timezonefile timezonename\n", argv[0]);
2530 fprintf(stderr,
" %s --leap timezonefile\n", argv[0]);
2536 root_name_end= strmake(fullname, argv[1], FN_REFLEN);
2538 printf(
"TRUNCATE TABLE time_zone;\n");
2539 printf(
"TRUNCATE TABLE time_zone_name;\n");
2540 printf(
"TRUNCATE TABLE time_zone_transition;\n");
2541 printf(
"TRUNCATE TABLE time_zone_transition_type;\n");
2543 if (scan_tz_dir(root_name_end))
2545 fprintf(stderr,
"There were fatal errors during processing "
2546 "of zoneinfo directory\n");
2550 printf(
"ALTER TABLE time_zone_transition "
2551 "ORDER BY Time_zone_id, Transition_time;\n");
2552 printf(
"ALTER TABLE time_zone_transition_type "
2553 "ORDER BY Time_zone_id, Transition_type_id;\n");
2557 init_alloc_root(&tz_storage, 32768, 0);
2559 if (strcmp(argv[1],
"--leap") == 0)
2561 if (tz_load(argv[2], &tz_info, &tz_storage))
2563 fprintf(stderr,
"Problems with zoneinfo file '%s'\n", argv[2]);
2566 print_tz_leaps_as_sql(&tz_info);
2570 if (tz_load(argv[1], &tz_info, &tz_storage))
2572 fprintf(stderr,
"Problems with zoneinfo file '%s'\n", argv[2]);
2575 print_tz_as_sql(argv[2], &tz_info);
2578 free_root(&tz_storage, MYF(0));
2600 #define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
2604 #define TYPE_SIGNED(type) (((type) -1) < 0)
2608 is_equal_TIME_tm(
const TIME* time_arg,
const struct tm * tm_arg)
2610 return (time_arg->year == (uint)tm_arg->tm_year+TM_YEAR_BASE) &&
2611 (time_arg->month == (uint)tm_arg->tm_mon+1) &&
2612 (time_arg->day == (uint)tm_arg->tm_mday) &&
2613 (time_arg->hour == (uint)tm_arg->tm_hour) &&
2614 (time_arg->minute == (uint)tm_arg->tm_min) &&
2615 (time_arg->second == (uint)tm_arg->tm_sec) &&
2616 time_arg->second_part == 0;
2621 main(
int argc,
char **argv)
2623 my_bool localtime_negative;
2628 char fullname[FN_REFLEN+1];
2634 init_alloc_root(&tz_storage, 32768, 0);
2637 setenv(
"TZ",
"MET", 1);
2641 printf(
"time_t: %s %u bit\n", TYPE_SIGNED(time_t) ?
"signed" :
"unsigned",
2642 (uint)TYPE_BIT(time_t));
2643 if (TYPE_SIGNED(time_t))
2646 localtime_negative=
test(localtime_r(&t, &tmp) != 0);
2647 printf(
"localtime_r %s negative params \
2648 (time_t=%d is %d-%d-%d %d:%d:%d)\n",
2649 (localtime_negative ?
"supports" :
"doesn't support"), (
int)t,
2650 TM_YEAR_BASE + tmp.tm_year, tmp.tm_mon + 1, tmp.tm_mday,
2651 tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
2653 printf(
"mktime %s negative results (%d)\n",
2654 (t == mktime(&tmp) ?
"doesn't support" :
"supports"),
2658 tmp.tm_year= 103; tmp.tm_mon= 2; tmp.tm_mday= 30;
2659 tmp.tm_hour= 2; tmp.tm_min= 30; tmp.tm_sec= 0; tmp.tm_isdst= -1;
2661 printf(
"mktime returns %s for spring time gap (%d)\n",
2662 (t != (time_t)-1 ?
"something" :
"error"), (
int)t);
2664 tmp.tm_year= 103; tmp.tm_mon= 8; tmp.tm_mday= 1;
2665 tmp.tm_hour= 0; tmp.tm_min= 0; tmp.tm_sec= 0; tmp.tm_isdst= 0;
2667 printf(
"mktime returns %s for non existing date (%d)\n",
2668 (t != (time_t)-1 ?
"something" :
"error"), (
int)t);
2670 tmp.tm_year= 103; tmp.tm_mon= 8; tmp.tm_mday= 1;
2671 tmp.tm_hour= 25; tmp.tm_min=0; tmp.tm_sec=0; tmp.tm_isdst=1;
2673 printf(
"mktime %s unnormalized input (%d)\n",
2674 (t != (time_t)-1 ?
"handles" :
"doesn't handle"), (
int)t);
2676 tmp.tm_year= 103; tmp.tm_mon= 9; tmp.tm_mday= 26;
2677 tmp.tm_hour= 0; tmp.tm_min= 30; tmp.tm_sec= 0; tmp.tm_isdst= 1;
2679 tmp.tm_hour= 2; tmp.tm_isdst= -1;
2681 tmp.tm_hour= 4; tmp.tm_isdst= 0;
2683 tmp.tm_hour= 2; tmp.tm_isdst= -1;
2685 printf(
"mktime is %s (%d %d)\n",
2686 (t == t1 ?
"determenistic" :
"is non-determenistic"),
2690 str_end= strmake(fullname, TZDIR, FN_REFLEN);
2691 strmake(str_end,
"/MET", FN_REFLEN - (str_end - fullname));
2693 if (tz_load(fullname, &tz_info, &tz_storage))
2695 printf(
"Unable to load time zone info from '%s'\n", fullname);
2696 free_root(&tz_storage, MYF(0));
2700 printf(
"Testing our implementation\n");
2702 if (TYPE_SIGNED(time_t) && localtime_negative)
2704 for (t= -40000; t < 20000; t++)
2706 localtime_r(&t, &tmp);
2707 gmt_sec_to_TIME(&time_tmp, (my_time_t)t, &tz_info);
2708 if (!is_equal_TIME_tm(&time_tmp, &tmp))
2710 printf(
"Problem with negative time_t = %d\n", (
int)t);
2711 free_root(&tz_storage, MYF(0));
2715 printf(
"gmt_sec_to_TIME = localtime for time_t in [-40000,20000) range\n");
2718 for (t= 1000000000; t < 1100000000; t+= 13)
2720 localtime_r(&t,&tmp);
2721 gmt_sec_to_TIME(&time_tmp, (my_time_t)t, &tz_info);
2723 if (!is_equal_TIME_tm(&time_tmp, &tmp))
2725 printf(
"Problem with time_t = %d\n", (
int)t);
2726 free_root(&tz_storage, MYF(0));
2730 printf(
"gmt_sec_to_TIME = localtime for time_t in [1000000000,1100000000) range\n");
2738 for (time_tmp.year= 1980; time_tmp.year < 2010; time_tmp.year++)
2740 for (time_tmp.month= 1; time_tmp.month < 13; time_tmp.month++)
2742 for (time_tmp.day= 1;
2743 time_tmp.day < mon_lengths[isleap(time_tmp.year)][time_tmp.month-1];
2746 for (time_tmp.hour= 0; time_tmp.hour < 24; time_tmp.hour++)
2748 for (time_tmp.minute= 0; time_tmp.minute < 60; time_tmp.minute+= 5)
2750 for (time_tmp.second=0; time_tmp.second<60; time_tmp.second+=25)
2754 t= (time_t)my_system_gmt_sec(&time_tmp, ¬_used, ¬_used_2);
2755 t1= (time_t)TIME_to_gmt_sec(&time_tmp, &tz_info, ¬_used_2);
2763 tmp.tm_year= time_tmp.year - TM_YEAR_BASE;
2764 tmp.tm_mon= time_tmp.month - 1;
2765 tmp.tm_mday= time_tmp.day;
2766 tmp.tm_hour= time_tmp.hour;
2767 tmp.tm_min= time_tmp.minute;
2768 tmp.tm_sec= time_tmp.second;
2776 printf(
"Problem: %u/%u/%u %u:%u:%u with times t=%d, t1=%d\n",
2777 time_tmp.year, time_tmp.month, time_tmp.day,
2778 time_tmp.hour, time_tmp.minute, time_tmp.second,
2781 free_root(&tz_storage, MYF(0));
2791 printf(
"TIME_to_gmt_sec = my_system_gmt_sec for test range\n");
2793 free_root(&tz_storage, MYF(0));