Commit a2b5573d authored by unknown's avatar unknown

fix for bug #16411 Events: Microsecond intervals are allowed

WL#1034


mysql-test/r/events.result:
  output fix
sql/event.cc:
  - handle also INTERVAL_MICROSECOND, was missing.
  - use renamed ER_ code which is generic
sql/event.h:
  add new error code
sql/event_executor.cc:
  - use new ER_ code name
  - handle EVEX_MICROSECOND_UNSUP error code
sql/event_timed.cc:
  forbid MICROSECOND intervals for events
sql/share/errmsg.txt:
  rename error code, it's generic
sql/sql_show.cc:
  use new error code name
sql/sql_yacc.yy:
  bail out if any MICROSECOND interval is specified
parent cc2030f3
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;
......@@ -438,6 +438,7 @@ event_reconstruct_interval_expression(String *buf,
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;
}
......
......@@ -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)
......
......@@ -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 @@ event_executor_worker(void *event_void)
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,6 +868,7 @@ evex_load_events_from_db(THD *thd)
thd->version--; // Force close to free memory
close_thread_tables(thd);
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));
......
......@@ -189,6 +189,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
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);
......@@ -997,8 +1000,9 @@ extern LEX_STRING interval_type_to_name[];
RETURN VALUE
0 OK
1 Error (for now if mysql.event has been tampered and MICROSECONDS
interval or derivative has been put there.
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);
......@@ -1217,6 +1221,7 @@ event_timed::restore_security_context(THD *thd, Security_context *backup)
RETURN VALUE
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));
......
......@@ -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"
......
......@@ -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);
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment