mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
@ -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.
|
||||
|
56
mysql-test/r/events_microsec.result
Normal file
56
mysql-test/r/events_microsec.result
Normal file
@ -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;
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ 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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user