mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
086fba7627
BUG#26429: SHOW CREATE EVENT is incorrect for an event that STARTS NOW() BUG#26431: Impossible to re-create an event from backup if its STARTS clause is in the past WL#3698: Events: execution in local time zone The problem was that local times specified by the user in AT, STARTS and ENDS of CREATE EVENT/ALTER EVENT statement were converted to UTC, and the original time zone was forgotten. This way, event scheduler couldn't honor Daylight Saving Time shifts, and times shown to the user were also in UTC. Additionally, CREATE EVENT didn't allow times in the past, thus preventing straightforward event restoration from old backups. This patch reworks event scheduler time computations, performing them in the time zone associated with the event. Also it allows times to be in the past. The patch adds time_zone column to mysql.event table. NOTE: The patch is almost final, but the bug#9953 should be pushed first. client/mysqldump.c: Before every CREATE EVENT, output its time zone. mysql-test/include/wait_condition.inc: Add optional $wait_timeout parameter. mysql-test/lib/init_db.sql: Add time_zone column. mysql-test/r/events.result: Update result. mysql-test/r/events_bugs.result: Update result. mysql-test/r/events_grant.result: Update result. mysql-test/r/events_restart_phase1.result: Update result. mysql-test/r/events_scheduling.result: Update result. mysql-test/r/mysqldump.result: Update result. mysql-test/r/ps.result: Update result. mysql-test/r/system_mysql_db.result: Update result. mysql-test/t/events.test: Remove STARTS from the result, as it depends on current time. mysql-test/t/events_bugs.test: Time in the past is no longer an error. mysql-test/t/events_restart_phase1.test: Fill new column 'time_zone' in mysql.event. mysql-test/t/events_scheduling.test: Cleanup: disable event scheduler. scripts/mysql_create_system_tables.sh: Add new column 'time_zone' to mysql.event. scripts/mysql_fix_privilege_tables.sql: Add new column 'time_zone' to mysql.event. sql/event_data_objects.cc: The essence of the change is the following: - for internal times use my_time_t instead of TIME. Assignment and comparison is done now on plain numbers. - in init_execute_at(), init_starts(), init_ends() convert given time to number of seconds since Epoch (aka Unix time, in UTC). - handle time_zone field loading and storing. - in get_next_time(), Unix time is converted back to event time zone, interval is added, and the result is converted to UTC again. - fix Event_timed::get_create_event() to report STARTS and ENDS. - before executing the event body we set thread time zone to the event time zone. sql/event_data_objects.h: Add time_zone member to Event_basic class. Store internal times in my_time_t (number of seconds since Epoch), rather than in broken down TIME structure. sql/event_db_repository.cc: Add time_zone column handling. Give a warning and do not create an event if its execution time is in the past, and ON COMPLETION NOT PRESERVE is set, because such an event should be dropped by that time. Also, do not allow ALTER EVENT to set execution time in the past when ON COMPLETION NOT PRESERVE is set. sql/event_db_repository.h: Add enum member for new time zone column. sql/event_queue.cc: Replace handling of broken down times with simple handling of my_time_t. sql/event_queue.h: Store internal times in my_time_t (number of seconds since Epoch), rather than in broken down TIME structure. sql/event_scheduler.cc: Add TODO comment. sql/events.cc: Send time_zone column for SHOW CREATE EVENT. sql/share/errmsg.txt: Update error message, and add two more errors. sql/sql_show.cc: Add TIME_ZONE column to the output of SHOW EVENTS. mysql-test/r/events_time_zone.result: BitKeeper file /home/tomash/src/mysql_ab/mysql-5.1-wl3698/mysql-test/r/events_time_zone.result mysql-test/t/events_time_zone.test: BitKeeper file /home/tomash/src/mysql_ab/mysql-5.1-wl3698/mysql-test/t/events_time_zone.test
66 lines
2.6 KiB
Text
66 lines
2.6 KiB
Text
# Can't test with embedded server that doesn't support grants
|
|
-- source include/not_embedded.inc
|
|
-- source include/not_valgrind.inc
|
|
|
|
CREATE DATABASE IF NOT EXISTS events_test;
|
|
USE events_test;
|
|
|
|
SET GLOBAL event_scheduler=OFF;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
SET GLOBAL event_scheduler=1;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
SET GLOBAL event_scheduler=0;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
SET GLOBAL event_scheduler=ON;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
--error ER_WRONG_VALUE_FOR_VAR
|
|
SET GLOBAL event_scheduler=DISABLED;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
--error ER_WRONG_VALUE_FOR_VAR
|
|
SET GLOBAL event_scheduler=-1;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
--error ER_WRONG_VALUE_FOR_VAR
|
|
SET GLOBAL event_scheduler=2;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
--error ER_WRONG_VALUE_FOR_VAR
|
|
SET GLOBAL event_scheduler=5;
|
|
SHOW VARIABLES LIKE 'event_scheduler';
|
|
|
|
CREATE TABLE table_1(a int);
|
|
CREATE TABLE table_2(a int);
|
|
CREATE TABLE table_3(a int);
|
|
CREATE TABLE table_4(a int);
|
|
CREATE TABLE T19170(s1 TIMESTAMP);
|
|
SET GLOBAL event_scheduler=ON;
|
|
# We need to have 2 to make it safe with valgrind. This is probably because
|
|
# of when we calculate the timestamp value
|
|
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
|
|
CREATE EVENT start_n_end
|
|
ON SCHEDULE EVERY 1 SECOND
|
|
ENDS NOW() + INTERVAL 6 SECOND
|
|
ON COMPLETION PRESERVE
|
|
DO INSERT INTO table_2 VALUES(1);
|
|
--sleep 5
|
|
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
|
|
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND ON COMPLETION PRESERVE DO INSERT INTO table_4 VALUES(1);
|
|
--sleep 5
|
|
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
|
|
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
|
|
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
|
|
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
|
|
DROP EVENT two_sec;
|
|
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
|
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
|
DROP EVENT start_n_end;
|
|
--echo "Already dropped because ended. Therefore an error."
|
|
--error ER_EVENT_DOES_NOT_EXIST
|
|
DROP EVENT only_one_time;
|
|
--echo "Should be preserved"
|
|
SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME;
|
|
DROP EVENT two_time;
|
|
DROP TABLE table_1;
|
|
DROP TABLE table_2;
|
|
DROP TABLE table_3;
|
|
DROP TABLE table_4;
|
|
DROP DATABASE events_test;
|
|
SET GLOBAL event_scheduler=OFF;
|