MDEV-31684 Add timezone information to DATE_FORMAT

Before starting to go over the format string, prepare the current time
zone information incase '%z' or '%Z' is encountered.
This information can be obtained as given below:

A) If timezone is not set ( meaning we are working with system timezone):
Get the MYSQL_TIME representation for current time and GMT time using
current thread variable for timezone and timezone variable for UTC
respectively. This MYSQL_TIME variable will be used to calculate time
difference. Also convert current time in second to tm structure to
get system timezone information.

B) If timezone is set as offset:
Get timezone information using current timezone information and store
in appropriate variable.

C) If timezone is set as some place (example: Europe/Berlin)
Get timezone information by searching the timezone. During internal
timezone search, information like timeoffset from UTC and abbrevation
is stored in another relevant structure. Hence use the same information.
This commit is contained in:
Rucha Deodhar 2023-08-04 00:28:13 +05:30
parent 5fc19e7137
commit 94eb819296
10 changed files with 292 additions and 59 deletions

View file

@ -555,3 +555,49 @@ time_format('01 02:02:02', '%T')
select time_format('2001-01-01 02:02:02', '%T');
time_format('2001-01-01 02:02:02', '%T')
02:02:02
#
# Beginning of 11.3 test
#
# MDEV-31684: Add timezone information to DATE_FORMAT
#
SET @old_timezone= @@time_zone;
# Using named timezones
SET TIME_ZONE='Japan';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
current_timezone
+0900 JST
SET @@time_zone='Europe/Moscow';
SELECT DATE_FORMAT('1965-02-17 22:23:00', '%z %Z') AS current_timezone;
current_timezone
+0300 MSK
SELECT DATE_FORMAT('1965-12-31 22:23:00', '%z %Z') AS current_timezone;
current_timezone
+0300 MSK
SELECT DATE_FORMAT('1985-06-01', '%z %Z');
DATE_FORMAT('1985-06-01', '%z %Z')
+0400 MSD
# Using positive and negative offset
SET TIME_ZONE= '-05:30';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
current_timezone
-0530 -05:30
SET TIME_ZONE= '+04:30';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
current_timezone
+0430 +04:30
# Using UTC
SET TIME_ZONE='UTC';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
current_timezone
+0000 UTC
# using system time
#
# output depends on system time information. Hence replacing
# to avoid result diff test failures.
#
SET @@time_zone= default;
SELECT DATE_FORMAT('2009-10+|-HH:MM ABC22:23:00', '%z %Z') AS current_timezone;
current_timezone
+|-HH:MM ABC
SET @@time_zone= @old_timezone;
# End of 11.3 test

View file

@ -256,3 +256,51 @@ select time_format('2001-01-01 02:02:02', '%d %T');
select time_format('01 02:02:02', '%d %T');
select time_format('01 02:02:02', '%T');
select time_format('2001-01-01 02:02:02', '%T');
--echo #
--echo # Beginning of 11.3 test
--echo #
--echo # MDEV-31684: Add timezone information to DATE_FORMAT
--echo #
SET @old_timezone= @@time_zone;
--echo # Using named timezones
SET TIME_ZONE='Japan';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
SET @@time_zone='Europe/Moscow';
SELECT DATE_FORMAT('1965-02-17 22:23:00', '%z %Z') AS current_timezone;
SELECT DATE_FORMAT('1965-12-31 22:23:00', '%z %Z') AS current_timezone;
SELECT DATE_FORMAT('1985-06-01', '%z %Z');
--echo # Using positive and negative offset
SET TIME_ZONE= '-05:30';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
SET TIME_ZONE= '+04:30';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
--echo # Using UTC
SET TIME_ZONE='UTC';
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
--echo # using system time
--echo #
--echo # output depends on system time information. Hence replacing
--echo # to avoid result diff test failures.
--echo #
SET @@time_zone= default;
--replace_regex /[+-][0-9]* [A-Z]*/+|-HH:MM ABC/
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%z %Z') AS current_timezone;
SET @@time_zone= @old_timezone;
--echo # End of 11.3 test

View file

