Loading mysql-test/r/events.result +48 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,54 @@ alter event event3 rename to event2; drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 10 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 1 ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 ALTER EVENT event_starts_test COMMENT "non-empty comment"; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 non-empty comment ALTER EVENT event_starts_test COMMENT ""; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 DROP EVENT event_starts_test; CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 0 ALTER EVENT event_starts_test COMMENT "non-empty comment"; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 0 non-empty comment ALTER EVENT event_starts_test COMMENT ""; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED DROP EVENT event_starts_test; create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; alter event e_43 do alter event e_43 do set @a = 4; Loading mysql-test/t/events.test +32 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,38 @@ drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; # BUG #16537 (Events: mysql.event.starts is null) CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; DROP EVENT event_starts_test; CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; --replace_column 8 # 9 # SHOW EVENTS; DROP EVENT event_starts_test; # # create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; --sleep 2 Loading sql/event.cc +28 −24 Original line number Diff line number Diff line Loading @@ -637,20 +637,6 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) goto trunc_err; } if (et->starts.year) { table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF table->field[EVEX_FIELD_STARTS]-> store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); } if (et->ends.year) { table->field[EVEX_FIELD_ENDS]->set_notnull(); table->field[EVEX_FIELD_ENDS]-> store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); } if (et->expression) { table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull(); Loading @@ -664,18 +650,31 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1); table->field[EVEX_FIELD_EXECUTE_AT]->set_null(); if (!et->starts_null) { table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF table->field[EVEX_FIELD_STARTS]-> store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); } if (!et->ends_null) { table->field[EVEX_FIELD_ENDS]->set_notnull(); table->field[EVEX_FIELD_ENDS]-> store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); } } else if (et->execute_at.year) { // fix_fields already called in init_execute_at table->field[EVEX_FIELD_INTERVAL_EXPR]->set_null(); table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); table->field[EVEX_FIELD_STARTS]->set_null(); table->field[EVEX_FIELD_ENDS]->set_null(); table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull(); table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at, MYSQL_TIMESTAMP_DATETIME); table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); } else { Loading @@ -686,14 +685,17 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) ((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time(); if (et->comment.length) if (table->field[field_num= EVEX_FIELD_COMMENT]-> store(et->comment.str, et->comment.length, system_charset_info)) if (et->comment.str) { if (table->field[field_num= EVEX_FIELD_COMMENT]->store(et->comment.str, et->comment.length, system_charset_info)) goto trunc_err; } DBUG_RETURN(0); trunc_err: my_error(ER_EVENT_DATA_TOO_LONG, MYF(0)); my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), table->field[field_num]->field_name); DBUG_RETURN(EVEX_GENERAL_ERROR); } Loading Loading @@ -807,13 +809,15 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not, goto err; } #ifdef USE_THIS_CODE_AS_TEMPLATE_WHEN_EVENT_REPLICATION_IS_AGREED if (mysql_bin_log.is_open()) { thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache */ // Such a statement can always go directly to binlog, no trans cache thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->query, thd->query_length, FALSE, FALSE); } #endif *rows_affected= 1; ok: Loading sql/event.h +3 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ class event_timed TIME starts; TIME ends; TIME execute_at; my_bool starts_null; my_bool ends_null; my_bool execute_at_null; longlong expression; interval_type interval; Loading sql/event_executor.cc +6 −4 Original line number Diff line number Diff line Loading @@ -523,8 +523,7 @@ event_executor_main(void *arg) et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*); DBUG_PRINT("evex main thread",("got event from the queue")); if (et->execute_at.year > 1969 && my_time_compare(&time_now, &et->execute_at) == -1) if (!et->execute_at_null && my_time_compare(&time_now,&et->execute_at) == -1) { DBUG_PRINT("evex main thread",("still not the time for execution")); VOID(pthread_mutex_unlock(&LOCK_event_arrays)); Loading Loading @@ -571,8 +570,11 @@ event_executor_main(void *arg) #else event_executor_worker((void *) et); #endif if ((et->execute_at.year && !et->expression) || TIME_to_ulonglong_datetime(&et->execute_at) == 0) /* 1. For one-time event : year is > 0 and expression is 0 2. For recurring, expression is != -=> check execute_at_null in this case */ if ((et->execute_at.year && !et->expression) || et->execute_at_null) et->flags |= EVENT_EXEC_NO_MORE; if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED) Loading Loading
mysql-test/r/events.result +48 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,54 @@ alter event event3 rename to event2; drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 10 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 1 ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 ALTER EVENT event_starts_test COMMENT "non-empty comment"; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 non-empty comment ALTER EVENT event_starts_test COMMENT ""; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 1 1 DROP EVENT event_starts_test; CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 0 ALTER EVENT event_starts_test COMMENT "non-empty comment"; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; starts IS NULL ends IS NULL comment 0 0 non-empty comment ALTER EVENT event_starts_test COMMENT ""; SHOW EVENTS; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED DROP EVENT event_starts_test; create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; alter event e_43 do alter event e_43 do set @a = 4; Loading
mysql-test/t/events.test +32 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,38 @@ drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; # BUG #16537 (Events: mysql.event.starts is null) CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; DROP EVENT event_starts_test; CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; --replace_column 8 # 9 # SHOW EVENTS; SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; --replace_column 8 # 9 # SHOW EVENTS; DROP EVENT event_starts_test; # # create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; --sleep 2 Loading
sql/event.cc +28 −24 Original line number Diff line number Diff line Loading @@ -637,20 +637,6 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) goto trunc_err; } if (et->starts.year) { table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF table->field[EVEX_FIELD_STARTS]-> store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); } if (et->ends.year) { table->field[EVEX_FIELD_ENDS]->set_notnull(); table->field[EVEX_FIELD_ENDS]-> store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); } if (et->expression) { table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull(); Loading @@ -664,18 +650,31 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1); table->field[EVEX_FIELD_EXECUTE_AT]->set_null(); if (!et->starts_null) { table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF table->field[EVEX_FIELD_STARTS]-> store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); } if (!et->ends_null) { table->field[EVEX_FIELD_ENDS]->set_notnull(); table->field[EVEX_FIELD_ENDS]-> store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); } } else if (et->execute_at.year) { // fix_fields already called in init_execute_at table->field[EVEX_FIELD_INTERVAL_EXPR]->set_null(); table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); table->field[EVEX_FIELD_STARTS]->set_null(); table->field[EVEX_FIELD_ENDS]->set_null(); table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull(); table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at, MYSQL_TIMESTAMP_DATETIME); table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); } else { Loading @@ -686,14 +685,17 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) ((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time(); if (et->comment.length) if (table->field[field_num= EVEX_FIELD_COMMENT]-> store(et->comment.str, et->comment.length, system_charset_info)) if (et->comment.str) { if (table->field[field_num= EVEX_FIELD_COMMENT]->store(et->comment.str, et->comment.length, system_charset_info)) goto trunc_err; } DBUG_RETURN(0); trunc_err: my_error(ER_EVENT_DATA_TOO_LONG, MYF(0)); my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), table->field[field_num]->field_name); DBUG_RETURN(EVEX_GENERAL_ERROR); } Loading Loading @@ -807,13 +809,15 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not, goto err; } #ifdef USE_THIS_CODE_AS_TEMPLATE_WHEN_EVENT_REPLICATION_IS_AGREED if (mysql_bin_log.is_open()) { thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache */ // Such a statement can always go directly to binlog, no trans cache thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->query, thd->query_length, FALSE, FALSE); } #endif *rows_affected= 1; ok: Loading
sql/event.h +3 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,9 @@ class event_timed TIME starts; TIME ends; TIME execute_at; my_bool starts_null; my_bool ends_null; my_bool execute_at_null; longlong expression; interval_type interval; Loading
sql/event_executor.cc +6 −4 Original line number Diff line number Diff line Loading @@ -523,8 +523,7 @@ event_executor_main(void *arg) et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*); DBUG_PRINT("evex main thread",("got event from the queue")); if (et->execute_at.year > 1969 && my_time_compare(&time_now, &et->execute_at) == -1) if (!et->execute_at_null && my_time_compare(&time_now,&et->execute_at) == -1) { DBUG_PRINT("evex main thread",("still not the time for execution")); VOID(pthread_mutex_unlock(&LOCK_event_arrays)); Loading Loading @@ -571,8 +570,11 @@ event_executor_main(void *arg) #else event_executor_worker((void *) et); #endif if ((et->execute_at.year && !et->expression) || TIME_to_ulonglong_datetime(&et->execute_at) == 0) /* 1. For one-time event : year is > 0 and expression is 0 2. For recurring, expression is != -=> check execute_at_null in this case */ if ((et->execute_at.year && !et->expression) || et->execute_at_null) et->flags |= EVENT_EXEC_NO_MORE; if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED) Loading