diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result index ccaaee90684..f41adfb8d56 100644 --- a/mysql-test/r/events.result +++ b/mysql-test/r/events.result @@ -204,7 +204,7 @@ event CREATE TABLE `event` ( `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP', `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL default '', `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '', - PRIMARY KEY (`definer`,`db`,`name`) + PRIMARY KEY (`definer`,`db`,`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events' SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. diff --git a/mysql-test/r/events_microsec.result b/mysql-test/r/events_microsec.result new file mode 100644 index 00000000000..e31720d0aaa --- /dev/null +++ b/mysql-test/r/events_microsec.result @@ -0,0 +1,56 @@ +create database if not exists events_test; +use events_test; +CREATE EVENT micro_test ON SCHEDULE EVERY 100 MICROSECOND DO SELECT 1; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +CREATE EVENT micro_test ON SCHEDULE EVERY 100 DAY_MICROSECOND DO SELECT 1; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +CREATE EVENT micro_test ON SCHEDULE EVERY 100 HOUR_MICROSECOND DO SELECT 1; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +CREATE EVENT micro_test ON SCHEDULE EVERY 100 MINUTE_MICROSECOND DO SELECT 1; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +CREATE EVENT micro_test ON SCHEDULE EVERY 100 SECOND_MICROSECOND DO SELECT 1; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +"Now create normal event and change it on SQL level" +CREATE EVENT micro_test2 ON SCHEDULE EVERY 1 MONTH DO SELECT 1; +UPDATE mysql.event SET interval_field='MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2'; +SHOW CREATE EVENT micro_test2; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +SET GLOBAL event_scheduler=0; +"Should not be running:" +SHOW VARIABLES like 'event_scheduler'; +Variable_name Value +event_scheduler OFF +UPDATE mysql.event SET interval_field='DAY_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2'; +SHOW CREATE EVENT micro_test2; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +SET GLOBAL event_scheduler=0; +"Should not be running:" +SHOW VARIABLES like 'event_scheduler'; +Variable_name Value +event_scheduler OFF +UPDATE mysql.event SET interval_field='SECOND_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2'; +SHOW CREATE EVENT micro_test2; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +SET GLOBAL event_scheduler=0; +"Should not be running:" +SHOW VARIABLES like 'event_scheduler'; +Variable_name Value +event_scheduler OFF +UPDATE mysql.event SET interval_field='HOUR_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2'; +SHOW CREATE EVENT micro_test2; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +SET GLOBAL event_scheduler=0; +"Should not be running:" +SHOW VARIABLES like 'event_scheduler'; +Variable_name Value +event_scheduler OFF +UPDATE mysql.event SET interval_field='MINUTE_MICROSECOND' WHERE db=database() AND definer=user() AND name='micro_test2'; +SHOW CREATE EVENT micro_test2; +ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' +SET GLOBAL event_scheduler=0; +"Should not be running:" +SHOW VARIABLES like 'event_scheduler'; +Variable_name Value +event_scheduler OFF +DROP EVENT micro_test2; +drop database events_test; diff --git a/sql/event.cc b/sql/event.cc index 93f7e9c41d0..bfb731e3a7b 100644 --- a/sql/event.cc +++ b/sql/event.cc @@ -438,6 +438,7 @@ common_1_lev_code: case INTERVAL_HOUR_MICROSECOND: case INTERVAL_MINUTE_MICROSECOND: case INTERVAL_SECOND_MICROSECOND: + case INTERVAL_MICROSECOND: my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND"); return 1; break; @@ -494,7 +495,7 @@ evex_open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table) if (table_check_intact(tables.table, EVEX_FIELD_COUNT, event_table_fields, &mysql_event_last_create_time, - ER_EVENT_CANNOT_LOAD_FROM_TABLE)) + ER_CANNOT_LOAD_FROM_TABLE)) { close_thread_tables(thd); DBUG_RETURN(2); @@ -976,7 +977,7 @@ db_find_event(THD *thd, sp_name *name, LEX_STRING *definer, event_timed **ett, */ if ((ret= et->load_from_row(root, table))) { - my_error(ER_EVENT_CANNOT_LOAD_FROM_TABLE, MYF(0)); + my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0)); goto done; } diff --git a/sql/event.h b/sql/event.h index 6df6267abc4..7ecc9d20996 100644 --- a/sql/event.h +++ b/sql/event.h @@ -35,6 +35,7 @@ #define EVEX_BODY_TOO_LONG SP_BODY_TOO_LONG #define EVEX_BAD_PARAMS -21 #define EVEX_NOT_RUNNING -22 +#define EVEX_MICROSECOND_UNSUP -23 #define EVENT_EXEC_NO_MORE (1L << 0) #define EVENT_NOT_USED (1L << 1) diff --git a/sql/event_executor.cc b/sql/event_executor.cc index 9483c2ab165..96144532c37 100644 --- a/sql/event_executor.cc +++ b/sql/event_executor.cc @@ -151,7 +151,7 @@ evex_check_system_tables() else { table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT, mysql_db_table_fields, - &mysql_db_table_last_check,ER_EVENT_CANNOT_LOAD_FROM_TABLE); + &mysql_db_table_last_check,ER_CANNOT_LOAD_FROM_TABLE); close_thread_tables(thd); } @@ -723,6 +723,8 @@ event_executor_worker(void *event_void) sql_print_information("SCHEDULER: COMPILE ERROR for event %s.%s of", event->dbname.str, event->name.str, event->definer.str); + else if (ret == EVEX_MICROSECOND_UNSUP) + sql_print_information("SCHEDULER: MICROSECOND is supported"); } event->spawn_thread_finish(thd); @@ -775,7 +777,7 @@ err_no_thd: RETURNS 0 - OK - -1 - Error + !0 - Error NOTES Reports the error to the console @@ -828,11 +830,17 @@ evex_load_events_from_db(THD *thd) DBUG_PRINT("evex_load_events_from_db", ("Event %s loaded from row. Time to compile", et->name.str)); - if ((ret= et->compile(thd, &evex_mem_root))) - { + switch (ret= et->compile(thd, &evex_mem_root)) { + case EVEX_MICROSECOND_UNSUP: + sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not " + "supported but found in mysql.event"); + goto end; + case EVEX_COMPILE_ERROR: sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load.", et->dbname.str, et->name.str); goto end; + default: + break; } // let's find when to be executed @@ -860,7 +868,8 @@ end: thd->version--; // Force close to free memory close_thread_tables(thd); - sql_print_information("SCHEDULER: Loaded %d event%s", count, (count == 1)?"":"s"); + if (!ret) + sql_print_information("SCHEDULER: Loaded %d event%s", count, (count == 1)?"":"s"); DBUG_PRINT("info", ("Status code %d. Loaded %d event(s)", ret, count)); DBUG_RETURN(ret); diff --git a/sql/event_timed.cc b/sql/event_timed.cc index 6440e221732..4a9aee49df0 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -186,9 +186,10 @@ event_timed::init_execute_at(THD *thd, Item *expr) new_interval what is the interval RETURNS - 0 OK - EVEX_PARSE_ERROR fix_fields failed - EVEX_BAD_PARAMS Interval is not positive + 0 OK + EVEX_PARSE_ERROR fix_fields failed + EVEX_BAD_PARAMS Interval is not positive + EVEX_MICROSECOND_UNSUP Microseconds are not supported. */ int @@ -248,6 +249,7 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval) case INTERVAL_MINUTE_MICROSECOND: // day and hour are 0 case INTERVAL_HOUR_MICROSECOND:// day is anyway 0 case INTERVAL_DAY_MICROSECOND: + DBUG_RETURN(EVEX_MICROSECOND_UNSUP); expression= ((((interval.day*24) + interval.hour)*60+interval.minute)*60 + interval.second) * 1000000L + interval.second_part; break; @@ -258,10 +260,11 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval) expression= interval.minute * 60 + interval.second; break; case INTERVAL_SECOND_MICROSECOND: + DBUG_RETURN(EVEX_MICROSECOND_UNSUP); expression= interval.second * 1000000L + interval.second_part; break; - default: - break; + case INTERVAL_MICROSECOND: + DBUG_RETURN(EVEX_MICROSECOND_UNSUP); } if (interval.neg || expression > EVEX_MAX_INTERVAL_VALUE) DBUG_RETURN(EVEX_BAD_PARAMS); @@ -996,9 +999,10 @@ extern LEX_STRING interval_type_to_name[]; buf String*, should be already allocated. CREATE EVENT goes inside. RETURN VALUE - 0 OK - 1 Error (for now if mysql.event has been tampered and MICROSECONDS - interval or derivative has been put there. + 0 OK + EVEX_MICROSECOND_UNSUP Error (for now if mysql.event has been + tampered and MICROSECONDS interval or + derivative has been put there. */ int @@ -1014,7 +1018,7 @@ event_timed::get_create_event(THD *thd, String *buf) if (expression && event_reconstruct_interval_expression(&expr_buf, interval, expression)) - DBUG_RETURN(1); + DBUG_RETURN(EVEX_MICROSECOND_UNSUP); buf->append(STRING_WITH_LEN("CREATE EVENT ")); append_identifier(thd, buf, dbname.str, dbname.length); @@ -1215,8 +1219,9 @@ event_timed::restore_security_context(THD *thd, Security_context *backup) instead of thd->mem_root RETURN VALUE - 0 success - EVEX_COMPILE_ERROR error during compilation + 0 success + EVEX_COMPILE_ERROR error during compilation + EVEX_MICROSECOND_UNSUP mysql.event was tampered */ int @@ -1238,7 +1243,20 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) *old_collation_connection, *old_character_set_results; + DBUG_ENTER("event_timed::compile"); + show_create.length(0); + + switch (get_create_event(thd, &show_create)) { + case EVEX_MICROSECOND_UNSUP: + sql_print_error("Scheduler"); + DBUG_RETURN(EVEX_MICROSECOND_UNSUP); + case 0: + break; + default: + DBUG_ASSERT(0); + } + old_character_set_client= thd->variables.character_set_client; old_character_set_results= thd->variables.character_set_results; old_collation_connection= thd->variables.collation_connection; @@ -1250,7 +1268,6 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) thd->update_charset(); - DBUG_ENTER("event_timed::compile"); /* Change the memory root for the execution time */ if (mem_root) { @@ -1264,8 +1281,6 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) thd->db= dbname.str; thd->db_length= dbname.length; - get_create_event(thd, &show_create); - thd->query= show_create.c_ptr(); thd->query_length= show_create.length(); DBUG_PRINT("event_timed::compile", ("query:%s",thd->query)); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c8daae724c7..18262cac873 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5781,7 +5781,7 @@ ER_EVENT_NEITHER_M_EXPR_NOR_M_AT eng "No datetime expression provided" ER_COL_COUNT_DOESNT_MATCH_CORRUPTED eng "Column count of mysql.%s is wrong. Expected %d, found %d. Table probably corrupted" -ER_EVENT_CANNOT_LOAD_FROM_TABLE +ER_CANNOT_LOAD_FROM_TABLE eng "Cannot load from mysql.%s. Table probably corrupted. See error log." ER_EVENT_CANNOT_DELETE eng "Failed to delete the event from mysql.event" diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f732a3ecbd6..85e8e10d9e0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3940,7 +3940,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) if (et.load_from_row(thd->mem_root, event_table)) { - my_error(ER_EVENT_CANNOT_LOAD_FROM_TABLE, MYF(0)); + my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0)); DBUG_RETURN(1); } @@ -3968,6 +3968,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) if (event_reconstruct_interval_expression(&show_str, et.interval, et.expression)) DBUG_RETURN(1); + sch_table->field[7]->set_notnull(); sch_table->field[7]->store(show_str.c_ptr(), show_str.length(), scs); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8f39bfd0f9d..f807204a2cd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1419,6 +1419,8 @@ ev_schedule_time: EVERY_SYM expr interval break; case EVEX_BAD_PARAMS: my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0)); + case EVEX_MICROSECOND_UNSUP: + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND"); YYABORT; break; }