@ -3,24 +3,24 @@
@@ -449,9 +449,9 @@
Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3895294076
mysql.time_zone_transition 3719776009
-mysql.plugin 1587119305
+mysql.plugin 2184891911
mysql.servers 2079085450
-mysql.func 3241572444
+mysql.func 310494789
mysql.innodb_table_stats 347867921
mysql.table_stats 664320059
mysql.innodb_table_stats 1285726777
mysql.table_stats 2836905944
# Opps....
@@ -484,9 +484,9 @@
Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3895294076
mysql.time_zone_transition 3719776009
-mysql.plugin 1587119305
+mysql.plugin 2184891911
mysql.servers 2079085450
-mysql.func 3241572444
+mysql.func 310494789
mysql.innodb_table_stats 347867921
mysql.table_stats 664320059
mysql.innodb_table_stats 1285726777
mysql.table_stats 2836905944
DROP FUNCTION IF EXISTS metaphon;

View file

@ -96,29 +96,29 @@ USE mysql;
LOCK TABLES `column_stats` WRITE;
/*!40000 ALTER TABLE `column_stats` DISABLE KEYS */;
REPLACE INTO `column_stats` VALUES
('mysql','tz','Time_zone_id','1','5',0.0000,4.0000,98.2500,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340966921, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"5\", \"size\": 0.002544529, \"ndv\": 1}]}');
('mysql','tz','Time_zone_id','1','6',0.0000,4.0000,78.8000,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340101523, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"6\", \"size\": 0.005076142, \"ndv\": 2}]}');
/*!40000 ALTER TABLE `column_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `index_stats` WRITE;
/*!40000 ALTER TABLE `index_stats` DISABLE KEYS */;
REPLACE INTO `index_stats` VALUES
('mysql','tz','PRIMARY',1,98.2500);
('mysql','tz','PRIMARY',1,78.8000);
/*!40000 ALTER TABLE `index_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `table_stats` WRITE;
/*!40000 ALTER TABLE `table_stats` DISABLE KEYS */;
REPLACE INTO `table_stats` VALUES
('mysql','tz',393);
('mysql','tz',394);
/*!40000 ALTER TABLE `table_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `innodb_index_stats` WRITE;
/*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */;
REPLACE INTO `innodb_index_stats` VALUES
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',4,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',393,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
@ -127,7 +127,7 @@ UNLOCK TABLES;
LOCK TABLES `innodb_table_stats` WRITE;
/*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */;
REPLACE INTO `innodb_table_stats` VALUES
('mysql','tz','2019-12-31 21:00:00',393,1,0);
('mysql','tz','2019-12-31 21:00:00',394,1,0);
/*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */;
UNLOCK TABLES;
@ -140,7 +140,8 @@ REPLACE INTO `time_zone` VALUES
(2,'N'),
(3,'N'),
(4,'Y'),
(5,'N');
(5,'N'),
(6,'Y');
/*!40000 ALTER TABLE `time_zone` ENABLE KEYS */;
UNLOCK TABLES;
@ -148,6 +149,7 @@ LOCK TABLES `time_zone_name` WRITE;
/*!40000 ALTER TABLE `time_zone_name` DISABLE KEYS */;
REPLACE INTO `time_zone_name` VALUES
('Europe/Moscow',3),
('India/Kolkata',6),
('Japan',5),
('leap/Europe/Moscow',4),
('MET',1),
@ -159,6 +161,7 @@ UNLOCK TABLES;
LOCK TABLES `time_zone_leap_second` WRITE;
/*!40000 ALTER TABLE `time_zone_leap_second` DISABLE KEYS */;
REPLACE INTO `time_zone_leap_second` VALUES
(174834660,1),
(78796800,1),
(94694401,2),
(126230402,3),
@ -579,7 +582,8 @@ REPLACE INTO `time_zone_transition` VALUES
(4,2108588422,8),
(4,2121894022,9),
(4,2140038022,8),
(5,-1009875600,1);
(5,-1009875600,1),
(6,174834660,1);
/*!40000 ALTER TABLE `time_zone_transition` ENABLE KEYS */;
UNLOCK TABLES;
@ -616,7 +620,8 @@ REPLACE INTO `time_zone_transition_type` VALUES
(4,10,10800,1,'EEST'),
(4,11,7200,0,'EET'),
(5,0,32400,0,'CJT'),
(5,1,32400,0,'JST');
(5,1,32400,0,'JST'),
(6,1,19800,0,'IST');
/*!40000 ALTER TABLE `time_zone_transition_type` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -710,29 +715,29 @@ USE mysql;
LOCK TABLES `column_stats` WRITE;
/*!40000 ALTER TABLE `column_stats` DISABLE KEYS */;
REPLACE INTO `column_stats` VALUES
('mysql','tz','Time_zone_id','1','5',0.0000,4.0000,98.2500,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340966921, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"5\", \"size\": 0.002544529, \"ndv\": 1}]}');
('mysql','tz','Time_zone_id','1','6',0.0000,4.0000,78.8000,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340101523, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"6\", \"size\": 0.005076142, \"ndv\": 2}]}');
/*!40000 ALTER TABLE `column_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `index_stats` WRITE;
/*!40000 ALTER TABLE `index_stats` DISABLE KEYS */;
REPLACE INTO `index_stats` VALUES
('mysql','tz','PRIMARY',1,98.2500);
('mysql','tz','PRIMARY',1,78.8000);
/*!40000 ALTER TABLE `index_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `table_stats` WRITE;
/*!40000 ALTER TABLE `table_stats` DISABLE KEYS */;
REPLACE INTO `table_stats` VALUES
('mysql','tz',393);
('mysql','tz',394);
/*!40000 ALTER TABLE `table_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `innodb_index_stats` WRITE;
/*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */;
REPLACE INTO `innodb_index_stats` VALUES
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',4,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',393,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
@ -741,7 +746,7 @@ UNLOCK TABLES;
LOCK TABLES `innodb_table_stats` WRITE;
/*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */;
REPLACE INTO `innodb_table_stats` VALUES
('mysql','tz','2019-12-31 21:00:00',393,1,0);
('mysql','tz','2019-12-31 21:00:00',394,1,0);
/*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */;
UNLOCK TABLES;
@ -754,7 +759,8 @@ REPLACE INTO `time_zone` VALUES
(2,'N'),
(3,'N'),
(4,'Y'),
(5,'N');
(5,'N'),
(6,'Y');
/*!40000 ALTER TABLE `time_zone` ENABLE KEYS */;
UNLOCK TABLES;
@ -762,6 +768,7 @@ LOCK TABLES `time_zone_name` WRITE;
/*!40000 ALTER TABLE `time_zone_name` DISABLE KEYS */;
REPLACE INTO `time_zone_name` VALUES
('Europe/Moscow',3),
('India/Kolkata',6),
('Japan',5),
('leap/Europe/Moscow',4),
('MET',1),
@ -773,6 +780,7 @@ UNLOCK TABLES;
LOCK TABLES `time_zone_leap_second` WRITE;
/*!40000 ALTER TABLE `time_zone_leap_second` DISABLE KEYS */;
REPLACE INTO `time_zone_leap_second` VALUES
(174834660,1),
(78796800,1),
(94694401,2),
(126230402,3),
@ -1193,7 +1201,8 @@ REPLACE INTO `time_zone_transition` VALUES
(4,2108588422,8),
(4,2121894022,9),
(4,2140038022,8),
(5,-1009875600,1);
(5,-1009875600,1),
(6,174834660,1);
/*!40000 ALTER TABLE `time_zone_transition` ENABLE KEYS */;
UNLOCK TABLES;
@ -1230,7 +1239,8 @@ REPLACE INTO `time_zone_transition_type` VALUES
(4,10,10800,1,'EEST'),
(4,11,7200,0,'EET'),
(5,0,32400,0,'CJT'),
(5,1,32400,0,'JST');
(5,1,32400,0,'JST'),
(6,1,19800,0,'IST');
/*!40000 ALTER TABLE `time_zone_transition_type` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -1301,29 +1311,29 @@ USE mysql;
LOCK TABLES `column_stats` WRITE;
/*!40000 ALTER TABLE `column_stats` DISABLE KEYS */;
INSERT IGNORE INTO `column_stats` VALUES
('mysql','tz','Time_zone_id','1','5',0.0000,4.0000,98.2500,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340966921, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.328244275, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"5\", \"size\": 0.002544529, \"ndv\": 1}]}');
('mysql','tz','Time_zone_id','1','6',0.0000,4.0000,78.8000,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340101523, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"6\", \"size\": 0.005076142, \"ndv\": 2}]}');
/*!40000 ALTER TABLE `column_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `index_stats` WRITE;
/*!40000 ALTER TABLE `index_stats` DISABLE KEYS */;
INSERT IGNORE INTO `index_stats` VALUES
('mysql','tz','PRIMARY',1,98.2500);
('mysql','tz','PRIMARY',1,78.8000);
/*!40000 ALTER TABLE `index_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `table_stats` WRITE;
/*!40000 ALTER TABLE `table_stats` DISABLE KEYS */;
INSERT IGNORE INTO `table_stats` VALUES
('mysql','tz',393);
('mysql','tz',394);
/*!40000 ALTER TABLE `table_stats` ENABLE KEYS */;
UNLOCK TABLES;
LOCK TABLES `innodb_index_stats` WRITE;
/*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */;
INSERT IGNORE INTO `innodb_index_stats` VALUES
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',4,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',393,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('mysql','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
@ -1332,7 +1342,7 @@ UNLOCK TABLES;
LOCK TABLES `innodb_table_stats` WRITE;
/*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */;
INSERT IGNORE INTO `innodb_table_stats` VALUES
('mysql','tz','2019-12-31 21:00:00',393,1,0);
('mysql','tz','2019-12-31 21:00:00',394,1,0);
/*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */;
UNLOCK TABLES;
@ -1345,7 +1355,8 @@ INSERT IGNORE INTO `time_zone` VALUES
(2,'N'),
(3,'N'),
(4,'Y'),
(5,'N');
(5,'N'),
(6,'Y');
/*!40000 ALTER TABLE `time_zone` ENABLE KEYS */;
UNLOCK TABLES;
@ -1353,6 +1364,7 @@ LOCK TABLES `time_zone_name` WRITE;
/*!40000 ALTER TABLE `time_zone_name` DISABLE KEYS */;
INSERT IGNORE INTO `time_zone_name` VALUES
('Europe/Moscow',3),
('India/Kolkata',6),
('Japan',5),
('leap/Europe/Moscow',4),
('MET',1),
@ -1364,6 +1376,7 @@ UNLOCK TABLES;
LOCK TABLES `time_zone_leap_second` WRITE;
/*!40000 ALTER TABLE `time_zone_leap_second` DISABLE KEYS */;
INSERT IGNORE INTO `time_zone_leap_second` VALUES
(174834660,1),
(78796800,1),
(94694401,2),
(126230402,3),
@ -1784,7 +1797,8 @@ INSERT IGNORE INTO `time_zone_transition` VALUES
(4,2108588422,8),
(4,2121894022,9),
(4,2140038022,8),
(5,-1009875600,1);
(5,-1009875600,1),
(6,174834660,1);
/*!40000 ALTER TABLE `time_zone_transition` ENABLE KEYS */;
UNLOCK TABLES;
@ -1821,7 +1835,8 @@ INSERT IGNORE INTO `time_zone_transition_type` VALUES
(4,10,10800,1,'EEST'),
(4,11,7200,0,'EET'),
(5,0,32400,0,'CJT'),
(5,1,32400,0,'JST');
(5,1,32400,0,'JST'),
(6,1,19800,0,'IST');
/*!40000 ALTER TABLE `time_zone_transition_type` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -1845,12 +1860,12 @@ CHECKSUM TABLE mysql.roles_mapping, mysql.time_zone_transition, mysql.plugin,
mysql.servers, mysql.func, mysql.innodb_table_stats, mysql.table_stats;
Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3895294076
mysql.time_zone_transition 3719776009
mysql.plugin 1587119305
mysql.servers 2079085450
mysql.func 3241572444
mysql.innodb_table_stats 347867921
mysql.table_stats 664320059
mysql.innodb_table_stats 1285726777
mysql.table_stats 2836905944
# Opps....
CREATE USER mariadb_test_restore IDENTIFIED BY 'getitback';
GRANT ALL ON *.* TO mariadb_test_restore WITH GRANT OPTION;
@ -1880,12 +1895,12 @@ CHECKSUM TABLE mysql.roles_mapping, mysql.time_zone_transition, mysql.plugin,
mysql.servers, mysql.func, mysql.innodb_table_stats, mysql.table_stats;
Table Checksum
mysql.roles_mapping 2510045525
mysql.time_zone_transition 3895294076
mysql.time_zone_transition 3719776009
mysql.plugin 1587119305
mysql.servers 2079085450
mysql.func 3241572444
mysql.innodb_table_stats 347867921
mysql.table_stats 664320059
mysql.innodb_table_stats 1285726777
mysql.table_stats 2836905944
DROP FUNCTION IF EXISTS metaphon;
DROP SERVER s1;
DELETE FROM mysql.column_stats WHERE db_name='mysql' and table_name in ('tz', 'gtid_slave_pos');

View file

@ -623,7 +623,7 @@ DATA_LENGTH #DL#
MAX_DATA_LENGTH #MDL#
INDEX_LENGTH #IL#
DATA_FREE #DF#
AUTO_INCREMENT 6
AUTO_INCREMENT 7
CREATE_TIME #CRT#
UPDATE_TIME #UT#
CHECK_TIME #CT#

View file

@ -623,7 +623,7 @@ DATA_LENGTH #DL#
MAX_DATA_LENGTH #MDL#
INDEX_LENGTH #IL#
DATA_FREE #DF#
AUTO_INCREMENT 6
AUTO_INCREMENT 7
CREATE_TIME #CRT#
UPDATE_TIME #UT#
CHECK_TIME #CT#
@ -1412,7 +1412,7 @@ DATA_LENGTH #DL#
MAX_DATA_LENGTH #MDL#
INDEX_LENGTH #IL#
DATA_FREE #DF#
AUTO_INCREMENT 6
AUTO_INCREMENT 7
CREATE_TIME #CRT#
UPDATE_TIME #UT#
CHECK_TIME #CT#

File diff suppressed because one or more lines are too long

View file

@ -473,15 +473,24 @@ err:
Create a formatted date/time value in a string.
*/
static bool make_date_time(const String *format, const MYSQL_TIME *l_time,
timestamp_type type, const MY_LOCALE *locale,
String *str)
static bool make_date_time(THD *thd, const String *format,
const MYSQL_TIME *l_time, timestamp_type type,
const MY_LOCALE *locale, String *str)
{
char intbuff[15];
uint hours_i;
uint weekday;
ulong length;
const char *ptr, *end;
int diff_hr=0, diff_min=0;
char abbrevation[8];
struct tz tmp;
tmp.is_inited= false;
Time_zone* curr_timezone= my_tz_find(thd,
thd->variables.time_zone->get_name());
memset(abbrevation, 0, sizeof(abbrevation));
str->length(0);
@ -699,6 +708,44 @@ static bool make_date_time(const String *format, const MYSQL_TIME *l_time,
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'z':
{
if (!tmp.is_inited)
{
curr_timezone->get_timezone_information(&tmp, l_time);
tmp.is_inited= true;
}
ulonglong seconds= abs(tmp.seconds_offset);
diff_hr= (int)(seconds/3600L);
int temp= (int)(seconds%3600L);
diff_min= temp/60L;
if (tmp.is_behind)
str->append("-", 1);
else
str->append("+", 1);
if (diff_hr/10 == 0)
str->append("0", 1);
length= (uint) (int10_to_str(diff_hr, intbuff, 10) - intbuff);
str->append(intbuff, length);
if (diff_min/10 == 0)
str->append("0", 1);
length= (uint) (int10_to_str(diff_min, intbuff, 10) - intbuff);
str->append(intbuff, length);
}
break;
case 'Z':
{
if (!tmp.is_inited)
{
curr_timezone->get_timezone_information(&tmp, l_time);
tmp.is_inited= true;
}
str->append(tmp.abbrevation, strlen(tmp.abbrevation));
}
break;
default:
str->append(*ptr);
break;
@ -1912,7 +1959,7 @@ String *Item_func_date_format::val_str(String *str)
/* Create the result string */
str->set_charset(collation.collation);
if (!make_date_time(format, &l_time,
if (!make_date_time(thd, format, &l_time,
is_time_format ? MYSQL_TIMESTAMP_TIME :
MYSQL_TIMESTAMP_DATE,
lc, str))

View file

@ -55,15 +55,10 @@
/*
Now we don't use abbreviations in server but we will do this in future.
Edit: Started needing abbrevation in server as part of task MDEV-31684.
*/
#if defined(TZINFO2SQL) || defined(TESTTIME)
#define ABBR_ARE_USED
#else
#if !defined(DBUG_OFF)
/* Let use abbreviations for debug purposes */
#undef ABBR_ARE_USED
#define ABBR_ARE_USED
#endif /* !defined(DBUG_OFF) */
#ifndef ABBR_ARE_USED
#define ABBR_ARE_USED
#endif /* defined(TZINFO2SQL) || defined(TESTTIME) */
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
@ -1031,6 +1026,7 @@ public:
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
virtual void get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const;
};
@ -1097,6 +1093,25 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
adjust_leap_second(tmp);
}
void
Time_zone_system::get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const
{
uint error;
struct tm tm_local_time;
time_t time_sec= this->TIME_to_gmt_sec(local_TIME, &error);
localtime_r(&time_sec, &tm_local_time);
# ifdef __USE_MISC
int len= strlen((tm_local_time.tm_zone));
strmake(curr_tz->abbrevation, tm_local_time.tm_zone, sizeof(tm_local_time.tm_zone)-1);
curr_tz->abbrevation[len]= '\0';
# endif
curr_tz->seconds_offset= tm_local_time.tm_gmtoff;
curr_tz->is_behind= tm_local_time.tm_gmtoff < 0;
}
/*
Get name of time zone
@ -1128,6 +1143,7 @@ public:
uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
virtual void get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const;
};
@ -1175,6 +1191,22 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
adjust_leap_second(tmp);
}
void
Time_zone_utc::get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const
{
uint error;
struct tm tm_local_time;
time_t time_sec= this->TIME_to_gmt_sec(local_TIME, &error);
localtime_r(&time_sec, &tm_local_time);
# ifdef __USE_MISC
strmake(curr_tz->abbrevation, "UTC", 3);
# endif
curr_tz->seconds_offset= tm_local_time.tm_gmtoff;
curr_tz->is_behind= tm_local_time.tm_gmtoff < 0;
}
/*
Get name of time zone
@ -1210,6 +1242,7 @@ public:
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
virtual void get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const;
private:
TIME_ZONE_INFO *tz_info;
const String *tz_name;
@ -1280,6 +1313,24 @@ Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
adjust_leap_second(tmp);
}
void
Time_zone_db::get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const
{
uint error;
my_time_t sec_in_utc;
const TRAN_TYPE_INFO *ttisp;
/* Get seconds since epoch. */
sec_in_utc= this->TIME_to_gmt_sec(local_TIME, &error);
/* Get local timezone information. */
ttisp= find_transition_type(sec_in_utc, tz_info);
curr_tz->seconds_offset= ttisp->tt_gmtoff;
curr_tz->is_behind= tz_info->revtis->rt_offset < 0 ? true : false;
strmake(curr_tz->abbrevation, &(tz_info->chars[ttisp->tt_abbrind]), tz_info->charcnt-1);
}
/*
Get name of time zone
@ -1309,6 +1360,7 @@ public:
uint *error_code) const;
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
virtual const String * get_name() const;
virtual void get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const;
/*
This have to be public because we want to be able to access it from
my_offset_tzs_get_key() function
@ -1434,6 +1486,15 @@ Time_zone_offset::get_name() const
return &name;
}
void
Time_zone_offset::get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const
{
curr_tz->seconds_offset= offset;
const char *name= get_name()->ptr();
curr_tz->is_behind= name[0] == '+' ? false : true;
strmake(curr_tz->abbrevation, name, sizeof(curr_tz->abbrevation)-1);
}
static Time_zone_utc tz_UTC;
static Time_zone_system tz_SYSTEM;
@ -1881,6 +1942,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
*/
TIME_ZONE_INFO tmp_tz_info;
memset(&tmp_tz_info, 0, sizeof(TIME_ZONE_INFO));
memset(ttis, 0, sizeof(ttis));
DBUG_ENTER("tz_load_from_open_tables");

View file

@ -38,6 +38,19 @@ class THD;
Actual time zones which are specified by DB, or via offset
or use system functions are its descendants.
*/
/*
Has only offset from UTC, bool value to denote if it is
ahead (+), behind(-) of UTC and abbrevation.
*/
struct tz
{
long seconds_offset;
bool is_behind;
char abbrevation[8];
bool is_inited;
};
class Time_zone: public Sql_alloc
{
public:
@ -62,6 +75,8 @@ public:
*/
virtual const String * get_name() const = 0;
virtual void get_timezone_information(struct tz* curr_tz, const MYSQL_TIME *local_TIME) const = 0;
/**
We need this only for surpressing warnings, objects of this type are
allocated on MEM_ROOT and should not require destruction.