Commit c7d7c47d authored by unknown's avatar unknown

Fix for bug #17394 - Events namespace is wrong


mysql-test/lib/init_db.sql:
  remove definer from PK
mysql-test/r/events.result:
  update results
mysql-test/r/system_mysql_db.result:
  update results
mysql-test/t/events.test:
  remove I_S.EVENTS test and move it to events_grant.test
scripts/mysql_fix_privilege_tables.sql:
  change table definition
sql/event.cc:
  make events non-user specific (namespace change)
sql/event.h:
  make events non-user specific (namespace change)
sql/event_priv.h:
  make events non-user specific (namespace change)
sql/event_scheduler.cc:
  make events non-user specific (namespace change)
sql/event_timed.cc:
  make events non-user specific (namespace change)
sql/sql_parse.cc:
  make events non-user specific (namespace change)
sql/sql_show.cc:
  SHOW EVENTS is available to everyone who has EVENT on specific schema.
  No additional privileges are needed to see others' events.
  - user A has events in db1 and db2
  - user B has events in db1 and db3
  A will see all his events from db1 and db2 as well as B's events
  from db1 but not from db3.
  B will see her events from db1 and db3. In addition B will see
  only A's events from db1 but not db2.
parent 24aeeb75
......@@ -631,7 +631,7 @@ 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 (db, name)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE DATABASE IF NOT EXISTS cluster;
......
......@@ -254,7 +254,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 (`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.
......@@ -280,84 +280,6 @@ 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 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 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 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 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 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
......@@ -452,9 +374,6 @@ select 2;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
event_schema event_name definer event_body
events_test white_space root@localhost select 2
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
event_schema event_name definer event_body
events_test white_space root@localhost select 2
drop event white_space;
create event white_space on schedule every 10 hour disable do select 3;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
......
......@@ -208,7 +208,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 (`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
show create table general_log;
Table Create Table
......
......@@ -148,9 +148,9 @@ set names cp1251;
create event ðóóò21 on schedule every '50:23:59:95' day_second COMMENT 'òîâà å 1251 êîìåíòàð' do select 1;
SHOW CREATE EVENT ðóóò21;
insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND");
--error 1235
--error ER_NOT_SUPPORTED_YET
show create event root22;
--error 1235
--error ER_NOT_SUPPORTED_YET
SHOW EVENTS;
drop event root22;
drop event root6;
......@@ -239,82 +239,6 @@ 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 EVENTS;
--echo "This should show us only 2 events:";
--replace_column 8 # 9 #
SHOW EVENTS LIKE 't%event';
--echo "This should show us no events:";
--replace_column 8 # 9 #
SHOW 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 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;
......@@ -358,7 +282,7 @@ select get_lock("test_lock2", 20);
--echo "Create an event which tries to acquire a mutex. The event locks on the mutex"
create event закаÑка on schedule every 10 hour do select get_lock("test_lock2", 20);
--echo "Let some time pass to the event starts"
--sleep 2
--sleep 1
--echo "Should have only 2 processes: the scheduler and the locked event"
select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;--echo "Release the mutex, the event worker should finish."
--echo "Release the mutex, the event worker should finish."
......@@ -409,7 +333,6 @@ create event white_space on schedule every 10 hour disable do
select 2;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
drop event white_space;
create event white_space on schedule every 10 hour disable do select 3;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
......
......@@ -570,7 +570,7 @@ DROP PROCEDURE create_log_tables;
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 '',
name char(64) CHARACTER SET utf8 NOT NULL default '',
body longblob NOT NULL,
definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
execute_at DATETIME default NULL,
......@@ -636,7 +636,7 @@ SELECT @hadEventPriv :=1 FROM user WHERE Event_priv LIKE '%';
ALTER TABLE user add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv;
ALTER TABLE db add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL;
ALTER TABLE event DROP PRIMARY KEY;
ALTER TABLE event ADD PRIMARY KEY(definer, db, name);
ALTER TABLE event ADD PRIMARY KEY(db, name);
ALTER TABLE event ADD sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
......
This diff is collapsed.
......@@ -85,7 +85,7 @@ class Events
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
static int
show_create_event(THD *thd, sp_name *spn, LEX_STRING definer);
show_create_event(THD *thd, sp_name *spn);
static int
reconstruct_interval_expression(String *buf, interval_type interval,
......
......@@ -33,7 +33,6 @@ my_time_compare(TIME *a, TIME *b);
int
evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname,
const LEX_STRING ev_name,
const LEX_STRING user_name,
TABLE *table);
int
......@@ -43,8 +42,8 @@ int
db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
uint *rows_affected);
int
db_find_event(THD *thd, sp_name *name, LEX_STRING *definer, Event_timed **ett,
TABLE *tbl, MEM_ROOT *root);
db_find_event(THD *thd, sp_name *name, Event_timed **ett, TABLE *tbl,
MEM_ROOT *root);
int
db_create_event(THD *thd, Event_timed *et, my_bool create_if_not,
......
......@@ -1292,11 +1292,17 @@ Event_scheduler::run(THD *thd)
/* Skip disabled events */
if (et->status != Event_timed::ENABLED)
{
sql_print_error("SCHEDULER: Found a disabled event %*s.%*s in the queue",
et->dbname.length, et->dbname.str, et->name.length,
et->name.str);
/*
It could be a one-timer scheduled for a time, already in the past when the
scheduler was suspended.
*/
sql_print_information("SCHEDULER: Found a disabled event %*s.%*s in the queue",
et->dbname.length, et->dbname.str, et->name.length,
et->name.str);
queue_remove(&queue, 0);
/* ToDo: check this again */
if (et->dropped)
et->drop(thd);
delete et;
UNLOCK_SCHEDULER_DATA();
continue;
......@@ -1805,7 +1811,10 @@ Event_scheduler::check_n_suspend_if_needed(THD *thd)
DBUG_PRINT("info", ("We have to recompute the execution times"));
for (i= 0; i < queue.elements; i++)
{
((Event_timed*)queue_element(&queue, i))->compute_next_execution_time();
((Event_timed*)queue_element(&queue, i))->update_fields(thd);
}
queue_fix(&queue);
}
/* This will implicitly unlock LOCK_scheduler_data */
......@@ -2050,8 +2059,7 @@ Event_scheduler::load_event(THD *thd, Event_timed *etn, Event_timed **etn_new)
/* No need to use my_error() here because db_find_event() has done it */
{
sp_name spn(etn->dbname, etn->name);
ret= db_find_event(thd, &spn, &etn->definer, &et_loaded, NULL,
&scheduler_root);
ret= db_find_event(thd, &spn, &et_loaded, NULL, &scheduler_root);
}
thd->restore_backup_open_tables_state(&backup);
/* In this case no memory was allocated so we don't need to clean */
......
......@@ -961,7 +961,7 @@ Event_timed::compute_next_execution_time()
}
goto ret;
}
current_thd->end_time();
my_tz_UTC->gmt_sec_to_TIME(&time_now, current_thd->query_start());
DBUG_PRINT("info",("NOW=[%llu]", TIME_to_ulonglong_datetime(&time_now)));
......@@ -975,6 +975,7 @@ Event_timed::compute_next_execution_time()
execute_at_null= TRUE;
if (on_completion == Event_timed::ON_COMPLETION_DROP)
dropped= true;
DBUG_PRINT("info", ("Dropped=%d", dropped));
status= Event_timed::DISABLED;
status_changed= true;
......@@ -1225,7 +1226,7 @@ Event_timed::update_fields(THD *thd)
{
TABLE *table;
Open_tables_state backup;
int ret= 0;
int ret;
DBUG_ENTER("Event_timed::update_time_fields");
......@@ -1233,7 +1234,7 @@ Event_timed::update_fields(THD *thd)
/* No need to update if nothing has changed */
if (!(status_changed || last_executed_changed))
goto done;
DBUG_RETURN(0);
thd->reset_n_backup_open_tables_state(&backup);
......@@ -1244,7 +1245,7 @@ Event_timed::update_fields(THD *thd)
}
if ((ret= evex_db_find_event_by_name(thd, dbname, name, definer, table)))
if ((ret= evex_db_find_event_by_name(thd, dbname, name, table)))
goto done;
store_record(table,record[1]);
......
......@@ -3837,16 +3837,16 @@ mysql_execute_command(THD *thd)
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
res= Events::create_event(thd, lex->et,
(uint) lex->create_info.options,
&rows_affected);
(uint) lex->create_info.options,
&rows_affected);
break;
case SQLCOM_ALTER_EVENT:
res= Events::update_event(thd, lex->et, lex->spname,
&rows_affected);
&rows_affected);
break;
case SQLCOM_DROP_EVENT:
res= Events::drop_event(thd, lex->et, lex->drop_if_exists,
&rows_affected);
&rows_affected);
default:;
}
DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d",
......@@ -3884,7 +3884,7 @@ mysql_execute_command(THD *thd)
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
goto error;
}
res= Events::show_create_event(thd, lex->spname, lex->et->definer);
res= Events::show_create_event(thd, lex->spname);
break;
}
#ifndef DBUG_OFF
......
This diff is collapsed.
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