Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2122 06/02/20 17:39:45 andrey@lmy004. +15 -0
fix for bug#16992 Events: information_schema troubles
WL#1034
(the previous CSet was missing one file :( )
EVENT is no more needed, as SHOW PRIVILEGES, to see own events.
To see all events one needs SELECT on mysql.event.
SHOW EVENTS always shows events from one database. FULL has no effect
SELECT I_S gets from all schemas. If user is missing EVENT on a schema
but still has events there he will be able to see them but they won't
be executed because he misses EVENT on this schema. They will start
executing again if she gets again granted EVENT on this schema.
mysql-test/t/events_tamper.test
1.1 06/02/20 17:39:37 andrey@lmy004. +100 -0
mysql-test/t/events_tamper.test
1.0 06/02/20 17:39:37 andrey@lmy004. +0 -0
BitKeeper file /work/mysql-5.1-bug16992/mysql-test/t/events_tamper.test
mysql-test/r/events_tamper.result
1.1 06/02/20 17:39:34 andrey@lmy004. +126 -0
mysql-test/r/events_tamper.result
1.0 06/02/20 17:39:34 andrey@lmy004. +0 -0
BitKeeper file /work/mysql-5.1-bug16992/mysql-test/r/events_tamper.result
mysql-test/r/events_i_s.result
1.1 06/02/20 17:39:33 andrey@lmy004. +125 -0
sql/table.h
1.132 06/02/20 17:39:33 andrey@lmy004. +19 -2
- add index checking typedef
sql/table.cc
1.210 06/02/20 17:39:33 andrey@lmy004. +64 -16
- add functionality to table_check_intact() to check also indices, if needed
indices on tables with up to 255 fields. The index length is practically unlimited
but anyway - 255 fields.
- prefix the table->alias with mysql. The code will be used anyway for now only for
mysql internal tables.
sql/sql_show.cc
1.308 06/02/20 17:39:33 andrey@lmy004. +63 -21
- field 16 of I_S.EVENTS, last_execute_at is declared as maybe_null so only in case
it's not
null call set_notnull() and set a value
- handle in better way SHOW EVENTS / SELECT I_S
-- SHOW EVENTS can be executed without having EVENT on the specific schema. All
user's events
will be presented. If the user has no EVENT but SELECT_ACL on mysql.event the he
will see
all events in the specific schema (nobody can prevent him from selecting
mysql.event anyway)
-- SELECT I_S is the same as SHOW EVENTS but on global level. Without SELECT_ACL on
mysql.event
one does see all events (s)he has. With SELECT_ACL on mysql.event one sees all
existing events.
sql/sql_parse.cc
1.523 06/02/20 17:39:33 andrey@lmy004. +5 -6
- handle show events in another way. show events does not require EVENT priv to
see your own events. SELECT on mysql.event is required to see all events per
db (with SHOW EVENTS) or globally (with SELECT I_S.EVENTS)
sql/event_executor.cc
1.31 06/02/20 17:39:33 andrey@lmy004. +6 -6
- additional NULL parameter durin checking of mysql.db, we don't check the
indices of mysql.db because we don't care about them.
- make "event_scheduler" var OFF when the scheduler finishes.
sql/event.cc
1.31 06/02/20 17:39:33 andrey@lmy004. +104 -86
- add information about the indices we expect mysql.event to have
- because the new UNIQUE index is introduced on mysql.event it is used
in evex_drop_db_events() to speedup the table scan to an index scan.
- everything else changed in this file is whitespace change
scripts/mysql_fix_privilege_tables.sql
1.41 06/02/20 17:39:33 andrey@lmy004. +3 -2
add additional unique index;
scripts/mysql_create_system_tables.sh
1.38 06/02/20 17:39:33 andrey@lmy004. +2 -1
add additional unique index
mysql-test/r/events_i_s.result
1.0 06/02/20 17:39:33 andrey@lmy004. +0 -0
BitKeeper file /work/mysql-5.1-bug16992/mysql-test/r/events_i_s.result
mysql-test/t/events.test
1.21 06/02/20 17:39:32 andrey@lmy004. +0 -132
- move information_schema test of EVENTS to a separate test
- move tampering test to separate file which has more tests for index
checking.
mysql-test/r/system_mysql_db.result
1.39 06/02/20 17:39:32 andrey@lmy004. +2 -1
- fix output
mysql-test/r/events.result
1.22 06/02/20 17:39:32 andrey@lmy004. +1 -143
-update results file
-information_schema test of EVENTS has been moved to a separate file
-tampering of mysql.event test has been moved to a separate file
mysql-test/lib/init_db.sql
1.25 06/02/20 17:39:32 andrey@lmy004. +2 -1
add a second key, unique to the table mysql.event
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: andrey
# Host: lmy004.
# Root: /work/mysql-5.1-bug16992
--- 1.522/sql/sql_parse.cc 2006-02-15 17:12:20 +01:00
+++ 1.523/sql/sql_parse.cc 2006-02-20 17:39:33 +01:00
@@ -2458,15 +2458,11 @@ mysql_execute_command(THD *thd)
if (all_tables)
{
if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
- lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC &&
- lex->orig_sql_command != SQLCOM_SHOW_EVENTS)
+ lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC)
res= check_table_access(thd,
lex->exchange ? SELECT_ACL | FILE_ACL :
SELECT_ACL,
all_tables, 0);
- else if (lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
- res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
- is_schema_db(thd->lex->select_lex.db));
}
else
res= check_access(thd,
@@ -3769,9 +3765,12 @@ end_with_restore_list:
break;
}
- if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
+ if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 1,
is_schema_db(lex->et->dbname.str)))
+ {
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "EVENT");
break;
+ }
if (end_active_trans(thd))
{
--- 1.307/sql/sql_show.cc 2006-02-16 13:12:37 +01:00
+++ 1.308/sql/sql_show.cc 2006-02-20 17:39:33 +01:00
@@ -4013,9 +4013,10 @@ fill_events_copy_to_schema_table(THD *th
sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
if (et.last_executed.year)
+ {
+ sch_table->field[16]->set_notnull();
sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME);
- else
- sch_table->field[16]->set_null();
+ }
sch_table->field[17]->store(et.comment.str, et.comment.length, scs);
@@ -4035,17 +4036,18 @@ int fill_schema_events(THD *thd, TABLE_L
int ret=0;
bool verbose= false;
char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
- bool use_prefix_scanning= true;
uint key_len= 0;
byte *key_buf= NULL;
LINT_INIT(key_buf);
+ bool use_prefix_scanning= TRUE;
DBUG_ENTER("fill_schema_events");
strxmov(definer,
thd->security_ctx->priv_user,"@",thd->security_ctx->priv_host,
NullS);
- DBUG_PRINT("info",("db=%s current_user=%s", thd->lex->select_lex.db, definer));
+ DBUG_PRINT("info",("db=%s current_user=%s",
+ thd->lex->select_lex.db?thd->lex->select_lex.db:"(null)",
definer));
thd->reset_n_backup_open_tables_state(&backup);
@@ -4055,33 +4057,68 @@ int fill_schema_events(THD *thd, TABLE_L
ret= 1;
goto err;
}
-
- event_table->file->ha_index_init(0, 1);
- /*
- see others' events only if you have PROCESS_ACL !!
- thd->lex->verbose is set either if SHOW FULL EVENTS or
- in case of SELECT FROM I_S.EVENTS
- */
- verbose= (thd->lex->verbose
- && (thd->security_ctx->master_access & PROCESS_ACL));
-
- if (verbose && thd->security_ctx->user)
- {
- ret= event_table->file->index_first(event_table->record[0]);
- use_prefix_scanning= false;
+ {
+ TABLE_LIST tmp_table;
+ bzero((char*) &tmp_table,sizeof(tmp_table));
+ tmp_table.db=(char*) "mysql";
+ tmp_table.table_name=(char*) "event";
+ verbose= !(check_grant(thd, SELECT_ACL, &tmp_table, 0, 1, 1));
+ }
+
+ if (verbose)
+ {
+ /*
+ 1. SELECT I_S => use PK(0)
+ 2. SHOW EVENTS => second index(1) (db, name, definer)
+
+ */
+ if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+ {
+ DBUG_PRINT("info",("Using prefix scanning on UNIQUE"));
+ event_table->file->ha_index_init(1, 1);
+ DBUG_ASSERT(thd->lex->select_lex.db);
+ DBUG_PRINT("info",("Using `%s` in the prefix", thd->lex->select_lex.db));
+ event_table->field[EVEX_FIELD_DB]->
+ store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db),
scs);
+ key_len= event_table->key_info[1].key_part[0].store_length;
+
+ if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+ {
+ ret= 1;
+ goto err;
+ }
+
+ key_copy(key_buf, event_table->record[0], event_table->key_info + 1,
+ key_len);
+ ret= event_table->file->index_read(event_table->record[0], key_buf,
+ key_len, HA_READ_PREFIX);
+ }
+ else
+ {
+ DBUG_PRINT("info",("Not using prefix scanning but using PK."));
+ event_table->file->ha_index_init(0, 1);
+ ret= event_table->file->index_first(event_table->record[0]);
+ use_prefix_scanning= FALSE;
+ }
}
else
{
- event_table->field[EVEX_FIELD_DEFINER]->store(definer, strlen(definer), scs);
+ DBUG_PRINT("info",("Using prefix scanning on PK"));
+
+ event_table->file->ha_index_init(0, 1);
+ event_table->field[EVEX_FIELD_DEFINER]->store(definer, strlen(definer), scs);
key_len= event_table->key_info->key_part[0].store_length;
- if (thd->lex->select_lex.db)
+ if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
{
+ DBUG_PRINT("info",("Using also `%s` in the prefix scanning",
+ thd->lex->select_lex.db));
event_table->field[EVEX_FIELD_DB]->
store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db),
scs);
key_len+= event_table->key_info->key_part[1].store_length;
}
+
if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
{
ret= 1;
@@ -4098,6 +4135,7 @@ int fill_schema_events(THD *thd, TABLE_L
ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
goto err;
}
+ DBUG_PRINT("info",("Found some rows, let's retrieve them."));
while (!ret)
{
@@ -4106,20 +4144,24 @@ int fill_schema_events(THD *thd, TABLE_L
if (use_prefix_scanning)
ret= event_table->file->
- index_next_same(event_table->record[0], key_buf, key_len);
+ index_next_same(event_table->record[0], key_buf, key_len);
else
ret= event_table->file->index_next(event_table->record[0]);
}
+ DBUG_PRINT("info",("Scan finished"));
// ret is guaranteed to be != 0
ret= (ret != HA_ERR_END_OF_FILE);
err:
if (event_table)
{
+ DBUG_PRINT("info",("Closing index"));
event_table->file->ha_index_end();
close_thread_tables(thd);
}
thd->restore_backup_open_tables_state(&backup);
+
+ DBUG_PRINT("info",("Return code=%d", ret));
DBUG_RETURN(ret);
}
--- 1.209/sql/table.cc 2006-02-14 20:10:43 +01:00
+++ 1.210/sql/table.cc 2006-02-20 17:39:33 +01:00
@@ -2299,6 +2299,9 @@ bool check_column_name(const char *name)
table - the table to check
table_f_count - expected number of columns in the table
table_def - expected structure of the table (column name and type)
+ table_keys - NULL if no index checking, otherwise a pointer to an
+ array of the type. The last element in the array should
+ be {NULL, 0} (terminated in this way).
last_create_time- the table->file->create_time of the table in memory
we have checked last time
error_num - ER_XXXX from the error messages file. When 0 no error
@@ -2314,8 +2317,9 @@ bool check_column_name(const char *name)
my_bool
table_check_intact(TABLE *table, uint table_f_count,
- TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
- int error_num)
+ TABLE_FIELD_W_TYPE *table_def,
+ TABLE_KEY_FOR_CHECK *table_keys,
+ time_t *last_create_time, int error_num)
{
uint i;
my_bool error= FALSE;
@@ -2323,7 +2327,7 @@ table_check_intact(TABLE *table, uint ta
DBUG_ENTER("table_check_intact");
DBUG_PRINT("info",("table=%s expected_count=%d",table->alias, table_f_count));
DBUG_PRINT("info",("last_create_time=%d", *last_create_time));
-
+
if ((fields_diff_count= (table->s->fields != table_f_count)) ||
(*last_create_time != table->file->create_time))
{
@@ -2363,11 +2367,11 @@ table_check_intact(TABLE *table, uint ta
if (strncmp(field->field_name, table_def->name.str,
table_def->name.length))
{
- sql_print_error("(%s) Expected field %s at position %d, found %s",
- table->alias, table_def->name.str, i,
+ sql_print_error("(mysql.%s) Expected field %s at position %d, "
+ " found %s", table->alias, table_def->name.str, i,
field->field_name);
}
-
+
/*
IF the type does not match than something is really wrong
Check up to length - 1. Why?
@@ -2382,22 +2386,23 @@ table_check_intact(TABLE *table, uint ta
if (strncmp(sql_type.c_ptr(), table_def->type.str,
table_def->type.length - 1))
{
- sql_print_error("(%s) Expected field %s at position %d to have type "
- "%s, found %s", table->alias, table_def->name.str,
- i, table_def->type.str, sql_type.c_ptr());
+ sql_print_error("(mysql.%s) Expected field %s at position %d to "
+ " have type %s, found %s", table->alias,
+ table_def->name.str, i, table_def->type.str,
+ sql_type.c_ptr());
error= TRUE;
}
else if (table_def->cset.str && !field->has_charset())
{
- sql_print_error("(%s) Expected field %s at position %d to have "
+ sql_print_error("(mysql.%s) Expected field %s at position %d to have "
"character set '%s' but found no such", table->alias,
- table_def->name.str, i, table_def->cset.str);
+ table_def->name.str, i, table_def->cset.str);
error= TRUE;
}
else if (table_def->cset.str &&
strcmp(field->charset()->csname, table_def->cset.str))
{
- sql_print_error("(%s) Expected field %s at position %d to have "
+ sql_print_error("(mysql.%s) Expected field %s at position %d to have "
"character set '%s' but found '%s'", table->alias,
table_def->name.str, i, table_def->cset.str,
field->charset()->csname);
@@ -2406,12 +2411,54 @@ table_check_intact(TABLE *table, uint ta
}
else
{
- sql_print_error("(%s) Expected field %s at position %d to have type %s "
- " but no field found.", table_def->name.str,
+ sql_print_error("(mysql.%s) Expected field %s at position %d to "
+ " have type %s but no field found.", table_def->name.str,
table_def->name.str, i, table_def->type.str);
error= TRUE;
}
}
+ if (table_keys)
+ {
+ KEY *key_info= table->key_info;
+ uint key_num= 0;
+ uint missing_keys= 0;
+ for (; table_keys->key.length; ++key_num, ++table_keys, ++key_info)
+ {
+ if (table->s->keys < key_num + 1)
+ {
+ ++missing_keys;
+ continue;
+ }
+ KEY_PART_INFO *key_part= key_info->key_part;
+ if (table_keys->key.length > key_info->key_parts)
+ {
+ error= TRUE;
+ sql_print_error("(mysql.%s) Key %d is shorter than expected. "
+ "Expected %d key parts, found %d", table->alias,
+ key_num, table_keys->key.length, key_info->key_parts);
+ continue;
+ }
+ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
+ {
+ if (j == table_keys->key.length)
+ break;
+
+ if (key_part->fieldnr != table_keys->key.str[j])
+ {
+ error= TRUE;
+ sql_print_error("(mysql.%s) Key %d, key part %d expected field %d,"
+ " found %d.", table->alias, key_num, j,
+ table_keys->key.str[j], key_part->fieldnr);
+ }
+ }
+ }
+ if (missing_keys)
+ {
+ error= TRUE;
+ sql_print_error("(mysql.%s) Expected %d keys, found %d", table->alias,
+ table->s->keys + missing_keys, table->s->keys);
+ }
+ }
if (!error)
*last_create_time= table->file->create_time;
else if (!fields_diff_count && error_num)
@@ -2422,8 +2469,9 @@ table_check_intact(TABLE *table, uint ta
DBUG_PRINT("info", ("Table seems ok without thorough checking."));
*last_create_time= table->file->create_time;
}
-
- DBUG_RETURN(error);
+
+ DBUG_PRINT("info", ("return code=%d", error));
+ DBUG_RETURN(error);
}
--- 1.131/sql/table.h 2006-02-16 14:53:27 +01:00
+++ 1.132/sql/table.h 2006-02-20 17:39:33 +01:00
@@ -867,6 +867,7 @@ typedef struct st_open_table_list{
uint32 in_use,locked;
} OPEN_TABLE_LIST;
+
typedef struct st_table_field_w_type
{
LEX_STRING name;
@@ -874,8 +875,24 @@ typedef struct st_table_field_w_type
LEX_STRING cset;
} TABLE_FIELD_W_TYPE;
+/*
+ Every byte in the string regards a fieldnr
+ Should work without probles with tables with up to 126 fields.
+ If char is unsigned by default with up to 255 fields.
+ Usage:
+
+ STRING_WITH_LEN("\x01\x04\07")
+ This instructs that the index has 3 parts and includes fields
+ 1, 4 and 7. For the keys the indexing is 1-based and not 0-based.
+*/
+typedef struct st_table_key_for_check
+{
+ LEX_STRING key;
+} TABLE_KEY_FOR_CHECK;
+
my_bool
table_check_intact(TABLE *table, uint table_f_count,
- TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
- int error_num);
+ TABLE_FIELD_W_TYPE *table_def,
+ TABLE_KEY_FOR_CHECK *table_keys,
+ time_t *last_create_time, int error_num);
--- 1.21/mysql-test/r/events.result 2006-02-16 13:11:06 +01:00
+++ 1.22/mysql-test/r/events.result 2006-02-20 17:39:32 +01:00
@@ -168,149 +168,6 @@ drop event root19;
drop event root20;
drop event ðóóò21;
set names latin1;
-CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
-ALTER TABLE mysql.event ADD dummy INT FIRST;
-SHOW EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
-ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
-SHOW EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
-ALTER TABLE mysql.event DROP dummy2;
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
-CREATE TABLE event_like LIKE mysql.event;
-INSERT INTO event_like SELECT * FROM mysql.event;
-ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default
'';
-SHOW CREATE TABLE mysql.event;
-Table Create Table
-event CREATE TABLE `event` (
- `db` char(20) character set utf8 collate utf8_bin NOT NULL default '',
- `name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
- `body` longblob NOT NULL,
- `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
- `execute_at` datetime default NULL,
- `interval_value` int(11) default NULL,
- `interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
- `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
- `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
- `last_executed` datetime default NULL,
- `starts` datetime default NULL,
- `ends` datetime default NULL,
- `status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
- `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`)
-) 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.
-ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default
'';
-"This should work"
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
-ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
-ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
-ALTER TABLE mysql.event DROP comment, DROP starts;
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 14. Table probably
corrupted
-DROP TABLE mysql.event;
-CREATE TABLE mysql.event like event_like;
-INSERT INTO mysql.event SELECT * FROM event_like;
-DROP TABLE event_like;
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
-DROP EVENT intact_check;
-create event one_event on schedule every 10 second do select 123;
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
-NULL events_test one_event root@localhost select 123 RECURRING NULL 10 SECOND ENABLED NOT
PRESERVE
-CREATE DATABASE events_test2;
-CREATE USER ev_test@localhost;
-GRANT ALL ON events_test.* to ev_test@localhost;
-GRANT ALL on events_test2.* to ev_test@localhost;
-REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
-REVOKE PROCESS on *.* from ev_test@localhost;
-select "NEW CONNECTION";
-NEW CONNECTION
-NEW CONNECTION
-SELECT USER(), DATABASE();
-USER() DATABASE()
-ev_test@localhost events_test2
-SHOW GRANTS;
-Grants for ev_test@localhost
-GRANT USAGE ON *.* TO 'ev_test'@'localhost'
-GRANT ALL PRIVILEGES ON `events_test`.* TO 'ev_test'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE
TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER
ROUTINE, TRIGGER ON `events_test2`.* TO 'ev_test'@'localhost'
-"Here comes an error:";
-SHOW EVENTS;
-ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_test2'
-USE events_test;
-"Now the list should be empty:";
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-select concat("Let's create some new events from the name of ",user());
-concat("Let's create some new events from the name of ",user())
-Let's create some new events from the name of ev_test@localhost
-create event one_event on schedule every 20 second do select 123;
-create event two_event on schedule every 20 second on completion not preserve comment
"two event" do select 123;
-create event three_event on schedule every 20 second on completion preserve comment
"three event" do select 123;
-"Now we should see 3 events:";
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-"This should show us only 3 events:";
-SHOW FULL EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-"This should show us only 2 events:";
-SHOW FULL EVENTS LIKE 't%event';
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-"This should show us no events:";
-SHOW FULL EVENTS FROM test LIKE '%';
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-DROP DATABASE events_test2;
-"should see 1 event:";
-SHOW EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
-"we should see 4 events now:";
-SHOW FULL EVENTS;
-Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
-events_test one_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
-events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
-NULL events_test one_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE
-NULL events_test three_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
-NULL events_test two_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
-NULL events_test one_event root@localhost select 123 RECURRING NULL 10 SECOND ENABLED NOT
PRESERVE
-drop event one_event;
-drop event two_event;
-drop event three_event;
-drop user ev_test@localhost;
-drop event one_event;
-"Sleep a bit so the server closes the second connection"
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
@@ -343,6 +200,7 @@ root@localhost закачка events_tes
show processlist;
Id User Host db Command Time State Info
# root localhost events_test Query # NULL show processlist
+# event_scheduler connecting host NULL Connect # Sleeping NULL
select release_lock("test_lock1");
release_lock("test_lock1")
1
--- New file ---
+++ mysql-test/r/events_i_s.result 06/02/20 17:39:33
create database if not exists events_test;
use events_test;
select user(), database();
user() database()
root@localhost events_test
create event one_event on schedule every 10 second do select 123;
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test one_event root@localhost RECURRING NULL 10 SECOND # # ENABLED
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost select 123 RECURRING NULL 10 SECOND ENABLED NOT
PRESERVE
CREATE DATABASE events_test2;
CREATE USER ev_test@localhost;
GRANT EVENT ON events_test.* to ev_test@localhost;
GRANT SELECT on events_test2.* to ev_test@localhost;
"Connect as ev_con1, user ev_test, db events_test2"
"NEW CONNECTION";
SELECT USER(), DATABASE();
USER() DATABASE()
ev_test@localhost events_test2
SHOW GRANTS;
Grants for ev_test@localhost
GRANT USAGE ON *.* TO 'ev_test'@'localhost'
GRANT EVENT ON `events_test`.* TO 'ev_test'@'localhost'
GRANT SELECT ON `events_test2`.* TO 'ev_test'@'localhost'
"Now the list should be empty:";
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
"Now create few events as ev_test@localhost in schema events_test"
select concat("Let's create some new events from the name of ",user());
concat("Let's create some new events from the name of ",user())
Let's create some new events from the name of ev_test@localhost
"ev_test@localhost has no EVENT so error"
create event one_event on schedule every 20 second disable do select 123;
ERROR 42000: Access denied; you need the EVENT privilege for this operation
"Now we will give him EVENT"
GRANT EVENT ON events_test2.* to ev_test@localhost;
"Change the current schema so the server will read our new privs"
use events_test;
use events_test2;
"Now he has EVENT and will create 3 events"
create event one_event on schedule every 20 second disable do select 123;
create event two_event on schedule every 20 second on completion not preserve comment "two
event" do select 123;
create event three_event on schedule every 20 second on completion preserve comment "three
event" do select 123;
"Now we should see 3 events because ev_test has no SELECT on mysql.event:";
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 one_event ev_test@localhost RECURRING NULL 20 SECOND # # DISABLED
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
"Let's REVOKE his EVENT on events_test2, but he will still see his events"
REVOKE EVENT on events_test2.* FROM ev_test@localhost;
"Now he has no EVENT on events_test2 but that's not a problem"
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 one_event ev_test@localhost RECURRING NULL 20 SECOND # # DISABLED
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
"This should show us only 2 events:";
SHOW EVENTS LIKE 't%event';
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
"This should show us no events:";
SHOW EVENTS FROM test LIKE '%';
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
"This also :";
SHOW EVENTS IN test LIKE '%';
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
"ok, we are back to root@localhost"
USE events_test2;
create event root_event_1 on schedule every 10 hour do select 12345;
create event root_event_2 on schedule every 20 minute do select 4567;
"As root@localhost we should see 5 event:";
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 one_event ev_test@localhost RECURRING NULL 20 SECOND # # DISABLED
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 root_event_1 root@localhost RECURRING NULL 10 HOUR # # ENABLED
events_test2 root_event_2 root@localhost RECURRING NULL 20 MINUTE # # ENABLED
"Switching back to ev_con1, should see only his 3 events. Keep in mind he has no EVENT
ATM"
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 one_event ev_test@localhost RECURRING NULL 20 SECOND # # DISABLED
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
"Back to root@localhost to GRANT SELECT on mysql.event"
GRANT SELECT ON mysql.event TO ev_test@localhost;
"Back to ev_test@localhost"
"Now we should see 5 events, because of SELECT on mysql.event,"
"even without EVENT on event_test2. 3 of ev_test@localhost and 2 of root@localhost"
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test2 one_event ev_test@localhost RECURRING NULL 20 SECOND # # DISABLED
events_test2 three_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 two_event ev_test@localhost RECURRING NULL 20 SECOND # # ENABLED
events_test2 root_event_1 root@localhost RECURRING NULL 10 HOUR # # ENABLED
events_test2 root_event_2 root@localhost RECURRING NULL 20 MINUTE # # ENABLED
"we should see 6 events now (additional one from events_test schema:";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test2 one_event ev_test@localhost select
123 RECURRING NULL 20 SECOND DISABLED NOT PRESERVE
NULL events_test2 three_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
NULL events_test2 two_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
NULL events_test one_event root@localhost select 123 RECURRING NULL 10 SECOND ENABLED NOT
PRESERVE
NULL events_test2 root_event_1 root@localhost select
12345 RECURRING NULL 10 HOUR ENABLED NOT PRESERVE
NULL events_test2 root_event_2 root@localhost select
4567 RECURRING NULL 20 MINUTE ENABLED NOT PRESERVE
REVOKE SELECT ON mysql.event FROM ev_test@localhost;
"we should see only 3 events now, we don't have SELECT on mysql.event anymore:";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test2 one_event ev_test@localhost select
123 RECURRING NULL 20 SECOND DISABLED NOT PRESERVE
NULL events_test2 three_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED PRESERVE three event
NULL events_test2 two_event ev_test@localhost select
123 RECURRING NULL 20 SECOND ENABLED NOT PRESERVE two event
DROP DATABASE events_test2;
use events_test;
"we should see only 2 events now, 3 of ev_test@localhost were dropped with DROP DATABASE";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost select 123 RECURRING NULL 10 SECOND ENABLED NOT
PRESERVE
drop user ev_test@localhost;
drop event one_event;
drop database events_test;
--- New file ---
+++ mysql-test/r/events_tamper.result 06/02/20 17:39:34
create database if not exists events_test;
use events_test;
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
ALTER TABLE mysql.event ADD dummy INT FIRST;
SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
ALTER TABLE mysql.event DROP dummy2;
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event;
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
SHOW CREATE TABLE mysql.event;
Table Create Table
event CREATE TABLE `event` (
`db` char(20) character set utf8 collate utf8_bin NOT NULL default '',
`name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
`body` longblob NOT NULL,
`definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
`execute_at` datetime default NULL,
`interval_value` int(11) default NULL,
`interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL default '0000-00-00 00:00:00',
`last_executed` datetime default NULL,
`starts` datetime default NULL,
`ends` datetime default NULL,
`status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
`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`),
UNIQUE KEY `db_definer_name` (`db`,`definer`,`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.
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
"This should work"
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP comment, DROP starts;
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 14. Table probably
corrupted
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
"Now dropping one index to see whether index tampering check works"
ALTER TABLE mysql.event DROP PRIMARY KEY;
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
"Recreating, should work now:"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
"Test whether everything is fine"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
ALTER TABLE mysql.event DROP INDEX db_definer_name;
SHOW CREATE TABLE mysql.event;
Table Create Table
event CREATE TABLE `event` (
`db` char(64) character set utf8 collate utf8_bin NOT NULL default '',
`name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
`body` longblob NOT NULL,
`definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
`execute_at` datetime default NULL,
`interval_value` int(11) default NULL,
`interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL default '0000-00-00 00:00:00',
`last_executed` datetime default NULL,
`starts` datetime default NULL,
`ends` datetime default NULL,
`status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
`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`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
"Now let's bork the index and see whether we catch it"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name, definer);
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP KEY db_definer_name;
"Make the key shorter"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name);
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP KEY db_definer_name;
"Try with longer index, this should work"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, definer, name, execute_at);
"No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
"Add 1 more index, that should not be a problem - downgrading is ok"
ALTER TABLE mysql.event ADD KEY dummy_index(execute_at);
"No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
"Recreating"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
DROP TABLE event_like;
SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
DROP EVENT intact_check;
drop database events_test;
--- 1.20/mysql-test/t/events.test 2006-02-16 05:20:54 +01:00
+++ 1.21/mysql-test/t/events.test 2006-02-20 17:39:32 +01:00
@@ -149,139 +149,7 @@ set names latin1;
# SHOW CREATE EVENT test end
#
-#
-# mysql.event intact checking start
-#
-# There should be at least 1 second between the ALTERs or we can't catch the change of
create_time!!
-#
-CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
---replace_column 8 # 9 #
-SHOW EVENTS;
-ALTER TABLE mysql.event ADD dummy INT FIRST;
---error 1525
-SHOW EVENTS;
-ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
---error 1525
-SHOW EVENTS;
-ALTER TABLE mysql.event DROP dummy2;
---replace_column 8 # 9 #
-SHOW EVENTS;
-CREATE TABLE event_like LIKE mysql.event;
-INSERT INTO event_like SELECT * FROM mysql.event;
-#sleep a bit or we won't catch the change of time
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default
'';
-#wait a bit or we won't see the difference because of seconds resolution
---sleep 1
-SHOW CREATE TABLE mysql.event;
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default
'';
---sleep 1
---echo "This should work"
---replace_column 8 # 9 #
-SHOW EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event DROP comment, DROP starts;
---sleep 1
---error 1525
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-DROP TABLE mysql.event;
-CREATE TABLE mysql.event like event_like;
-INSERT INTO mysql.event SELECT * FROM event_like;
-DROP TABLE event_like;
---replace_column 8 # 9 #
-SHOW EVENTS;
-DROP EVENT intact_check;
-#
-# mysql.event intact checking end
-#
-#
-#INFORMATION_SCHEMA.EVENTS test begin
-#
-create event one_event on schedule every 10 second do select 123;
---replace_column 8 # 9 #
-SHOW EVENTS;
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-CREATE DATABASE events_test2;
-CREATE USER ev_test@localhost;
-GRANT ALL ON events_test.* to ev_test@localhost;
-GRANT ALL on events_test2.* to ev_test@localhost;
-REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
-REVOKE PROCESS on *.* from ev_test@localhost;
-#now we are on con1
-connect (ev_con1,localhost,ev_test,,events_test2);
-select "NEW CONNECTION";
-SELECT USER(), DATABASE();
-SHOW GRANTS;
-
---echo "Here comes an error:";
-#NO EVENT_ACL on events_test2
---error 1044
-SHOW EVENTS;
-USE events_test;
-
---echo "Now the list should be empty:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-#now create an event with the same name but we are different user
-select concat("Let's create some new events from the name of ",user());
-create event one_event on schedule every 20 second do select 123;
-create event two_event on schedule every 20 second on completion not preserve comment
"two event" do select 123;
-create event three_event on schedule every 20 second on completion preserve comment
"three event" do select 123;
-
---echo "Now we should see 3 events:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-
---echo "This should show us only 3 events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS;
-
---echo "This should show us only 2 events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS LIKE 't%event';
-
---echo "This should show us no events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS FROM test LIKE '%';
-#ok, we are back
-connection default;
-DROP DATABASE events_test2;
-
---echo "should see 1 event:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-
---echo "we should see 4 events now:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS;
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-
-connection ev_con1;
-drop event one_event;
-drop event two_event;
-drop event three_event;
-disconnect ev_con1;
-connection default;
-drop user ev_test@localhost;
-drop event one_event;
-#
-##INFORMATION_SCHEMA.EVENTS test end
-#
-
---echo "Sleep a bit so the server closes the second connection"
---sleep 2
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;
drop event e_26;
--- New file ---
+++ mysql-test/t/events_tamper.test 06/02/20 17:39:37
create database if not exists events_test;
use events_test;
#
# mysql.event intact checking start
#
# There should be at least 1 second between the ALTERs or we can't catch the change of
create_time!!
#
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
--replace_column 8 # 9 #
SHOW EVENTS;
ALTER TABLE mysql.event ADD dummy INT FIRST;
--error 1525
SHOW EVENTS;
ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
--error 1525
SHOW EVENTS;
ALTER TABLE mysql.event DROP dummy2;
--replace_column 8 # 9 #
SHOW EVENTS;
CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event;
#sleep a bit or we won't catch the change of time
--sleep 1
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
#wait a bit or we won't see the difference because of seconds resolution
--sleep 1
SHOW CREATE TABLE mysql.event;
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
--sleep 1
--echo "This should work"
--replace_column 8 # 9 #
SHOW EVENTS;
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP comment, DROP starts;
--sleep 2
--error 1525
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
--echo "Now dropping one index to see whether index tampering check works"
ALTER TABLE mysql.event DROP PRIMARY KEY;
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Recreating, should work now:"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
--echo "Test whether everything is fine"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP INDEX db_definer_name;
SHOW CREATE TABLE mysql.event;
#--sleep 2
#--error 1526
#SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Now let's bork the index and see whether we catch it"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name, definer);
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP KEY db_definer_name;
--echo "Make the key shorter"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name);
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP KEY db_definer_name;
--echo "Try with longer index, this should work"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, definer, name, execute_at);
--sleep 2
--echo "No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Add 1 more index, that should not be a problem - downgrading is ok"
ALTER TABLE mysql.event ADD KEY dummy_index(execute_at);
--sleep 2
--echo "No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Recreating"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like;
DROP TABLE event_like;
--replace_column 8 # 9 #
SHOW EVENTS;
DROP EVENT intact_check;
#
# mysql.event intact checking end
#
drop database events_test;
--- 1.30/sql/event.cc 2006-02-16 13:11:06 +01:00
+++ 1.31/sql/event.cc 2006-02-20 17:39:33 +01:00
@@ -66,10 +66,15 @@ QUEUE EVEX_EQ_NAME;
MEM_ROOT evex_mem_root;
time_t mysql_event_last_create_time= 0L;
+TABLE_KEY_FOR_CHECK event_table_keys[4]= {
+ { (char *) STRING_WITH_LEN("\x04\x01\x02") },
+ { (char *) STRING_WITH_LEN("\x01\x04\x02") },
+ { NULL, 0}
+};
-static TABLE_FIELD_W_TYPE event_table_fields[EVEX_FIELD_COUNT] = {
+TABLE_FIELD_W_TYPE event_table_fields[EVEX_FIELD_COUNT] = {
{
- {(char *) STRING_WITH_LEN("db")},
+ {(char *) STRING_WITH_LEN("db")},
{(char *) STRING_WITH_LEN("char(64)")},
{(char *) STRING_WITH_LEN("utf8")}
},
@@ -162,25 +167,25 @@ static TABLE_FIELD_W_TYPE event_table_fi
LEX_STRING interval_type_to_name[] = {
- {(char *) STRING_WITH_LEN("YEAR")},
- {(char *) STRING_WITH_LEN("QUARTER")},
- {(char *) STRING_WITH_LEN("MONTH")},
- {(char *) STRING_WITH_LEN("DAY")},
- {(char *) STRING_WITH_LEN("HOUR")},
- {(char *) STRING_WITH_LEN("MINUTE")},
- {(char *) STRING_WITH_LEN("WEEK")},
- {(char *) STRING_WITH_LEN("SECOND")},
- {(char *) STRING_WITH_LEN("MICROSECOND")},
- {(char *) STRING_WITH_LEN("YEAR_MONTH")},
- {(char *) STRING_WITH_LEN("DAY_HOUR")},
- {(char *) STRING_WITH_LEN("DAY_MINUTE")},
- {(char *) STRING_WITH_LEN("DAY_SECOND")},
- {(char *) STRING_WITH_LEN("HOUR_MINUTE")},
- {(char *) STRING_WITH_LEN("HOUR_SECOND")},
- {(char *) STRING_WITH_LEN("MINUTE_SECOND")},
- {(char *) STRING_WITH_LEN("DAY_MICROSECOND")},
- {(char *) STRING_WITH_LEN("HOUR_MICROSECOND")},
- {(char *) STRING_WITH_LEN("MINUTE_MICROSECOND")},
+ {(char *) STRING_WITH_LEN("YEAR")},
+ {(char *) STRING_WITH_LEN("QUARTER")},
+ {(char *) STRING_WITH_LEN("MONTH")},
+ {(char *) STRING_WITH_LEN("DAY")},
+ {(char *) STRING_WITH_LEN("HOUR")},
+ {(char *) STRING_WITH_LEN("MINUTE")},
+ {(char *) STRING_WITH_LEN("WEEK")},
+ {(char *) STRING_WITH_LEN("SECOND")},
+ {(char *) STRING_WITH_LEN("MICROSECOND")},
+ {(char *) STRING_WITH_LEN("YEAR_MONTH")},
+ {(char *) STRING_WITH_LEN("DAY_HOUR")},
+ {(char *) STRING_WITH_LEN("DAY_MINUTE")},
+ {(char *) STRING_WITH_LEN("DAY_SECOND")},
+ {(char *) STRING_WITH_LEN("HOUR_MINUTE")},
+ {(char *) STRING_WITH_LEN("HOUR_SECOND")},
+ {(char *) STRING_WITH_LEN("MINUTE_SECOND")},
+ {(char *) STRING_WITH_LEN("DAY_MICROSECOND")},
+ {(char *) STRING_WITH_LEN("HOUR_MICROSECOND")},
+ {(char *) STRING_WITH_LEN("MINUTE_MICROSECOND")},
{(char *) STRING_WITH_LEN("SECOND_MICROSECOND")}
};
@@ -369,7 +374,7 @@ event_reconstruct_interval_expression(St
goto common_1_lev_code;
case INTERVAL_HOUR_MINUTE:
case INTERVAL_MINUTE_SECOND:
- multipl= 60;
+ multipl= 60;
common_1_lev_code:
buf->append('\'');
end= longlong10_to_str(expression/multipl, tmp_buff, 10);
@@ -410,7 +415,7 @@ common_1_lev_code:
expr= tmp_expr - (tmp_expr/60)*60;
/* the code after the switch will finish */
}
- break;
+ break;
case INTERVAL_DAY_SECOND:
{
int tmp_expr= expr;
@@ -493,7 +498,7 @@ evex_open_event_table(THD *thd, enum thr
DBUG_RETURN(1);
if (table_check_intact(tables.table, EVEX_FIELD_COUNT, event_table_fields,
- &mysql_event_last_create_time,
+ event_table_keys, &mysql_event_last_create_time,
ER_EVENT_CANNOT_LOAD_FROM_TABLE))
{
close_thread_tables(thd);
@@ -593,7 +598,7 @@ evex_db_find_event_by_name(THD *thd, con
Returns
0 - ok
EVEX_GENERAL_ERROR - bad data
- EVEX_GET_FIELD_FAILED - field count does not match. table corrupted?
+ EVEX_GET_FIELD_FAILED - field count does not match. table corrupted?
DESCRIPTION
Used both when an event is created and when it is altered.
@@ -641,7 +646,7 @@ evex_fill_row(THD *thd, TABLE *table, ev
table->field[EVEX_FIELD_ENDS]->
store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
}
-
+
if (et->expression)
{
table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull();
@@ -664,8 +669,8 @@ evex_fill_row(THD *thd, TABLE *table, ev
table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull();
table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at,
- MYSQL_TIMESTAMP_DATETIME);
-
+ MYSQL_TIMESTAMP_DATETIME);
+
table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null();
}
else
@@ -674,7 +679,7 @@ evex_fill_row(THD *thd, TABLE *table, ev
// it is normal to be here when the action is update
// this is an error if the action is create. something is borked
}
-
+
((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time();
if (et->comment.length)
@@ -698,7 +703,7 @@ trunc_err:
et event_timed object containing information for the event
create_if_not - if an warning should be generated in case event exists
rows_affected - how many rows were affected
-
+
Return value
0 - OK
EVEX_GENERAL_ERROR - Failure
@@ -726,7 +731,7 @@ db_create_event(THD *thd, event_timed *e
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
goto err;
}
-
+
DBUG_PRINT("info", ("check existance of an event with the same name"));
if (!evex_db_find_event_aux(thd, et, table))
{
@@ -735,7 +740,7 @@ db_create_event(THD *thd, event_timed *e
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
et->name.str);
- goto ok;
+ goto ok;
}
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
goto err;
@@ -747,7 +752,7 @@ db_create_event(THD *thd, event_timed *e
my_error(ER_BAD_DB_ERROR, MYF(0));
goto err;
}
-
+
restore_record(table, s->default_values); // Get default values for fields
if (system_charset_info->cset->numchars(system_charset_info, et->dbname.str,
@@ -831,7 +836,7 @@ err:
thd THD
sp_name the name of the event to alter
et event's data
-
+
NOTES
sp_name is passed since this is the name of the event to
alter in case of RENAME TO.
@@ -931,7 +936,7 @@ err:
definer who owns the event
ett event's data if event is found
tbl TABLE object to use when not NULL
-
+
NOTES
1) Use sp_name for look up, return in **ett if found
2) tbl is not closed at exit
@@ -967,7 +972,7 @@ db_find_event(THD *thd, sp_name *name, L
goto done;
}
et= new event_timed;
-
+
/*
1)The table should not be closed beforehand. ::load_from_row() only loads
and does not compile
@@ -1146,7 +1151,7 @@ done:
create_options Options specified when in the query. We are
interested whether there is IF NOT EXISTS
rows_affected How many rows were affected
-
+
NOTES
- in case there is an event with the same name (db) and
IF NOT EXISTS is specified, an warning is put into the W stack.
@@ -1190,7 +1195,7 @@ done:
thd THD
et event's data
new_name set in case of RENAME TO.
-
+
NOTES
et contains data about dbname and event name.
new_name is the new name of the event, if not null (this means
@@ -1312,7 +1317,7 @@ done:
et event's name
drop_if_exists if set and the event not existing => warning onto the stack
rows_affected affected number of rows is returned heres
-
+
*/
int
@@ -1349,11 +1354,11 @@ evex_drop_event(THD *thd, event_timed *e
thd THD
spn the name of the event (db, name)
definer the definer of the event
-
+
RETURNS
0 - OK
1 - Error during writing to the wire
-
+
*/
int
@@ -1378,7 +1383,7 @@ evex_show_create_event(THD *thd, sp_name
List<Item> field_list;
const char *sql_mode_str;
ulong sql_mode_len=0;
-
+
show_str.length(0);
show_str.set_charset(system_charset_info);
@@ -1404,19 +1409,19 @@ evex_show_create_event(THD *thd, sp_name
protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
-
+
protocol->store(show_str.c_ptr(), show_str.length(), system_charset_info);
ret= protocol->write();
send_eof(thd);
}
-
+
DBUG_RETURN(ret);
}
/*
evex_drop_db_events - Drops all events in the selected database
-
+
thd - Thread
db - ASCIIZ the name of the database
@@ -1447,12 +1452,11 @@ int
evex_drop_db_events(THD *thd, char *db)
{
TABLE *table;
- READ_RECORD read_record_info;
- MYSQL_LOCK *lock;
int ret= 0;
uint i;
+ uint key_len= 0;
+ byte *key_buf= NULL;
LEX_STRING db_lex= {db, strlen(db)};
-
DBUG_ENTER("evex_drop_db_events");
DBUG_PRINT("info",("dropping events from %s", db));
@@ -1537,58 +1541,72 @@ skip_memory:
*/
DBUG_PRINT("info",("Mem-cache checked, now going to db for disabled events"));
/* only enabled events are in memory, so we go now and delete the rest */
- init_read_record(&read_record_info, thd, table ,NULL,1,0);
- while (!(read_record_info.read_record(&read_record_info)) && !ret)
+
+
+ table->file->ha_index_init(1, 1);
+
+ DBUG_ASSERT(db);
+ DBUG_PRINT("info",("Using `%s` in the prefix", db));
+ table->field[EVEX_FIELD_DB]->store(db, strlen(db), system_charset_info);
+ key_len= table->key_info[1].key_part[0].store_length;
+
+ if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+ {
+ ret= 1;
+ goto end;
+ }
+
+ key_copy(key_buf, table->record[0], table->key_info + 1, key_len);
+ ret= table->file->index_read(table->record[0], key_buf, key_len,
+ HA_READ_PREFIX);
+ if (ret)
{
- char *et_db;
+ ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
+ goto end;
+ }
- if ((et_db= get_field(thd->mem_root, table->field[EVEX_FIELD_DB])) == NULL)
+ while (!ret)
+ {
+ char *ptr;
+
+ if ((ptr= get_field(thd->mem_root, table->field[EVEX_FIELD_STATUS]))
+ == NullS)
{
- ret= 2;
- break;
+ sql_print_error("Error while loading from mysql.event. "
+ "Table probably corrupted");
+ goto end;
}
-
- LEX_STRING et_db_lex= {et_db, strlen(et_db)};
- if (!sortcmp_lex_string(et_db_lex, db_lex, system_charset_info))
+ /*
+ When not running nothing is in memory so we have to clean
+ everything.
+ We don't delete EVENT_ENABLED events when the scheduler is running
+ because maybe this is an event which we asked to drop itself when
+ it is finished and it hasn't finished yet, so we don't touch it.
+ It will drop itself. The not running ENABLED events has been already
+ deleted from ha_delete_row() above in the loop over the QUEUE
+ (in case the executor is running).
+ 'D' stands for DISABLED, 'E' for ENABLED - it's an enum
+ */
+ if ((evex_is_running && ptr[0] == 'D') || !evex_is_running)
{
- event_timed ett;
- char *ptr;
-
- if ((ptr= get_field(thd->mem_root, table->field[EVEX_FIELD_STATUS]))
- == NullS)
+ char *name= get_field(thd->mem_root, table->field[EVEX_FIELD_NAME]);
+
+ if ((ret= table->file->ha_delete_row(table->record[0])))
{
- sql_print_error("Error while loading from mysql.event. "
- "Table probably corrupted");
+ my_error(ER_EVENT_DROP_FAILED, MYF(0), name);
goto end;
}
- /*
- When not running nothing is in memory so we have to clean
- everything.
- We don't delete EVENT_ENABLED events when the scheduler is running
- because maybe this is an event which we asked to drop itself when
- it is finished and it hasn't finished yet, so we don't touch it.
- It will drop itself. The not running ENABLED events has been already
- deleted from ha_delete_row() above in the loop over the QUEUE
- (in case the executor is running).
- 'D' stands for DISABLED, 'E' for ENABLED - it's an enum
- */
- if ((evex_is_running && ptr[0] == 'D') || !evex_is_running)
- {
- DBUG_PRINT("info", ("Dropping %s.%s", et_db, ett.name.str));
- if ((ret= table->file->ha_delete_row(table->record[0])))
- {
- my_error(ER_EVENT_DROP_FAILED, MYF(0), ett.name.str);
- goto end;
- }
- }
}
+ table->file->index_next_same(table->record[0], key_buf, key_len);
}
- DBUG_PRINT("info",("Disk checked for disabled events. Finishing."));
+ // ret is guaranteed to be != 0
+ ret= (ret != HA_ERR_END_OF_FILE);
+ DBUG_PRINT("info",("Disk checked for disabled events. Finishing."));
end:
VOID(pthread_mutex_unlock(&LOCK_evex_running));
VOID(pthread_mutex_unlock(&LOCK_event_arrays));
- end_read_record(&read_record_info);
+ table->file->ha_index_end();
thd->version--; // Force close to free memory
--- 1.30/sql/event_executor.cc 2006-02-16 01:27:30 +01:00
+++ 1.31/sql/event_executor.cc 2006-02-20 17:39:33 +01:00
@@ -151,7 +151,8 @@ 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);
+ NULL, &mysql_db_table_last_check,
+ ER_EVENT_CANNOT_LOAD_FROM_TABLE);
close_thread_tables(thd);
}
@@ -377,7 +378,6 @@ executor_wait_till_next_event_exec(THD *
DBUG_RETURN(ret);
}
-
/*
The main scheduler thread. Inits the priority queue on start and
destroys it on thread shutdown. Forks child threads for every event
@@ -402,12 +402,12 @@ event_executor_main(void *arg)
TIME time_now;
DBUG_ENTER("event_executor_main");
- DBUG_PRINT("event_executor_main", ("EVEX thread started"));
+ DBUG_PRINT("event_executor_main", ("EVEX thread started"));
+ sql_print_information("SCHEDULER: Starting");
// init memory root
init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
-
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
@@ -643,9 +643,9 @@ finish:
err_no_thd:
VOID(pthread_mutex_lock(&LOCK_evex_running));
- evex_is_running= false;
+ evex_is_running= false;
+ event_executor_running_global_var= false;
VOID(pthread_mutex_unlock(&LOCK_evex_running));
-
free_root(&evex_mem_root, MYF(0));
sql_print_information("SCHEDULER: Stopped.");
--- 1.24/mysql-test/lib/init_db.sql 2006-02-01 19:27:04 +01:00
+++ 1.25/mysql-test/lib/init_db.sql 2006-02-20 17:39:32 +01:00
@@ -631,7 +631,8 @@ CREATE TABLE event (
'HIGH_NOT_PRECEDENCE'
) DEFAULT '' NOT NULL,
comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
- PRIMARY KEY (definer, db, name)
+ PRIMARY KEY (definer, db, name),
+ UNIQUE KEY db_definer_name(db, definer, name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE DATABASE IF NOT EXISTS cluster_replication;
--- 1.40/scripts/mysql_fix_privilege_tables.sql 2006-02-02 11:35:58 +01:00
+++ 1.41/scripts/mysql_fix_privilege_tables.sql 2006-02-20 17:39:33 +01:00
@@ -622,7 +622,8 @@ CREATE TABLE event (
'HIGH_NOT_PRECEDENCE'
) DEFAULT '' NOT NULL,
comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
- PRIMARY KEY (db,name)
+ PRIMARY KEY (db,name),
+ UNIQUE KEY db_definer_name(db, definer, name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
@@ -666,7 +667,7 @@ ALTER TABLE event ADD sql_mode
'NO_AUTO_CREATE_USER',
'HIGH_NOT_PRECEDENCE'
) DEFAULT '' NOT NULL AFTER on_completion;
-
+ALTER TABLE event ADD UNIQUE KEY db_definer_name(db, definer, name);
--
-- TRIGGER privilege
--
--- 1.38/mysql-test/r/system_mysql_db.result 2006-02-02 11:35:57 +01:00
+++ 1.39/mysql-test/r/system_mysql_db.result 2006-02-20 17:39:32 +01:00
@@ -208,7 +208,8 @@ 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`),
+ UNIQUE KEY `db_definer_name` (`db`,`definer`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
show create table general_log;
Table Create Table
--- 1.37/scripts/mysql_create_system_tables.sh 2006-02-01 11:28:40 +01:00
+++ 1.38/scripts/mysql_create_system_tables.sh 2006-02-20 17:39:33 +01:00
@@ -827,7 +827,8 @@ then
c_ev="$c_ev 'HIGH_NOT_PRECEDENCE'"
c_ev="$c_ev ) DEFAULT '' NOT NULL,"
c_ev="$c_ev comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default
'',"
- c_ev="$c_ev PRIMARY KEY (definer, db, name)"
+ c_ev="$c_ev PRIMARY KEY (definer, db, name),"
+ c_ev="$c_ev UNIQUE KEY db_definer_name(db, definer, name)"
c_ev="$c_ev ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';"
fi
| Thread |
|---|
| • bk commit into 5.1 tree (andrey:1.2122) BUG#16992 | ahristov | 20 Feb |