diff options
author | unknown <kostja@vajra.(none)> | 2007-04-05 20:47:22 +0400 |
---|---|---|
committer | unknown <kostja@vajra.(none)> | 2007-04-05 20:47:22 +0400 |
commit | ff452d050a78083b878260f8d2393016503ae0cb (patch) | |
tree | 8ca3fb500b914b5ecd4542a6d38a8a4c49bd22c1 | |
parent | a36054f4201568fac1717b451040ffa7925900a2 (diff) | |
download | mariadb-git-ff452d050a78083b878260f8d2393016503ae0cb.tar.gz |
Post-merge and post-review fixes for the patch for
Bug#23631 "Events: SHOW VARIABLES doesn't work when mysql.event
is damaged:
mysql-test/r/events.result:
Update results (a post-merge fix)
mysql-test/r/events_bugs.result:
Update results (a post-merge fix)
mysql-test/r/events_scheduling.result:
Update results (a post-merge fix)
mysql-test/t/events_scheduling.test:
Make sure this test has no races.
sql/event_data_objects.cc:
Manual post-merge fix for the events replication patch.
sql/event_data_objects.h:
A post-merge fix.
sql/event_db_repository.cc:
A post-merge fix.
sql/event_scheduler.cc:
We should drop the event inside ::execute since there we have
the right credentials to do so (otherwise Events::drop_event
returns "access denied" error).
sql/events.cc:
A post-review fix for: rename start_or_stop_event_scheduler
to switch_event_scheduler_state.
sql/events.h:
A post-review fix for: rename start_or_stop_event_scheduler
to switch_event_scheduler_state.
sql/set_var.cc:
A post-review fix for: rename start_or_stop_event_scheduler
to switch_event_scheduler_state.
sql/sql_yacc.yy:
Remove unused declaratoins.
-rw-r--r-- | mysql-test/r/events.result | 16 | ||||
-rw-r--r-- | mysql-test/r/events_bugs.result | 62 | ||||
-rw-r--r-- | mysql-test/r/events_scheduling.result | 50 | ||||
-rw-r--r-- | mysql-test/t/events_scheduling.test | 77 | ||||
-rw-r--r-- | sql/event_data_objects.cc | 72 | ||||
-rw-r--r-- | sql/event_data_objects.h | 2 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 7 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 23 | ||||
-rw-r--r-- | sql/events.cc | 12 | ||||
-rw-r--r-- | sql/events.h | 2 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
12 files changed, 209 insertions, 118 deletions
diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result index 7125b13cb88..0b1cd67f559 100644 --- a/mysql-test/r/events.result +++ b/mysql-test/r/events.result @@ -197,7 +197,7 @@ create event руут21 on schedule every '50:23:59:95' day_second COMMENT 'това е 1 SHOW CREATE EVENT руут21; Event sql_mode time_zone Create Event руут21 SYSTEM CREATE EVENT `руут21` ON SCHEDULE EVERY '51 0:0:35' DAY_SECOND STARTS '#' ON COMPLETION NOT PRESERVE ENABLE COMMENT 'това е 1251 коментар' DO select 1 -insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND"); +insert into mysql.event (db, name, body, definer, interval_value, interval_field, originator) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND", 1); show create event root22; ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' SHOW EVENTS; @@ -231,8 +231,8 @@ Create a test event. Only event metadata is relevant, the actual schedule and body are not. CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing"; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1 Try to alter mysql.event: the server should fail to load event information after mysql.event was tampered with. @@ -241,8 +241,8 @@ works as before ALTER TABLE mysql.event ADD dummy INT; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1 SELECT event_name FROM INFORMATION_SCHEMA.events; event_name intact_check @@ -330,7 +330,7 @@ ERROR HY000: Cannot load from mysql.event. The table is probably corrupted DROP EVENT no_such_event; ERROR HY000: Unknown event 'no_such_event' CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5; -ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 15. The table is probably corrupted +ERROR HY000: Column count of mysql.event is wrong. Expected 18, found 16. The table is probably corrupted ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8; ERROR HY000: Unknown event 'intact_check_1' ALTER EVENT intact_check_1 RENAME TO intact_check_2; @@ -400,7 +400,7 @@ Restore the original table. CREATE TABLE mysql.event like event_like; DROP TABLE event_like; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5; select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event; db name body definer convert_tz(execute_at, 'UTC', 'SYSTEM') on_completion @@ -512,7 +512,7 @@ ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa SHOW EVENTS FROM ``; ERROR 42000: Incorrect database name '' SHOW EVENTS FROM `events\\test`; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator LOCK TABLES mode. diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index ba82a7d7b1b..c4053bcfb47 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -390,30 +390,30 @@ SET TIME_ZONE= '+00:00'; SET TIMESTAMP= UNIX_TIMESTAMP('2005-12-31 23:58:59'); CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost +00:00 RECURRING NULL 1 DAY 2005-12-31 23:58:59 NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost +00:00 RECURRING NULL 1 DAY 2005-12-31 23:58:59 NULL ENABLED 1 SET TIME_ZONE= '-01:00'; ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 00:00:00'; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost -01:00 RECURRING NULL 1 DAY 2000-01-01 00:00:00 NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost -01:00 RECURRING NULL 1 DAY 2000-01-01 00:00:00 NULL ENABLED 1 SET TIME_ZONE= '+02:00'; ALTER EVENT e1 ON SCHEDULE AT '2000-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost +02:00 ONE TIME 2000-01-02 00:00:00 NULL NULL NULL NULL DISABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost +02:00 ONE TIME 2000-01-02 00:00:00 NULL NULL NULL NULL DISABLED 1 SET TIME_ZONE= '-03:00'; ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY ENDS '2030-01-03 00:00:00' ON COMPLETION PRESERVE DISABLE; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 DISABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 DISABLED 1 SET TIME_ZONE= '+04:00'; ALTER EVENT e1 DO SELECT 2; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 ENABLED 1 DROP EVENT e1; SET TIME_ZONE='+05:00'; CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO @@ -427,15 +427,15 @@ SET TIME_ZONE='+00:00'; CREATE EVENT e3 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO SELECT 1; SELECT * FROM INFORMATION_SCHEMA.EVENTS ORDER BY event_name; -EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT -NULL events_test e1 root@localhost +05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:58:59 2005-12-31 23:58:59 NULL -NULL events_test e2 root@localhost -05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:00 2005-12-31 23:59:00 NULL -NULL events_test e3 root@localhost +00:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:01 2005-12-31 23:59:01 NULL +EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR +NULL events_test e1 root@localhost +05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:58:59 2005-12-31 23:58:59 NULL 1 +NULL events_test e2 root@localhost -05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:00 2005-12-31 23:59:00 NULL 1 +NULL events_test e3 root@localhost +00:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:01 2005-12-31 23:59:01 NULL 1 SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED -events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED -events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 +events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 +events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 SHOW CREATE EVENT e1; Event sql_mode time_zone Create Event e1 +05:00 CREATE EVENT `e1` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1 @@ -475,10 +475,10 @@ SELECT 1; Warnings: Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED -events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED -events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 +events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 +events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1 The following should succeed giving a warning. ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE; @@ -511,15 +511,15 @@ CREATE EVENT e8 ON SCHEDULE AT '1999-01-01 00:00:00' DO SELECT 1; SHOW EVENTS; -Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status -events_test e1 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED -events_test e2 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED -events_test e3 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED -events_test e4 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED -events_test e5 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED -events_test e6 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED -events_test e7 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED -events_test e8 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +events_test e1 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1 +events_test e2 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1 +events_test e3 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1 +events_test e4 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1 +events_test e5 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1 +events_test e6 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1 +events_test e7 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1 +events_test e8 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1 DROP EVENT e8; DROP EVENT e7; DROP EVENT e6; diff --git a/mysql-test/r/events_scheduling.result b/mysql-test/r/events_scheduling.result index 33c0781d4e7..d45bffcd7ff 100644 --- a/mysql-test/r/events_scheduling.result +++ b/mysql-test/r/events_scheduling.result @@ -44,44 +44,56 @@ 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; -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 +CREATE EVENT event_1 ON SCHEDULE EVERY 2 SECOND +DO +INSERT INTO table_1 VALUES (1); +CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 6 SECOND ON COMPLETION PRESERVE -DO INSERT INTO table_2 VALUES(1); -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); +DO +INSERT INTO table_2 VALUES (1); +CREATE EVENT event_3 ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND +ON COMPLETION NOT PRESERVE +DO +INSERT INTO table_3 VALUES (1); +CREATE EVENT event_4 ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND +ON COMPLETION PRESERVE +DO +INSERT INTO table_4 VALUES (1); SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1; IF(SUM(a) >= 4, 'OK', 'ERROR') OK SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2; IF(SUM(a) >= 5, 'OK', 'ERROR') OK -SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3; -IF(SUM(a) > 0, 'OK', 'ERROR') +SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_3; +IF(SUM(a) >= 1, 'OK', 'ERROR') OK -SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4; -IF(SUM(a) > 0, 'OK', 'ERROR') +SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_4; +IF(SUM(a) >= 1, 'OK', 'ERROR') OK -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(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') +FROM INFORMATION_SCHEMA.EVENTS +WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2'; IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') OK -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; +SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') +FROM INFORMATION_SCHEMA.EVENTS +WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2'; IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') OK -DROP EVENT IF EXISTS events_test.start_n_end; "Already dropped because ended. Therefore an error." -DROP EVENT only_one_time; -ERROR HY000: Unknown event 'only_one_time' +DROP EVENT event_3; +ERROR HY000: Unknown event 'event_3' +DROP EVENT event_1; "Should be preserved" SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME; EVENT_NAME STATUS -two_time DISABLED -DROP EVENT two_time; +event_2 DISABLED +event_4 DISABLED +DROP EVENT event_2; +DROP EVENT event_4; DROP TABLE table_1; DROP TABLE table_2; DROP TABLE table_3; diff --git a/mysql-test/t/events_scheduling.test b/mysql-test/t/events_scheduling.test index b53a548b6ed..5b839e25910 100644 --- a/mysql-test/t/events_scheduling.test +++ b/mysql-test/t/events_scheduling.test @@ -34,34 +34,73 @@ 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 +CREATE EVENT event_1 ON SCHEDULE EVERY 2 SECOND +DO + INSERT INTO table_1 VALUES (1); + +CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND +ENDS NOW() + INTERVAL 6 SECOND +ON COMPLETION PRESERVE +DO + INSERT INTO table_2 VALUES (1); + +CREATE EVENT event_3 ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND +ON COMPLETION NOT PRESERVE +DO + INSERT INTO table_3 VALUES (1); + +CREATE EVENT event_4 ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND +ON COMPLETION PRESERVE +DO + INSERT INTO table_4 VALUES (1); + +# Let event_1 insert at least 4 records into the table +let $wait_condition=select count(*) >= 4 from table_1; +--source include/wait_condition.inc + +# Let event_2 reach the end of its execution interval +let $wait_condition=select count(*) = 0 from information_schema.events +where event_name='event_2' and status='enabled'; +--source include/wait_condition.inc + +# Let event_3, which is ON COMPLETION NOT PRESERVE execute and drop itself +let $wait_condition=select count(*) = 0 from information_schema.events +where event_name='event_3'; +--source include/wait_condition.inc + +# Let event_4 reach the end of its execution interval +let $wait_condition=select count(*) = 0 from information_schema.events +where event_name='event_4' and status='enabled'; +--source include/wait_condition.inc + +# check the data + 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 IF EXISTS events_test.start_n_end; +SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_3; +SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_4; + +SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') +FROM INFORMATION_SCHEMA.EVENTS +WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2'; + +SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') +FROM INFORMATION_SCHEMA.EVENTS +WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2'; + --echo "Already dropped because ended. Therefore an error." --error ER_EVENT_DOES_NOT_EXIST -DROP EVENT only_one_time; +DROP EVENT event_3; + +DROP EVENT event_1; --echo "Should be preserved" SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME; -DROP EVENT two_time; +DROP EVENT event_2; +DROP EVENT event_4; DROP TABLE table_1; DROP TABLE table_2; DROP TABLE table_3; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 95bfba548de..1881a3540e4 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -99,7 +99,9 @@ Event_parse_data::new_instance(THD *thd) */ Event_parse_data::Event_parse_data() - :on_completion(ON_COMPLETION_DROP), status(ENABLED), do_not_create(FALSE), + :on_completion(Event_basic::ON_COMPLETION_DROP), + status(Event_basic::ENABLED), + do_not_create(FALSE), item_starts(NULL), item_ends(NULL), item_execute_at(NULL), starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE), item_expression(NULL), expression(0) @@ -241,7 +243,7 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc) if (ltime_utc >= (my_time_t) thd->query_start()) return; - if (on_completion == ON_COMPLETION_DROP) + if (on_completion == Event_basic::ON_COMPLETION_DROP) { switch (thd->lex->sql_command) { case SQLCOM_CREATE_EVENT: @@ -258,9 +260,9 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc) do_not_create= TRUE; } - else if (status == ENABLED) + else if (status == Event_basic::ENABLED) { - status= DISABLED; + status= Event_basic::DISABLED; push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_EVENT_EXEC_TIME_IN_THE_PAST, ER(ER_EVENT_EXEC_TIME_IN_THE_PAST)); @@ -589,6 +591,7 @@ Event_parse_data::check_parse_data(THD *thd) ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) || init_ends(thd); + check_originator_id(thd); DBUG_RETURN(ret); } @@ -635,6 +638,31 @@ Event_parse_data::init_definer(THD *thd) } +/** + Set the originator id of the event to the server_id if executing on + the master or set to the server_id of the master if executing on + the slave. If executing on slave, also set status to SLAVESIDE_DISABLED. + + SYNOPSIS + Event_parse_data::check_originator_id() +*/ +void Event_parse_data::check_originator_id(THD *thd) +{ + /* Disable replicated events on slave. */ + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) || + (thd->system_thread == SYSTEM_THREAD_SLAVE_IO)) + { + DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED.")); + if ((status == Event_basic::ENABLED) || + (status == Event_basic::DISABLED)) + status = Event_basic::SLAVESIDE_DISABLED; + originator = thd->server_id; + } + else + originator = server_id; +} + + /* Constructor @@ -1004,8 +1032,23 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table) goto error; DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", name.str, ptr)); - status= (ptr[0]=='E'? Event_queue_element::ENABLED: - Event_queue_element::DISABLED); + + /* Set event status (ENABLED | SLAVESIDE_DISABLED | DISABLED) */ + switch (ptr[0]) + { + case 'E' : + status = Event_queue_element::ENABLED; + break; + case 'S' : + status = Event_queue_element::SLAVESIDE_DISABLED; + break; + case 'D' : + status = Event_queue_element::DISABLED; + break; + } + if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS) + goto error; + originator = table->field[ET_FIELD_ORIGINATOR]->val_int(); /* ToDo : Andrey . Find a way not to allocate ptr on event_mem_root */ if ((ptr= get_field(&mem_root, @@ -1356,7 +1399,7 @@ Event_queue_element::compute_next_execution_time() (long) starts, (long) ends, (long) last_executed, (long) this)); - if (status == Event_queue_element::DISABLED) + if (status != Event_queue_element::ENABLED) { DBUG_PRINT("compute_next_execution_time", ("Event %s is DISABLED", name.str)); @@ -1708,6 +1751,8 @@ Event_timed::get_create_event(THD *thd, String *buf) if (status == Event_timed::ENABLED) buf->append(STRING_WITH_LEN("ENABLE")); + else if (status == Event_timed::SLAVESIDE_DISABLED) + buf->append(STRING_WITH_LEN("DISABLE ON SLAVE")); else buf->append(STRING_WITH_LEN("DISABLE")); @@ -1765,7 +1810,7 @@ Event_job_data::get_fake_create_event(String *buf) */ int -Event_job_data::execute(THD *thd) +Event_job_data::execute(THD *thd, bool drop) { Security_context save_ctx; /* this one is local and not needed after exec */ @@ -1805,6 +1850,17 @@ Event_job_data::execute(THD *thd) definer_host.str, dbname.str)); ret= -99; } + if (drop) + { + sql_print_information("Event Scheduler: Dropping %s.%s", + dbname.str, name.str); + /* + We must do it here since here we're under the right authentication + ID of the event definer + */ + if (Events::drop_event(thd, dbname, name, FALSE)) + ret= 1; + } event_restore_security_context(thd, &save_ctx); done: diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 4d58484e5c2..eb851c98065 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -184,7 +184,7 @@ public: load_from_row(THD *thd, TABLE *table); int - execute(THD *thd); + execute(THD *thd, bool drop); int compile(THD *thd, MEM_ROOT *mem_root); diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index cc981c9cb69..fcd48757957 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -905,6 +905,13 @@ update_timing_fields_for_event(THD *thd, DBUG_ENTER("Event_db_repository::update_timing_fields_for_event"); + /* + Turn off row binlogging of event timing updates. These are not used + for RBR of events replicated to the slave. + */ + if (thd->current_stmt_binlog_row_based) + thd->clear_current_stmt_binlog_row_based(); + if (open_event_table(thd, TL_WRITE, &table)) goto end; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index a9a93cbc74b..fa5cde9a43a 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -309,7 +309,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) thd->enable_slow_log= TRUE; - ret= job_data->execute(thd); + ret= job_data->execute(thd, event->dropped); print_warnings(thd, job_data); @@ -338,27 +338,6 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) end: delete job_data; - if (event->dropped) - { - sql_print_information("Event Scheduler: Dropping %s.%s", - event->dbname.str, event->name.str); - /* - Using db_repository can lead to a race condition because we access - the table without holding LOCK_metadata. - Scenario: - 1. CREATE EVENT xyz AT ... (conn thread) - 2. execute xyz (worker) - 3. CREATE EVENT XYZ EVERY ... (conn thread) - 4. drop xyz (worker) - 5. XYZ was just created on disk but `drop xyz` of the worker dropped it. - A consequent load to create Event_queue_element will fail. - - If all operations are performed under LOCK_metadata there is no such - problem. However, this comes at the price of introduction bi-directional - association between class Events and class Event_worker_thread. - */ - Events::drop_event(thd, event->dbname, event->name, FALSE); - } DBUG_PRINT("info", ("Done with Event %s.%s", event->dbname.str, event->name.str)); diff --git a/sql/events.cc b/sql/events.cc index 7c44116af55..10a002121a0 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1041,14 +1041,14 @@ Events::dump_internal_status() */ bool -Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop) +Events::switch_event_scheduler_state(enum_opt_event_scheduler new_state) { bool ret= FALSE; - DBUG_ENTER("Events::start_or_stop_event_scheduler"); + DBUG_ENTER("Events::switch_event_scheduler_state"); - DBUG_ASSERT(start_or_stop == Events::EVENTS_ON || - start_or_stop == Events::EVENTS_OFF); + DBUG_ASSERT(new_state == Events::EVENTS_ON || + new_state == Events::EVENTS_OFF); /* If the scheduler was disabled because there are no/bad @@ -1068,7 +1068,7 @@ Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop) goto end; } - if (start_or_stop == EVENTS_ON) + if (new_state == EVENTS_ON) ret= scheduler->start(); else ret= scheduler->stop(); @@ -1079,7 +1079,7 @@ Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop) goto end; } - opt_event_scheduler= start_or_stop; + opt_event_scheduler= new_state; end: pthread_mutex_unlock(&LOCK_event_metadata); diff --git a/sql/events.h b/sql/events.h index db0e947ab6c..1b99b072fd7 100644 --- a/sql/events.h +++ b/sql/events.h @@ -99,7 +99,7 @@ public: destroy_mutexes(); static bool - start_or_stop_event_scheduler(enum enum_opt_event_scheduler start_or_stop); + switch_event_scheduler_state(enum enum_opt_event_scheduler new_state); static bool create_event(THD *thd, Event_parse_data *parse_data, bool if_exists); diff --git a/sql/set_var.cc b/sql/set_var.cc index 898d47e766e..741969214bd 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -4020,7 +4020,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var) new_state= (enum Events::enum_opt_event_scheduler) var->save_result.ulong_value; - res= Events::start_or_stop_event_scheduler(new_state); + res= Events::switch_event_scheduler_state(new_state); DBUG_RETURN((bool) res); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0c6ce1d7eeb..50bc81cc13d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -948,7 +948,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE -%token SLAVESIDE_DISABLE_SYM %token SMALLINT /* SQL-2003-R */ %token SNAPSHOT_SYM %token SOCKET_SYM @@ -10004,7 +10003,6 @@ keyword_sp: | SIMPLE_SYM {} | SHARE_SYM {} | SHUTDOWN {} - | SLAVESIDE_DISABLE_SYM {} | SNAPSHOT_SYM {} | SOUNDS_SYM {} | SQL_CACHE_SYM {} |