mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1-new-ndb
into whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-single-user
This commit is contained in:
commit
0507590a51
43 changed files with 3035 additions and 1905 deletions
|
@ -1,4 +1,8 @@
|
|||
create database if not exists events_test;
|
||||
drop database if exists events_test;
|
||||
drop database if exists db_x;
|
||||
drop database if exists mysqltest_db2;
|
||||
drop database if exists mysqltest_no_such_database;
|
||||
create database events_test;
|
||||
use events_test;
|
||||
CREATE USER pauline@localhost;
|
||||
CREATE DATABASE db_x;
|
||||
|
@ -223,73 +227,180 @@ drop event root19;
|
|||
drop event root20;
|
||||
drop event ðóóò21;
|
||||
set names latin1;
|
||||
Create a test event. Only event metadata is relevant,
|
||||
the actual schedule and body are not.
|
||||
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
|
||||
Try to alter mysql.event: the server should fail to load
|
||||
event information after mysql.event was tampered with.
|
||||
|
||||
First, let's add a column to the end and make sure everything
|
||||
works as before
|
||||
|
||||
ALTER TABLE mysql.event ADD dummy INT;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
event_name
|
||||
intact_check
|
||||
SHOW CREATE EVENT intact_check;
|
||||
Event sql_mode time_zone Create Event
|
||||
intact_check SYSTEM CREATE EVENT `intact_check` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO SELECT "nothing"
|
||||
DROP EVENT no_such_event;
|
||||
ERROR HY000: Unknown event 'no_such_event'
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
DROP EVENT intact_check_1;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
DROP EVENT intact_check_2;
|
||||
DROP EVENT intact_check;
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'mysqltest_no_such_database'; database doesn't exist
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
@@event_scheduler
|
||||
OFF
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
ALTER TABLE mysql.event DROP dummy;
|
||||
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
|
||||
|
||||
Now let's add a column to the first position: the server
|
||||
expects to see event schema name there
|
||||
|
||||
ALTER TABLE mysql.event ADD dummy INT FIRST;
|
||||
SHOW EVENTS;
|
||||
ERROR HY000: Column count of mysql.event is wrong. Expected 18, found 19. The table is 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 18, found 19. The table is probably corrupted
|
||||
ALTER TABLE mysql.event DROP dummy2;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
SHOW CREATE EVENT intact_check;
|
||||
ERROR HY000: Unknown event 'intact_check'
|
||||
DROP EVENT no_such_event;
|
||||
ERROR HY000: Unknown event 'no_such_event'
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
DROP EVENT intact_check_1;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
DROP EVENT intact_check_2;
|
||||
ERROR HY000: Unknown event 'intact_check_2'
|
||||
DROP EVENT intact_check;
|
||||
ERROR HY000: Unknown event 'intact_check'
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'mysqltest_no_such_database'; database doesn't exist
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
@@event_scheduler
|
||||
OFF
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
Clean up
|
||||
ALTER TABLE mysql.event DROP dummy;
|
||||
DELETE FROM mysql.event;
|
||||
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
|
||||
Back up the table, further changes are not reversible
|
||||
CREATE TABLE event_like LIKE mysql.event;
|
||||
INSERT INTO event_like SELECT * FROM mysql.event;
|
||||
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. The table is probably corrupted. Please see the error log for details
|
||||
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) 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','SLAVESIDE_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 '',
|
||||
`originator` int(10) NOT NULL,
|
||||
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
||||
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. The table is probably corrupted. Please see the error log for details
|
||||
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
|
||||
"This should work"
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
|
||||
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. The table is probably corrupted. Please see the error log for details
|
||||
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. The table is probably corrupted. Please see the error log for details
|
||||
|
||||
Drop some columns and try more checks.
|
||||
|
||||
|
||||
ALTER TABLE mysql.event DROP comment, DROP starts;
|
||||
SHOW EVENTS;
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
SHOW CREATE EVENT intact_check;
|
||||
ERROR HY000: Cannot load from mysql.event. The table is probably corrupted
|
||||
DROP EVENT no_such_event;
|
||||
ERROR HY000: Unknown event 'no_such_event'
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
ERROR HY000: Column count of mysql.event is wrong. Expected 18, found 16. The table is probably corrupted
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
DROP EVENT intact_check_1;
|
||||
ERROR HY000: Unknown event 'intact_check_1'
|
||||
DROP EVENT intact_check_2;
|
||||
ERROR HY000: Unknown event 'intact_check_2'
|
||||
DROP EVENT intact_check;
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'mysqltest_no_such_database'; database doesn't exist
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
@@event_scheduler
|
||||
OFF
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
|
||||
Now drop the table, and test again
|
||||
|
||||
|
||||
DROP TABLE mysql.event;
|
||||
SHOW EVENTS;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
SHOW CREATE EVENT intact_check;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
DROP EVENT no_such_event;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
DROP EVENT intact_check_1;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
DROP EVENT intact_check_2;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
DROP EVENT intact_check;
|
||||
ERROR 42S02: Table 'mysql.event' doesn't exist
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'mysqltest_no_such_database'; database doesn't exist
|
||||
Error 1146 Table 'mysql.event' doesn't exist
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
OK, there is an unnecessary warning about the non-existent table
|
||||
but it's not easy to fix and no one complained about it.
|
||||
A similar warning is printed if mysql.proc is missing.
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 1146 Table 'mysql.event' doesn't exist
|
||||
SELECT @@event_scheduler;
|
||||
@@event_scheduler
|
||||
OFF
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
Restore the original table.
|
||||
CREATE TABLE mysql.event like event_like;
|
||||
INSERT INTO mysql.event SELECT * FROM event_like;
|
||||
DROP TABLE event_like;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
|
||||
DROP EVENT intact_check;
|
||||
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
|
||||
|
@ -402,4 +513,196 @@ SHOW EVENTS FROM ``;
|
|||
ERROR 42000: Incorrect database name ''
|
||||
SHOW EVENTS FROM `events\\test`;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
|
||||
LOCK TABLES mode.
|
||||
|
||||
create table t1 (a int);
|
||||
create event e1 on schedule every 10 hour do select 1;
|
||||
lock table t1 read;
|
||||
show create event e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 SYSTEM CREATE EVENT `e1` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO select 1
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
e1
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
alter event e2 disable;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
alter event e2 rename to e3;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
drop event e2;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
drop event e1;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
unlock tables;
|
||||
lock table t1 write;
|
||||
show create event e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 SYSTEM CREATE EVENT `e1` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO select 1
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
e1
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
alter event e2 disable;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
alter event e2 rename to e3;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
drop event e2;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
drop event e1;
|
||||
ERROR HY000: Table 'event' was not locked with LOCK TABLES
|
||||
unlock tables;
|
||||
lock table t1 read, mysql.event read;
|
||||
show create event e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 SYSTEM CREATE EVENT `e1` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO select 1
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
e1
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
alter event e2 disable;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
alter event e2 rename to e3;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
drop event e2;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
drop event e1;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
unlock tables;
|
||||
lock table t1 write, mysql.event read;
|
||||
show create event e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 SYSTEM CREATE EVENT `e1` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO select 1
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
e1
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
alter event e2 disable;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
alter event e2 rename to e3;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
drop event e2;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
drop event e1;
|
||||
ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
|
||||
unlock tables;
|
||||
lock table t1 read, mysql.event write;
|
||||
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
|
||||
lock table t1 write, mysql.event write;
|
||||
ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
|
||||
lock table mysql.event write;
|
||||
show create event e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 SYSTEM CREATE EVENT `e1` ON SCHEDULE EVERY 10 HOUR STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO select 1
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
e1
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
alter event e2 disable;
|
||||
alter event e2 rename to e3;
|
||||
drop event e3;
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
Make sure we have left no events
|
||||
select event_name from information_schema.events;
|
||||
event_name
|
||||
|
||||
Events in sub-statements, events and prelocking
|
||||
|
||||
|
||||
create event e1 on schedule every 10 hour do select 1;
|
||||
create function f1() returns int
|
||||
begin
|
||||
show create event e1;
|
||||
return 1;
|
||||
end|
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
show create event e1;
|
||||
end|
|
||||
ERROR 0A000: Not allowed to return a result set from a trigger
|
||||
create function f1() returns int
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
return 1;
|
||||
end|
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
end|
|
||||
ERROR 0A000: Not allowed to return a result set from a trigger
|
||||
create function f1() returns int
|
||||
begin
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
return 1;
|
||||
end|
|
||||
ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present
|
||||
create function f1() returns int
|
||||
begin
|
||||
alter event e1 rename to e2;
|
||||
return 1;
|
||||
end|
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
create function f1() returns int
|
||||
begin
|
||||
drop event e2;
|
||||
return 1;
|
||||
end|
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
----------------------------------------------------------------------
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
set new.a= f1();
|
||||
end|
|
||||
create function f1() returns int
|
||||
begin
|
||||
call p1();
|
||||
return 0;
|
||||
end|
|
||||
create procedure p1()
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
end|
|
||||
insert into t1 (a) values (1)|
|
||||
ERROR 0A000: Not allowed to return a result set from a trigger
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
show create event e1;
|
||||
end|
|
||||
insert into t1 (a) values (1)|
|
||||
ERROR 0A000: Not allowed to return a result set from a trigger
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
create temporary table tmp select event_name from information_schema.events;
|
||||
end|
|
||||
expected to work, since we redirect the output into a tmp table
|
||||
insert into t1 (a) values (1)|
|
||||
select * from tmp|
|
||||
event_name
|
||||
e1
|
||||
drop temporary table tmp|
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
alter event e1 rename to e2;
|
||||
end|
|
||||
insert into t1 (a) values (1)|
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
drop event e1;
|
||||
end|
|
||||
insert into t1 (a) values (1)|
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
drop table t1|
|
||||
drop event e1|
|
||||
drop database events_test;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
create database if not exists events_test;
|
||||
drop database if exists events_test;
|
||||
drop database if exists mysqltest_db1;
|
||||
drop database if exists mysqltest_db2;
|
||||
create database events_test;
|
||||
use events_test;
|
||||
CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1;
|
||||
CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2;
|
||||
|
@ -381,4 +384,149 @@ ERROR 42000: Access denied; you need the SUPER privilege for this operation
|
|||
DROP EVENT e1;
|
||||
ERROR HY000: Unknown event 'e1'
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
SET GLOBAL EVENT_SCHEDULER= OFF;
|
||||
SET @save_time_zone= @@TIME_ZONE;
|
||||
SET TIME_ZONE= '+00:00';
|
||||
SET TIMESTAMP= UNIX_TIMESTAMP('2005-12-31 23:58:59');
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost +00:00 RECURRING NULL 1 DAY 2005-12-31 23:58:59 NULL ENABLED 1
|
||||
SET TIME_ZONE= '-01:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 00:00:00';
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost -01:00 RECURRING NULL 1 DAY 2000-01-01 00:00:00 NULL ENABLED 1
|
||||
SET TIME_ZONE= '+02:00';
|
||||
ALTER EVENT e1 ON SCHEDULE AT '2000-01-02 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost +02:00 ONE TIME 2000-01-02 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
SET TIME_ZONE= '-03:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY ENDS '2030-01-03 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 DISABLED 1
|
||||
SET TIME_ZONE= '+04:00';
|
||||
ALTER EVENT e1 DO SELECT 2;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 ENABLED 1
|
||||
DROP EVENT e1;
|
||||
SET TIME_ZONE='+05:00';
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
SET TIME_ZONE='-05:00';
|
||||
CREATE EVENT e2 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
SET TIME_ZONE='+00:00';
|
||||
CREATE EVENT e3 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SELECT * FROM INFORMATION_SCHEMA.EVENTS ORDER BY event_name;
|
||||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR
|
||||
NULL events_test e1 root@localhost +05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:58:59 2005-12-31 23:58:59 NULL 1
|
||||
NULL events_test e2 root@localhost -05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:00 2005-12-31 23:59:00 NULL 1
|
||||
NULL events_test e3 root@localhost +00:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:01 2005-12-31 23:59:01 NULL 1
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
SHOW CREATE EVENT e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 +05:00 CREATE EVENT `e1` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
SHOW CREATE EVENT e2;
|
||||
Event sql_mode time_zone Create Event
|
||||
e2 -05:00 CREATE EVENT `e2` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
SHOW CREATE EVENT e3;
|
||||
Event sql_mode time_zone Create Event
|
||||
e3 +00:00 CREATE EVENT `e3` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
The following should fail, and nothing should be altered.
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00';
|
||||
ERROR HY000: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been altered
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE;
|
||||
ERROR HY000: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been altered
|
||||
The following should give warnings, and nothing should be created.
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00'
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
The following should succeed giving a warning.
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
CREATE EVENT e5 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
The following should succeed without warnings.
|
||||
ALTER EVENT e2 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00';
|
||||
ALTER EVENT e3 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE;
|
||||
CREATE EVENT e6 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
CREATE EVENT e7 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
CREATE EVENT e8 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
events_test e1 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
events_test e2 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e3 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
events_test e4 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
events_test e5 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
events_test e6 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1
|
||||
events_test e7 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
events_test e8 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
DROP EVENT e8;
|
||||
DROP EVENT e7;
|
||||
DROP EVENT e6;
|
||||
DROP EVENT e5;
|
||||
DROP EVENT e4;
|
||||
DROP EVENT e3;
|
||||
DROP EVENT e2;
|
||||
DROP EVENT e1;
|
||||
SET TIME_ZONE=@save_time_zone;
|
||||
drop database events_test;
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
create database if not exists mysqltest_events_test;
|
||||
use mysqltest_events_test;
|
||||
set global event_scheduler=off;
|
||||
drop database if exists events_test;
|
||||
create database events_test;
|
||||
use events_test;
|
||||
create table execution_log(name char(10));
|
||||
create event abc1 on schedule every 1 second do insert into execution_log value('abc1');
|
||||
create event abc2 on schedule every 1 second do insert into execution_log value('abc2');
|
||||
create event abc3 on schedule every 1 second do insert into execution_log value('abc3');
|
||||
select name from execution_log;
|
||||
name
|
||||
insert into mysql.event values ('db1','bad','select 42','root@localhost',NULL,1000,'MICROSECOND','2006-05-05 17:39:11','2006-05-05 17:39:20','2016-05-05 15:39:24','2016-05-05 15:39:11',NULL,'ENABLED','DROP','','comment1',1,'SYSTEM');
|
||||
insert into mysql.event values ('db1','bad2','sect','root@localhost',NULL,1000,'SECOND','2006-05-05 17:39:11','2006-05-05 17:39:20','2016-05-05 15:39:24','2016-05-05 15:39:11',NULL,'ENABLED','DROP','','comment2',1,'SYSTEM');
|
||||
create event abc1 on schedule every 1 second do
|
||||
insert into execution_log value('abc1');
|
||||
create event abc2 on schedule every 1 second do
|
||||
insert into execution_log value('abc2');
|
||||
create event abc3 on schedule every 1 second do
|
||||
insert into execution_log value('abc3');
|
||||
create table event_like like mysql.event;
|
||||
insert into event_like select * from mysql.event;
|
||||
alter table mysql.event
|
||||
change column body body longtext character set utf8 collate utf8_bin;
|
||||
"Now we restart the server"
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
use mysqltest_events_test;
|
||||
"Should get 0 rows because the queue aborted run
|
||||
select distinct name from execution_log order by name;
|
||||
name
|
||||
delete from mysql.event where name like 'bad%';
|
||||
"Now restart the server again"
|
||||
use events_test;
|
||||
select @@event_scheduler;
|
||||
@@event_scheduler
|
||||
DISABLED
|
||||
show events;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
select event_name from information_schema.events;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
show create event intact_check;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
drop event no_such_event;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
create event intact_check_1 on schedule every 5 hour do select 5;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
alter event intact_check_1 on schedule every 8 hour do select 8;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
alter event intact_check_1 rename to intact_check_2;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
drop event intact_check_1;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
drop event intact_check_2;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
drop event intact_check;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
set global event_scheduler=on;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
set global event_scheduler=off;
|
||||
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
|
||||
show variables like 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler DISABLED
|
||||
Make sure that we still can create and drop databases,
|
||||
and no warnings are produced.
|
||||
drop database if exists mysqltest_database_not_exists;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'mysqltest_database_not_exists'; database doesn't exist
|
||||
create database mysqltest_db1;
|
||||
drop database mysqltest_db1;
|
||||
Restore the original mysql.event table
|
||||
drop table mysql.event;
|
||||
rename table event_like to mysql.event;
|
||||
Now let's restart the server again
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use mysqltest_events_test;
|
||||
use events_test;
|
||||
select @@event_scheduler;
|
||||
@@event_scheduler
|
||||
ON
|
||||
"Should get 3 rows : abc1, abc2, abc3
|
||||
select distinct name from execution_log order by name;
|
||||
name
|
||||
abc1
|
||||
abc2
|
||||
abc3
|
||||
drop event abc1;
|
||||
drop event abc2;
|
||||
drop event abc3;
|
||||
drop table execution_log;
|
||||
drop database mysqltest_events_test;
|
||||
drop database events_test;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
CREATE DATABASE IF NOT EXISTS events_test;
|
||||
USE events_test;
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
Try agian to make sure it's allowed
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
|
@ -13,6 +15,8 @@ SHOW VARIABLES LIKE 'event_scheduler';
|
|||
Variable_name Value
|
||||
event_scheduler OFF
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
Try again to make sure it's allowed
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
Variable_name Value
|
||||
event_scheduler ON
|
||||
|
@ -40,44 +44,56 @@ CREATE TABLE table_1(a int);
|
|||
CREATE TABLE table_2(a int);
|
||||
CREATE TABLE table_3(a int);
|
||||
CREATE TABLE table_4(a int);
|
||||
CREATE TABLE T19170(s1 TIMESTAMP);
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
|
||||
CREATE EVENT start_n_end
|
||||
ON SCHEDULE EVERY 1 SECOND
|
||||
CREATE EVENT event_1 ON SCHEDULE EVERY 2 SECOND
|
||||
DO
|
||||
INSERT INTO table_1 VALUES (1);
|
||||
CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND
|
||||
ENDS NOW() + INTERVAL 6 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO INSERT INTO table_2 VALUES(1);
|
||||
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND ON COMPLETION PRESERVE DO INSERT INTO table_4 VALUES(1);
|
||||
DO
|
||||
INSERT INTO table_2 VALUES (1);
|
||||
CREATE EVENT event_3 ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND
|
||||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
INSERT INTO table_3 VALUES (1);
|
||||
CREATE EVENT event_4 ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
INSERT INTO table_4 VALUES (1);
|
||||
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
|
||||
IF(SUM(a) >= 4, 'OK', 'ERROR')
|
||||
OK
|
||||
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
|
||||
IF(SUM(a) >= 5, 'OK', 'ERROR')
|
||||
OK
|
||||
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
|
||||
IF(SUM(a) > 0, 'OK', 'ERROR')
|
||||
SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_3;
|
||||
IF(SUM(a) >= 1, 'OK', 'ERROR')
|
||||
OK
|
||||
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
|
||||
IF(SUM(a) > 0, 'OK', 'ERROR')
|
||||
SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_4;
|
||||
IF(SUM(a) >= 1, 'OK', 'ERROR')
|
||||
OK
|
||||
DROP EVENT two_sec;
|
||||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
|
||||
FROM INFORMATION_SCHEMA.EVENTS
|
||||
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
|
||||
IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
|
||||
OK
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
|
||||
FROM INFORMATION_SCHEMA.EVENTS
|
||||
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
|
||||
IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
|
||||
OK
|
||||
DROP EVENT IF EXISTS events_test.start_n_end;
|
||||
"Already dropped because ended. Therefore an error."
|
||||
DROP EVENT only_one_time;
|
||||
ERROR HY000: Unknown event 'only_one_time'
|
||||
DROP EVENT event_3;
|
||||
ERROR HY000: Unknown event 'event_3'
|
||||
DROP EVENT event_1;
|
||||
"Should be preserved"
|
||||
SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME;
|
||||
EVENT_NAME STATUS
|
||||
two_time DISABLED
|
||||
DROP EVENT two_time;
|
||||
event_2 DISABLED
|
||||
event_4 DISABLED
|
||||
DROP EVENT event_2;
|
||||
DROP EVENT event_4;
|
||||
DROP TABLE table_1;
|
||||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
|
|
|
@ -3,148 +3,6 @@ CREATE DATABASE mysqltest_db1;
|
|||
USE mysqltest_db1;
|
||||
SET GLOBAL EVENT_SCHEDULER= OFF;
|
||||
SET @save_time_zone= @@TIME_ZONE;
|
||||
SET TIME_ZONE= '+00:00';
|
||||
SET TIMESTAMP= UNIX_TIMESTAMP('2005-12-31 23:58:59');
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost +00:00 RECURRING NULL 1 DAY 2005-12-31 23:58:59 NULL ENABLED 1
|
||||
SET TIME_ZONE= '-01:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 00:00:00';
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost -01:00 RECURRING NULL 1 DAY 2000-01-01 00:00:00 NULL ENABLED 1
|
||||
SET TIME_ZONE= '+02:00';
|
||||
ALTER EVENT e1 ON SCHEDULE AT '2000-01-02 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost +02:00 ONE TIME 2000-01-02 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
SET TIME_ZONE= '-03:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY ENDS '2030-01-03 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 DISABLED 1
|
||||
SET TIME_ZONE= '+04:00';
|
||||
ALTER EVENT e1 DO SELECT 2;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost -03:00 RECURRING NULL 1 DAY 2005-12-31 20:58:59 2030-01-03 00:00:00 ENABLED 1
|
||||
DROP EVENT e1;
|
||||
SET TIME_ZONE='+05:00';
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
SET TIME_ZONE='-05:00';
|
||||
CREATE EVENT e2 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
SET TIME_ZONE='+00:00';
|
||||
CREATE EVENT e3 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
SELECT * FROM INFORMATION_SCHEMA.EVENTS;
|
||||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER TIME_ZONE EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD SQL_MODE STARTS ENDS STATUS ON_COMPLETION CREATED LAST_ALTERED LAST_EXECUTED EVENT_COMMENT ORIGINATOR
|
||||
NULL mysqltest_db1 e1 root@localhost +05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:58:59 2005-12-31 23:58:59 NULL 1
|
||||
NULL mysqltest_db1 e2 root@localhost -05:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:00 2005-12-31 23:59:00 NULL 1
|
||||
NULL mysqltest_db1 e3 root@localhost +00:00 SQL SELECT 1 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED NOT PRESERVE 2005-12-31 23:59:01 2005-12-31 23:59:01 NULL 1
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
SHOW CREATE EVENT e1;
|
||||
Event sql_mode time_zone Create Event
|
||||
e1 +05:00 CREATE EVENT `e1` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
SHOW CREATE EVENT e2;
|
||||
Event sql_mode time_zone Create Event
|
||||
e2 -05:00 CREATE EVENT `e2` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
SHOW CREATE EVENT e3;
|
||||
Event sql_mode time_zone Create Event
|
||||
e3 +00:00 CREATE EVENT `e3` ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1
|
||||
The following should fail, and nothing should be altered.
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00';
|
||||
ERROR HY000: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been altered
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE;
|
||||
ERROR HY000: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been altered
|
||||
The following should give warnings, and nothing should be created.
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00'
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1584 Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. Event has not been created
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost +05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e2 root@localhost -05:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e3 root@localhost +00:00 RECURRING NULL 1 DAY 2006-01-01 00:00:00 NULL ENABLED 1
|
||||
The following should succeed giving a warning.
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
CREATE EVENT e5 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
Warnings:
|
||||
Note 1533 Event execution time is in the past. Event has been disabled
|
||||
The following should succeed without warnings.
|
||||
ALTER EVENT e2 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00';
|
||||
ALTER EVENT e3 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE;
|
||||
CREATE EVENT e6 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
CREATE EVENT e7 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
CREATE EVENT e8 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
SHOW EVENTS;
|
||||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
|
||||
mysqltest_db1 e1 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
mysqltest_db1 e2 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e3 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
mysqltest_db1 e4 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
mysqltest_db1 e5 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
mysqltest_db1 e6 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 NULL ENABLED 1
|
||||
mysqltest_db1 e7 root@localhost +00:00 RECURRING NULL 1 HOUR 1999-01-01 00:00:00 1999-01-02 00:00:00 DISABLED 1
|
||||
mysqltest_db1 e8 root@localhost +00:00 ONE TIME 1999-01-01 00:00:00 NULL NULL NULL NULL DISABLED 1
|
||||
DROP EVENT e8;
|
||||
DROP EVENT e7;
|
||||
DROP EVENT e6;
|
||||
DROP EVENT e5;
|
||||
DROP EVENT e4;
|
||||
DROP EVENT e3;
|
||||
DROP EVENT e2;
|
||||
DROP EVENT e1;
|
||||
CREATE TABLE t_step (step INT);
|
||||
INSERT INTO t_step VALUES (@step);
|
||||
CREATE FUNCTION round_to_step(i INT, n INT) RETURNS INT
|
||||
|
|
159
mysql-test/r/events_trans.result
Normal file
159
mysql-test/r/events_trans.result
Normal file
|
@ -0,0 +1,159 @@
|
|||
drop database if exists events_test;
|
||||
drop database if exists mysqltest_db2;
|
||||
drop database if exists mysqltest_no_such_database;
|
||||
create database events_test;
|
||||
use events_test;
|
||||
|
||||
Test that Events DDL issue an implicit COMMIT
|
||||
|
||||
|
||||
set autocommit=off;
|
||||
select @@autocommit;
|
||||
@@autocommit
|
||||
0
|
||||
create table t1 (a varchar(255)) engine=innodb;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event");
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: create event
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event");
|
||||
alter event e1 on schedule every 2 day do select 2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: alter event
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename");
|
||||
alter event e1 rename to e2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: alter event rename
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event");
|
||||
drop event e2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: drop event
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event if exists");
|
||||
drop event if exists e2;
|
||||
Warnings:
|
||||
Note 1305 Event e2 does not exist
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: drop event if exists
|
||||
delete from t1;
|
||||
commit work;
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event if not exists");
|
||||
create event if not exists e1 on schedule every 2 day do select 2;
|
||||
Warnings:
|
||||
Note 1526 Event 'e1' already exists
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: create event if not exists
|
||||
delete from t1;
|
||||
commit work;
|
||||
|
||||
Now check various error conditions: make sure we issue an
|
||||
implicit commit anyway
|
||||
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: event already exists");
|
||||
create event e1 on schedule every 2 day do select 2;
|
||||
ERROR HY000: Event 'e1' already exists
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: create event: event already exists
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename: rename to same name");
|
||||
alter event e1 rename to e1;
|
||||
ERROR HY000: Same old and new event name
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: alter event rename: rename to same name
|
||||
delete from t1;
|
||||
commit work;
|
||||
create event e2 on schedule every 3 day do select 3;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename: destination exists");
|
||||
alter event e2 rename to e1;
|
||||
ERROR HY000: Event 'e1' already exists
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: alter event rename: destination exists
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: database does not exist");
|
||||
create event mysqltest_no_such_database.e1 on schedule every 1 day do select 1;
|
||||
ERROR 42000: Unknown database 'mysqltest_no_such_database'
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: create event: database does not exist
|
||||
delete from t1;
|
||||
commit work;
|
||||
grant create, insert, select, delete on mysqltest_db2.*
|
||||
to mysqltest_user1@localhost;
|
||||
create database mysqltest_db2;
|
||||
set autocommit=off;
|
||||
select @@autocommit;
|
||||
@@autocommit
|
||||
0
|
||||
create table t1 (a varchar(255)) engine=innodb;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: insufficient privileges");
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
ERROR 42000: Access denied for user 'mysqltest_user1'@'localhost' to database 'mysqltest_db2'
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: create event: insufficient privileges
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event: insufficient privileges");
|
||||
alter event e1 on schedule every 1 day do select 1;
|
||||
ERROR 42000: Access denied for user 'mysqltest_user1'@'localhost' to database 'mysqltest_db2'
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: alter event: insufficient privileges
|
||||
delete from t1;
|
||||
commit work;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event: insufficient privileges");
|
||||
drop event e1;
|
||||
ERROR 42000: Access denied for user 'mysqltest_user1'@'localhost' to database 'mysqltest_db2'
|
||||
rollback work;
|
||||
select * from t1;
|
||||
a
|
||||
OK: drop event: insufficient privileges
|
||||
delete from t1;
|
||||
commit work;
|
||||
drop user mysqltest_user1@localhost;
|
||||
drop database mysqltest_db2;
|
||||
drop database events_test;
|
|
@ -1408,7 +1408,6 @@ select user,db from information_schema.processlist;
|
|||
user db
|
||||
user3148 test
|
||||
drop user user3148@localhost;
|
||||
DROP TABLE IF EXISTS thread_status;
|
||||
DROP TABLE IF EXISTS server_status;
|
||||
DROP EVENT IF EXISTS event_status;
|
||||
SET GLOBAL event_scheduler=1;
|
||||
|
@ -1417,26 +1416,16 @@ ON SCHEDULE AT NOW()
|
|||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
BEGIN
|
||||
CREATE TABLE thread_status
|
||||
SELECT variable_name, variable_value
|
||||
FROM information_schema.session_status
|
||||
WHERE variable_name LIKE 'SSL_ACCEPTS' OR
|
||||
variable_name LIKE 'SSL_CALLBACK_CACHE_HITS';
|
||||
CREATE TABLE server_status
|
||||
SELECT variable_name
|
||||
FROM information_schema.global_status
|
||||
WHERE variable_name LIKE 'ABORTED_CONNECTS' OR
|
||||
variable_name LIKE 'BINLOG_CACHE_DISK_USE';
|
||||
END$$
|
||||
SELECT variable_name, variable_value FROM thread_status;
|
||||
variable_name variable_value
|
||||
SSL_ACCEPTS 0.0000000
|
||||
SSL_CALLBACK_CACHE_HITS 0.0000000
|
||||
SELECT variable_name FROM server_status;
|
||||
variable_name
|
||||
ABORTED_CONNECTS
|
||||
BINLOG_CACHE_DISK_USE
|
||||
DROP TABLE thread_status;
|
||||
DROP TABLE server_status;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
End of 5.1 tests.
|
||||
|
|
|
@ -53,3 +53,25 @@ SSL error: Unable to get certificate from ''
|
|||
mysqltest: Could not open connection 'default': 2026 SSL connection error
|
||||
Variable_name Value
|
||||
Ssl_cipher DHE-RSA-AES256-SHA
|
||||
End of 5.0 tests
|
||||
DROP TABLE IF EXISTS thread_status;
|
||||
DROP EVENT IF EXISTS event_status;
|
||||
SET GLOBAL event_scheduler=1;
|
||||
CREATE EVENT event_status
|
||||
ON SCHEDULE AT NOW()
|
||||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
BEGIN
|
||||
CREATE TABLE thread_status
|
||||
SELECT variable_name, variable_value
|
||||
FROM information_schema.session_status
|
||||
WHERE variable_name LIKE 'SSL_ACCEPTS' OR
|
||||
variable_name LIKE 'SSL_CALLBACK_CACHE_HITS';
|
||||
END$$
|
||||
SELECT variable_name, variable_value FROM thread_status;
|
||||
variable_name variable_value
|
||||
SSL_ACCEPTS 0.0000000
|
||||
SSL_CALLBACK_CACHE_HITS 0.0000000
|
||||
DROP TABLE thread_status;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
End of 5.1 tests
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
SHOW STATUS LIKE 'Ssl%';
|
||||
Variable_name Value
|
||||
Ssl_accepts 1
|
||||
Ssl_finished_accepts 1
|
||||
Ssl_finished_connects 0
|
||||
Ssl_accept_renegotiates 0
|
||||
Ssl_connect_renegotiates 0
|
||||
Ssl_callback_cache_hits 0
|
||||
Ssl_session_cache_hits 0
|
||||
Ssl_session_cache_misses 0
|
||||
Ssl_session_cache_timeouts 0
|
||||
Ssl_used_session_cache_entries 1
|
||||
Ssl_client_connects 0
|
||||
Ssl_session_cache_overflows 0
|
||||
Ssl_session_cache_size 128
|
||||
Ssl_session_cache_mode SERVER
|
||||
Ssl_sessions_reused 0
|
||||
Ssl_ctx_verify_mode 7
|
||||
Ssl_ctx_verify_depth 4294967295
|
||||
Ssl_verify_mode 7
|
||||
Ssl_verify_depth 4294967295
|
||||
Ssl_version TLSv1
|
||||
Ssl_cipher EDH-RSA-DES-CBC3-SHA
|
||||
Ssl_cipher_list
|
||||
Ssl_default_timeout 7200
|
|
@ -1,7 +1,13 @@
|
|||
# Can't test with embedded server that doesn't support grants
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
create database if not exists events_test;
|
||||
--disable_warnings
|
||||
drop database if exists events_test;
|
||||
drop database if exists db_x;
|
||||
drop database if exists mysqltest_db2;
|
||||
drop database if exists mysqltest_no_such_database;
|
||||
--enable_warnings
|
||||
create database events_test;
|
||||
use events_test;
|
||||
|
||||
#
|
||||
|
@ -215,62 +221,161 @@ set names latin1;
|
|||
#
|
||||
|
||||
#
|
||||
# mysql.event intact checking start
|
||||
# mysql.event intact checking
|
||||
# Check that the server does not crash if
|
||||
# one has destroyed or tampered with the event table.
|
||||
# Please see see for events_restart_phase* tests to
|
||||
# see the server behavior at start up with bad mysql.event
|
||||
# table.
|
||||
#
|
||||
# There should be at least 1 second between the ALTERs or we can't catch the change of create_time!!
|
||||
#
|
||||
--echo Create a test event. Only event metadata is relevant,
|
||||
--echo the actual schedule and body are not.
|
||||
#
|
||||
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 ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
|
||||
SHOW EVENTS;
|
||||
ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
|
||||
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
|
||||
SHOW EVENTS;
|
||||
ALTER TABLE mysql.event DROP dummy2;
|
||||
#
|
||||
--echo Try to alter mysql.event: the server should fail to load
|
||||
--echo event information after mysql.event was tampered with.
|
||||
--echo
|
||||
--echo First, let's add a column to the end and make sure everything
|
||||
--echo works as before
|
||||
--echo
|
||||
ALTER TABLE mysql.event ADD dummy INT;
|
||||
--replace_column 8 # 9 #
|
||||
SHOW EVENTS;
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
SHOW CREATE EVENT intact_check;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT no_such_event;
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check_1;
|
||||
DROP EVENT intact_check_2;
|
||||
DROP EVENT intact_check;
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
# Clean up
|
||||
ALTER TABLE mysql.event DROP dummy;
|
||||
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
|
||||
--echo
|
||||
--echo Now let's add a column to the first position: the server
|
||||
--echo expects to see event schema name there
|
||||
--echo
|
||||
ALTER TABLE mysql.event ADD dummy INT FIRST;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SHOW EVENTS;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
SHOW CREATE EVENT intact_check;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT no_such_event;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check_1;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check_2;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check;
|
||||
# Should work OK
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
--echo Clean up
|
||||
ALTER TABLE mysql.event DROP dummy;
|
||||
DELETE FROM mysql.event;
|
||||
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
|
||||
--echo Back up the table, further changes are not reversible
|
||||
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.1
|
||||
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
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.1
|
||||
SHOW CREATE TABLE mysql.event;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
--sleep 1.1
|
||||
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
|
||||
--sleep 1.1
|
||||
--echo "This should work"
|
||||
--replace_column 8 # 9 #
|
||||
SHOW EVENTS;
|
||||
--sleep 1.1
|
||||
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
--sleep 1.1
|
||||
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default '';
|
||||
--sleep 1.1
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
--sleep 1.1
|
||||
--echo
|
||||
--echo Drop some columns and try more checks.
|
||||
--echo
|
||||
--echo
|
||||
ALTER TABLE mysql.event DROP comment, DROP starts;
|
||||
--sleep 1.1
|
||||
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SHOW EVENTS;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
|
||||
--error ER_CANNOT_LOAD_FROM_TABLE
|
||||
SHOW CREATE EVENT intact_check;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT no_such_event;
|
||||
--error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check_1;
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT intact_check_2;
|
||||
# Should succeed
|
||||
DROP EVENT intact_check;
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
SELECT @@event_scheduler;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
--echo
|
||||
--echo Now drop the table, and test again
|
||||
--echo
|
||||
--echo
|
||||
DROP TABLE mysql.event;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SHOW EVENTS;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SELECT event_name FROM INFORMATION_SCHEMA.events;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
SHOW CREATE EVENT intact_check;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
DROP EVENT no_such_event;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
CREATE EVENT intact_check_1 ON SCHEDULE EVERY 5 HOUR DO SELECT 5;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
ALTER EVENT intact_check_1 ON SCHEDULE EVERY 8 HOUR DO SELECT 8;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
ALTER EVENT intact_check_1 RENAME TO intact_check_2;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
DROP EVENT intact_check_1;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
DROP EVENT intact_check_2;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
DROP EVENT intact_check;
|
||||
DROP DATABASE IF EXISTS mysqltest_no_such_database;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
--echo OK, there is an unnecessary warning about the non-existent table
|
||||
--echo but it's not easy to fix and no one complained about it.
|
||||
--echo A similar warning is printed if mysql.proc is missing.
|
||||
SHOW WARNINGS;
|
||||
SELECT @@event_scheduler;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
--echo Restore the original table.
|
||||
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
|
||||
#
|
||||
|
@ -424,5 +529,200 @@ SHOW EVENTS FROM aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|||
SHOW EVENTS FROM ``;
|
||||
|
||||
SHOW EVENTS FROM `events\\test`;
|
||||
#
|
||||
# A check for events SQL under LOCK TABLES and in pre-locked mode.
|
||||
#
|
||||
--echo
|
||||
--echo LOCK TABLES mode.
|
||||
--echo
|
||||
#
|
||||
# SHOW CREATE EVENT and INFORMATION_SCHEMA.events are available and
|
||||
# cause an implicit lock/unlock of mysql.event table, regardless of the
|
||||
# currently locked tables.
|
||||
#
|
||||
create table t1 (a int);
|
||||
create event e1 on schedule every 10 hour do select 1;
|
||||
#
|
||||
lock table t1 read;
|
||||
#
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
show create event e1;
|
||||
select event_name from information_schema.events;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
alter event e2 disable;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
alter event e2 rename to e3;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
drop event e2;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
#
|
||||
lock table t1 write;
|
||||
#
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
show create event e1;
|
||||
select event_name from information_schema.events;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
alter event e2 disable;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
alter event e2 rename to e3;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
drop event e2;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
#
|
||||
lock table t1 read, mysql.event read;
|
||||
#
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
show create event e1;
|
||||
select event_name from information_schema.events;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
alter event e2 disable;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
alter event e2 rename to e3;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
drop event e2;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
#
|
||||
lock table t1 write, mysql.event read;
|
||||
#
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
show create event e1;
|
||||
select event_name from information_schema.events;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
alter event e2 disable;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
alter event e2 rename to e3;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
drop event e2;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
#
|
||||
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
|
||||
lock table t1 read, mysql.event write;
|
||||
#
|
||||
--error ER_WRONG_LOCK_OF_SYSTEM_TABLE
|
||||
lock table t1 write, mysql.event write;
|
||||
#
|
||||
lock table mysql.event write;
|
||||
--replace_regex /STARTS '[^']+'/STARTS '#'/
|
||||
show create event e1;
|
||||
select event_name from information_schema.events;
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
alter event e2 disable;
|
||||
alter event e2 rename to e3;
|
||||
drop event e3;
|
||||
drop event e1;
|
||||
unlock tables;
|
||||
--echo Make sure we have left no events
|
||||
select event_name from information_schema.events;
|
||||
--echo
|
||||
--echo Events in sub-statements, events and prelocking
|
||||
--echo
|
||||
--echo
|
||||
create event e1 on schedule every 10 hour do select 1;
|
||||
delimiter |;
|
||||
--error ER_SP_NO_RETSET
|
||||
create function f1() returns int
|
||||
begin
|
||||
show create event e1;
|
||||
return 1;
|
||||
end|
|
||||
--error ER_SP_NO_RETSET
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
show create event e1;
|
||||
end|
|
||||
--error ER_SP_NO_RETSET
|
||||
create function f1() returns int
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
return 1;
|
||||
end|
|
||||
--error ER_SP_NO_RETSET
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
end|
|
||||
--error ER_EVENT_RECURSION_FORBIDDEN
|
||||
create function f1() returns int
|
||||
begin
|
||||
create event e2 on schedule every 10 hour do select 1;
|
||||
return 1;
|
||||
end|
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function f1() returns int
|
||||
begin
|
||||
alter event e1 rename to e2;
|
||||
return 1;
|
||||
end|
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
create function f1() returns int
|
||||
begin
|
||||
drop event e2;
|
||||
return 1;
|
||||
end|
|
||||
--echo ----------------------------------------------------------------------
|
||||
create trigger trg before insert on t1 for each row
|
||||
begin
|
||||
set new.a= f1();
|
||||
end|
|
||||
create function f1() returns int
|
||||
begin
|
||||
call p1();
|
||||
return 0;
|
||||
end|
|
||||
create procedure p1()
|
||||
begin
|
||||
select event_name from information_schema.events;
|
||||
end|
|
||||
--error ER_SP_NO_RETSET
|
||||
insert into t1 (a) values (1)|
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
show create event e1;
|
||||
end|
|
||||
--error ER_SP_NO_RETSET
|
||||
insert into t1 (a) values (1)|
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
create temporary table tmp select event_name from information_schema.events;
|
||||
end|
|
||||
--echo expected to work, since we redirect the output into a tmp table
|
||||
insert into t1 (a) values (1)|
|
||||
select * from tmp|
|
||||
drop temporary table tmp|
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
alter event e1 rename to e2;
|
||||
end|
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
insert into t1 (a) values (1)|
|
||||
drop procedure p1|
|
||||
create procedure p1()
|
||||
begin
|
||||
drop event e1;
|
||||
end|
|
||||
--error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
insert into t1 (a) values (1)|
|
||||
drop table t1|
|
||||
drop event e1|
|
||||
delimiter ;|
|
||||
|
||||
drop database events_test;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
# Can't test with embedded server that doesn't support grants
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
create database if not exists events_test;
|
||||
--disable_warnings
|
||||
drop database if exists events_test;
|
||||
drop database if exists mysqltest_db1;
|
||||
drop database if exists mysqltest_db2;
|
||||
--enable_warnings
|
||||
create database events_test;
|
||||
use events_test;
|
||||
|
||||
#
|
||||
|
@ -429,6 +434,184 @@ DROP USER mysqltest_u1@localhost;
|
|||
|
||||
|
||||
#
|
||||
# BUG#16420: Events: timestamps become UTC
|
||||
# BUG#26429: SHOW CREATE EVENT is incorrect for an event that
|
||||
# STARTS NOW()
|
||||
# BUG#26431: Impossible to re-create an event from backup if its
|
||||
# STARTS clause is in the past
|
||||
# WL#3698: Events: execution in local time zone
|
||||
#
|
||||
# Here we only check non-concurrent aspects of the patch.
|
||||
# For the actual tests of time zones please see events_time_zone.test
|
||||
#
|
||||
SET GLOBAL EVENT_SCHEDULER= OFF;
|
||||
SET @save_time_zone= @@TIME_ZONE;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# We will use a separate connection because SET TIMESTAMP will stop
|
||||
# the clock in that connection.
|
||||
|
||||
SET TIME_ZONE= '+00:00';
|
||||
SET TIMESTAMP= UNIX_TIMESTAMP('2005-12-31 23:58:59');
|
||||
|
||||
|
||||
# Test when event time zone is updated on ALTER EVENT.
|
||||
#
|
||||
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
|
||||
SHOW EVENTS;
|
||||
|
||||
# Test storing and updating of the event time zone.
|
||||
#
|
||||
SET TIME_ZONE= '-01:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 00:00:00';
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will update event time zone.
|
||||
SET TIME_ZONE= '+02:00';
|
||||
ALTER EVENT e1 ON SCHEDULE AT '2000-01-02 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will update event time zone.
|
||||
SET TIME_ZONE= '-03:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY ENDS '2030-01-03 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will not update event time zone, as no time is being adjusted.
|
||||
SET TIME_ZONE= '+04:00';
|
||||
ALTER EVENT e1 DO SELECT 2;
|
||||
SHOW EVENTS;
|
||||
|
||||
DROP EVENT e1;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Create some events.
|
||||
SET TIME_ZONE='+05:00';
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
|
||||
SET TIME_ZONE='-05:00';
|
||||
CREATE EVENT e2 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
|
||||
SET TIME_ZONE='+00:00';
|
||||
CREATE EVENT e3 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
|
||||
# Test INFORMATION_SCHEMA.EVENTS.
|
||||
#
|
||||
|
||||
SELECT * FROM INFORMATION_SCHEMA.EVENTS ORDER BY event_name;
|
||||
|
||||
|
||||
# Test SHOW EVENTS.
|
||||
#
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
|
||||
# Test SHOW CREATE EVENT.
|
||||
#
|
||||
|
||||
SHOW CREATE EVENT e1;
|
||||
SHOW CREATE EVENT e2;
|
||||
SHOW CREATE EVENT e3;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Test times in the past.
|
||||
#
|
||||
|
||||
--echo The following should fail, and nothing should be altered.
|
||||
|
||||
--error ER_EVENT_CANNOT_ALTER_IN_THE_PAST
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00';
|
||||
|
||||
--error ER_EVENT_CANNOT_ALTER_IN_THE_PAST
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE;
|
||||
|
||||
--echo The following should give warnings, and nothing should be created.
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00'
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
--echo The following should succeed giving a warning.
|
||||
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e5 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
--echo The following should succeed without warnings.
|
||||
|
||||
ALTER EVENT e2 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00';
|
||||
|
||||
ALTER EVENT e3 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE;
|
||||
|
||||
CREATE EVENT e6 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e7 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e8 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
|
||||
DROP EVENT e8;
|
||||
DROP EVENT e7;
|
||||
DROP EVENT e6;
|
||||
DROP EVENT e5;
|
||||
DROP EVENT e4;
|
||||
DROP EVENT e3;
|
||||
DROP EVENT e2;
|
||||
DROP EVENT e1;
|
||||
|
||||
SET TIME_ZONE=@save_time_zone;
|
||||
|
||||
#
|
||||
# End of tests
|
||||
#
|
||||
drop database events_test;
|
||||
|
|
|
@ -1,19 +1,43 @@
|
|||
# Can't test with embedded server that doesn't support grants
|
||||
-- source include/not_embedded.inc
|
||||
#
|
||||
# Test that when the server is restarted, it checks mysql.event table,
|
||||
# and disables the scheduler if it's not up to date.
|
||||
#
|
||||
|
||||
# Switch off the scheduler for now.
|
||||
set global event_scheduler=off;
|
||||
|
||||
--disable_warnings
|
||||
create database if not exists mysqltest_events_test;
|
||||
drop database if exists events_test;
|
||||
--enable_warnings
|
||||
|
||||
use mysqltest_events_test;
|
||||
set global event_scheduler=off;
|
||||
create database events_test;
|
||||
use events_test;
|
||||
create table execution_log(name char(10));
|
||||
create event abc1 on schedule every 1 second do insert into execution_log value('abc1');
|
||||
create event abc2 on schedule every 1 second do insert into execution_log value('abc2');
|
||||
create event abc3 on schedule every 1 second do insert into execution_log value('abc3');
|
||||
--sleep 1.5
|
||||
select name from execution_log;
|
||||
|
||||
insert into mysql.event values ('db1','bad','select 42','root@localhost',NULL,1000,'MICROSECOND','2006-05-05 17:39:11','2006-05-05 17:39:20','2016-05-05 15:39:24','2016-05-05 15:39:11',NULL,'ENABLED','DROP','','comment1',1,'SYSTEM');
|
||||
insert into mysql.event values ('db1','bad2','sect','root@localhost',NULL,1000,'SECOND','2006-05-05 17:39:11','2006-05-05 17:39:20','2016-05-05 15:39:24','2016-05-05 15:39:11',NULL,'ENABLED','DROP','','comment2',1,'SYSTEM');
|
||||
create event abc1 on schedule every 1 second do
|
||||
insert into execution_log value('abc1');
|
||||
create event abc2 on schedule every 1 second do
|
||||
insert into execution_log value('abc2');
|
||||
create event abc3 on schedule every 1 second do
|
||||
insert into execution_log value('abc3');
|
||||
#
|
||||
# There are various conditions when a server would regard mysql.event
|
||||
# table as damaged:
|
||||
# - the table has more column than specified in the compiled in value, but
|
||||
# the version of the server which created the table is the same
|
||||
# - the column count in the table is less than the compiled in value
|
||||
# - some column has an incompatible type specification (for what is an
|
||||
# incompatible type specification please refer to the comments in the source
|
||||
#
|
||||
# Unfortunately, in order to test a condition, we need to restart the
|
||||
# server. Therefore, here we test only one simple case: changing the data
|
||||
# type of the 'body' field to blob.
|
||||
#
|
||||
# First, let's do a backup to not depend on actual definition of mysql.event
|
||||
create table event_like like mysql.event;
|
||||
insert into event_like select * from mysql.event;
|
||||
# Now let's alter the table and restart the server
|
||||
alter table mysql.event
|
||||
change column body body longtext character set utf8 collate utf8_bin;
|
||||
--echo "Now we restart the server"
|
||||
|
|
|
@ -1,9 +1,41 @@
|
|||
# Can't test with embedded server that doesn't support grants
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
use mysqltest_events_test;
|
||||
--sleep 1.5
|
||||
--echo "Should get 0 rows because the queue aborted run
|
||||
select distinct name from execution_log order by name;
|
||||
delete from mysql.event where name like 'bad%';
|
||||
--echo "Now restart the server again"
|
||||
use events_test;
|
||||
# Event scheduler should be disabled: the system tables are damaged
|
||||
select @@event_scheduler;
|
||||
# Try various Event Scheduler operation and check the output.
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
show events;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
select event_name from information_schema.events;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
show create event intact_check;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
drop event no_such_event;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
create event intact_check_1 on schedule every 5 hour do select 5;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
alter event intact_check_1 on schedule every 8 hour do select 8;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
alter event intact_check_1 rename to intact_check_2;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
drop event intact_check_1;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
drop event intact_check_2;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
drop event intact_check;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
set global event_scheduler=on;
|
||||
--error ER_EVENTS_DB_ERROR
|
||||
set global event_scheduler=off;
|
||||
show variables like 'event_scheduler';
|
||||
--echo Make sure that we still can create and drop databases,
|
||||
--echo and no warnings are produced.
|
||||
drop database if exists mysqltest_database_not_exists;
|
||||
create database mysqltest_db1;
|
||||
drop database mysqltest_db1;
|
||||
--echo Restore the original mysql.event table
|
||||
drop table mysql.event;
|
||||
rename table event_like to mysql.event;
|
||||
--echo Now let's restart the server again
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
# Can't test with embedded server that doesn't support grants
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
use mysqltest_events_test;
|
||||
--sleep 2
|
||||
#
|
||||
# We need this file primarily to make sure that the scheduler is restarted
|
||||
# and enabled after we have restored mysql.event table.
|
||||
# This is the final step of the "cleanup".
|
||||
#
|
||||
# Make sure also that events are executed OK after restart, just in case.
|
||||
use events_test;
|
||||
# Make sure the scheduler was started successfully
|
||||
select @@event_scheduler;
|
||||
let $wait_condition=select count(distinct name)=3 from execution_log;
|
||||
--source include/wait_condition.inc
|
||||
--echo "Should get 3 rows : abc1, abc2, abc3
|
||||
select distinct name from execution_log order by name;
|
||||
|
||||
drop event abc1;
|
||||
drop event abc2;
|
||||
drop event abc3;
|
||||
drop table execution_log;
|
||||
|
||||
drop database mysqltest_events_test;
|
||||
# Will drop all events
|
||||
drop database events_test;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
CREATE DATABASE IF NOT EXISTS events_test;
|
||||
USE events_test;
|
||||
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
--echo Try agian to make sure it's allowed
|
||||
SET GLOBAL event_scheduler=OFF;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=1;
|
||||
|
@ -12,6 +14,8 @@ SHOW VARIABLES LIKE 'event_scheduler';
|
|||
SET GLOBAL event_scheduler=0;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
--echo Try again to make sure it's allowed
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
SHOW VARIABLES LIKE 'event_scheduler';
|
||||
--error ER_WRONG_VALUE_FOR_VAR
|
||||
SET GLOBAL event_scheduler=DISABLED;
|
||||
|
@ -30,34 +34,73 @@ CREATE TABLE table_1(a int);
|
|||
CREATE TABLE table_2(a int);
|
||||
CREATE TABLE table_3(a int);
|
||||
CREATE TABLE table_4(a int);
|
||||
CREATE TABLE T19170(s1 TIMESTAMP);
|
||||
|
||||
SET GLOBAL event_scheduler=ON;
|
||||
# We need to have 2 to make it safe with valgrind. This is probably because
|
||||
# of when we calculate the timestamp value
|
||||
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
|
||||
CREATE EVENT start_n_end
|
||||
ON SCHEDULE EVERY 1 SECOND
|
||||
ENDS NOW() + INTERVAL 6 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO INSERT INTO table_2 VALUES(1);
|
||||
--sleep 5
|
||||
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
|
||||
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND ON COMPLETION PRESERVE DO INSERT INTO table_4 VALUES(1);
|
||||
--sleep 5
|
||||
CREATE EVENT event_1 ON SCHEDULE EVERY 2 SECOND
|
||||
DO
|
||||
INSERT INTO table_1 VALUES (1);
|
||||
|
||||
CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND
|
||||
ENDS NOW() + INTERVAL 6 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
INSERT INTO table_2 VALUES (1);
|
||||
|
||||
CREATE EVENT event_3 ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND
|
||||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
INSERT INTO table_3 VALUES (1);
|
||||
|
||||
CREATE EVENT event_4 ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
INSERT INTO table_4 VALUES (1);
|
||||
|
||||
# Let event_1 insert at least 4 records into the table
|
||||
let $wait_condition=select count(*) >= 4 from table_1;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# Let event_2 reach the end of its execution interval
|
||||
let $wait_condition=select count(*) = 0 from information_schema.events
|
||||
where event_name='event_2' and status='enabled';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# Let event_3, which is ON COMPLETION NOT PRESERVE execute and drop itself
|
||||
let $wait_condition=select count(*) = 0 from information_schema.events
|
||||
where event_name='event_3';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# Let event_4 reach the end of its execution interval
|
||||
let $wait_condition=select count(*) = 0 from information_schema.events
|
||||
where event_name='event_4' and status='enabled';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# check the data
|
||||
|
||||
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
|
||||
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
|
||||
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
|
||||
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
|
||||
DROP EVENT two_sec;
|
||||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
|
||||
DROP EVENT IF EXISTS events_test.start_n_end;
|
||||
SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_3;
|
||||
SELECT IF(SUM(a) >= 1, 'OK', 'ERROR') FROM table_4;
|
||||
|
||||
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
|
||||
FROM INFORMATION_SCHEMA.EVENTS
|
||||
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
|
||||
|
||||
SELECT IF(LAST_EXECUTED-ENDS < 3, 'OK', 'ERROR')
|
||||
FROM INFORMATION_SCHEMA.EVENTS
|
||||
WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='event_2';
|
||||
|
||||
--echo "Already dropped because ended. Therefore an error."
|
||||
--error ER_EVENT_DOES_NOT_EXIST
|
||||
DROP EVENT only_one_time;
|
||||
DROP EVENT event_3;
|
||||
|
||||
DROP EVENT event_1;
|
||||
--echo "Should be preserved"
|
||||
SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME;
|
||||
DROP EVENT two_time;
|
||||
DROP EVENT event_2;
|
||||
DROP EVENT event_4;
|
||||
DROP TABLE table_1;
|
||||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
|
|
|
@ -20,6 +20,7 @@ let $old_db= `SELECT DATABASE()`;
|
|||
USE mysqltest_db1;
|
||||
|
||||
SET GLOBAL EVENT_SCHEDULER= OFF;
|
||||
SET @save_time_zone= @@TIME_ZONE;
|
||||
|
||||
|
||||
#
|
||||
|
@ -31,176 +32,6 @@ SET GLOBAL EVENT_SCHEDULER= OFF;
|
|||
# WL#3698: Events: execution in local time zone
|
||||
#
|
||||
|
||||
SET @save_time_zone= @@TIME_ZONE;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# We will use a separate connection because SET TIMESTAMP will stop
|
||||
# the clock in that connection.
|
||||
|
||||
connect (conn1, localhost, root, , mysqltest_db1);
|
||||
|
||||
SET TIME_ZONE= '+00:00';
|
||||
SET TIMESTAMP= UNIX_TIMESTAMP('2005-12-31 23:58:59');
|
||||
|
||||
|
||||
# Test when event time zone is updated on ALTER EVENT.
|
||||
#
|
||||
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
|
||||
SHOW EVENTS;
|
||||
|
||||
# Test storing and updating of the event time zone.
|
||||
#
|
||||
SET TIME_ZONE= '-01:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 00:00:00';
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will update event time zone.
|
||||
SET TIME_ZONE= '+02:00';
|
||||
ALTER EVENT e1 ON SCHEDULE AT '2000-01-02 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will update event time zone.
|
||||
SET TIME_ZONE= '-03:00';
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 DAY ENDS '2030-01-03 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE;
|
||||
SHOW EVENTS;
|
||||
|
||||
# This will not update event time zone, as no time is being adjusted.
|
||||
SET TIME_ZONE= '+04:00';
|
||||
ALTER EVENT e1 DO SELECT 2;
|
||||
SHOW EVENTS;
|
||||
|
||||
DROP EVENT e1;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Create some events.
|
||||
SET TIME_ZONE='+05:00';
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
|
||||
SET TIME_ZONE='-05:00';
|
||||
CREATE EVENT e2 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
SET TIMESTAMP= @@TIMESTAMP + 1;
|
||||
|
||||
SET TIME_ZONE='+00:00';
|
||||
CREATE EVENT e3 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
|
||||
# Test INFORMATION_SCHEMA.EVENTS.
|
||||
#
|
||||
|
||||
SELECT * FROM INFORMATION_SCHEMA.EVENTS;
|
||||
|
||||
|
||||
# Test SHOW EVENTS.
|
||||
#
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
|
||||
# Test SHOW CREATE EVENT.
|
||||
#
|
||||
|
||||
SHOW CREATE EVENT e1;
|
||||
SHOW CREATE EVENT e2;
|
||||
SHOW CREATE EVENT e3;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Test times in the past.
|
||||
#
|
||||
|
||||
--echo The following should fail, and nothing should be altered.
|
||||
|
||||
--error ER_EVENT_CANNOT_ALTER_IN_THE_PAST
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00';
|
||||
|
||||
--error ER_EVENT_CANNOT_ALTER_IN_THE_PAST
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE;
|
||||
|
||||
--echo The following should give warnings, and nothing should be created.
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00'
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE AT '1999-01-01 00:00:00' DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
--echo The following should succeed giving a warning.
|
||||
|
||||
ALTER EVENT e1 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE;
|
||||
|
||||
CREATE EVENT e4 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e5 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
--echo The following should succeed without warnings.
|
||||
|
||||
ALTER EVENT e2 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00';
|
||||
|
||||
ALTER EVENT e3 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE;
|
||||
|
||||
CREATE EVENT e6 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00' DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e7 ON SCHEDULE EVERY 1 HOUR STARTS '1999-01-01 00:00:00'
|
||||
ENDS '1999-01-02 00:00:00' ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
CREATE EVENT e8 ON SCHEDULE AT '1999-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE DISABLE
|
||||
DO
|
||||
SELECT 1;
|
||||
|
||||
SHOW EVENTS;
|
||||
|
||||
|
||||
DROP EVENT e8;
|
||||
DROP EVENT e7;
|
||||
DROP EVENT e6;
|
||||
DROP EVENT e5;
|
||||
DROP EVENT e4;
|
||||
DROP EVENT e3;
|
||||
DROP EVENT e2;
|
||||
DROP EVENT e1;
|
||||
|
||||
|
||||
disconnect conn1;
|
||||
connection default;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# Create rounding function.
|
||||
|
|
159
mysql-test/t/events_trans.test
Normal file
159
mysql-test/t/events_trans.test
Normal file
|
@ -0,0 +1,159 @@
|
|||
#
|
||||
# Tests that require transactions
|
||||
#
|
||||
-- source include/have_innodb.inc
|
||||
--disable_warnings
|
||||
drop database if exists events_test;
|
||||
drop database if exists mysqltest_db2;
|
||||
drop database if exists mysqltest_no_such_database;
|
||||
--enable_warnings
|
||||
create database events_test;
|
||||
use events_test;
|
||||
|
||||
--echo
|
||||
--echo Test that Events DDL issue an implicit COMMIT
|
||||
--echo
|
||||
--echo
|
||||
set autocommit=off;
|
||||
# Sanity check
|
||||
select @@autocommit;
|
||||
create table t1 (a varchar(255)) engine=innodb;
|
||||
# Basic: check that successful Events DDL commits pending transaction
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event");
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event");
|
||||
alter event e1 on schedule every 2 day do select 2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename");
|
||||
alter event e1 rename to e2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event");
|
||||
drop event e2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event if exists");
|
||||
drop event if exists e2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event if not exists");
|
||||
create event if not exists e1 on schedule every 2 day do select 2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
--echo
|
||||
--echo Now check various error conditions: make sure we issue an
|
||||
--echo implicit commit anyway
|
||||
--echo
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: event already exists");
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
create event e1 on schedule every 2 day do select 2;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename: rename to same name");
|
||||
--error ER_EVENT_SAME_NAME
|
||||
alter event e1 rename to e1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
create event e2 on schedule every 3 day do select 3;
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event rename: destination exists");
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
alter event e2 rename to e1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: database does not exist");
|
||||
--error ER_BAD_DB_ERROR
|
||||
create event mysqltest_no_such_database.e1 on schedule every 1 day do select 1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
#
|
||||
# Privilege checks
|
||||
#
|
||||
grant create, insert, select, delete on mysqltest_db2.*
|
||||
to mysqltest_user1@localhost;
|
||||
create database mysqltest_db2;
|
||||
connect (conn1,localhost,mysqltest_user1,,mysqltest_db2);
|
||||
set autocommit=off;
|
||||
# Sanity check
|
||||
select @@autocommit;
|
||||
create table t1 (a varchar(255)) engine=innodb;
|
||||
# Not enough privileges to CREATE EVENT
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: create event: insufficient privileges");
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
create event e1 on schedule every 1 day do select 1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
# Not enough privileges to ALTER EVENT
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: alter event: insufficient privileges");
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
alter event e1 on schedule every 1 day do select 1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
# Not enough privileges to DROP EVENT
|
||||
begin work;
|
||||
insert into t1 (a) values ("OK: drop event: insufficient privileges");
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
drop event e1;
|
||||
rollback work;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit work;
|
||||
# Cleanup
|
||||
disconnect conn1;
|
||||
connection default;
|
||||
drop user mysqltest_user1@localhost;
|
||||
drop database mysqltest_db2;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
drop database events_test;
|
||||
|
|
@ -1042,16 +1042,13 @@ select user,db from information_schema.processlist;
|
|||
connection default;
|
||||
drop user user3148@localhost;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Bug #26174 Server Crash: INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in Event
|
||||
# Bug #26174 Server Crash: INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS
|
||||
# in Event (see also openssl_1.test)
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS thread_status;
|
||||
DROP TABLE IF EXISTS server_status;
|
||||
DROP EVENT IF EXISTS event_status;
|
||||
|
||||
--enable_warnings
|
||||
|
||||
SET GLOBAL event_scheduler=1;
|
||||
|
@ -1063,12 +1060,6 @@ CREATE EVENT event_status
|
|||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
BEGIN
|
||||
CREATE TABLE thread_status
|
||||
SELECT variable_name, variable_value
|
||||
FROM information_schema.session_status
|
||||
WHERE variable_name LIKE 'SSL_ACCEPTS' OR
|
||||
variable_name LIKE 'SSL_CALLBACK_CACHE_HITS';
|
||||
|
||||
CREATE TABLE server_status
|
||||
SELECT variable_name
|
||||
FROM information_schema.global_status
|
||||
|
@ -1079,15 +1070,11 @@ END$$
|
|||
DELIMITER ;$$
|
||||
|
||||
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status';
|
||||
let $wait_timeout=30;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT variable_name, variable_value FROM thread_status;
|
||||
SELECT variable_name FROM server_status;
|
||||
|
||||
DROP TABLE thread_status;
|
||||
DROP TABLE server_status;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
|
||||
--echo End of 5.1 tests.
|
||||
|
||||
|
|
|
@ -104,3 +104,41 @@ drop table t1;
|
|||
# and ca path to NULL
|
||||
#
|
||||
--exec $MYSQL --ssl --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "SHOW STATUS LIKE 'ssl_Cipher'" 2>&1
|
||||
--echo End of 5.0 tests
|
||||
|
||||
#
|
||||
# Bug #26174 Server Crash: INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in
|
||||
# Event (see also information_schema.test for the other part of test for
|
||||
# this bug).
|
||||
#
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS thread_status;
|
||||
DROP EVENT IF EXISTS event_status;
|
||||
--enable_warnings
|
||||
|
||||
SET GLOBAL event_scheduler=1;
|
||||
|
||||
DELIMITER $$;
|
||||
|
||||
CREATE EVENT event_status
|
||||
ON SCHEDULE AT NOW()
|
||||
ON COMPLETION NOT PRESERVE
|
||||
DO
|
||||
BEGIN
|
||||
CREATE TABLE thread_status
|
||||
SELECT variable_name, variable_value
|
||||
FROM information_schema.session_status
|
||||
WHERE variable_name LIKE 'SSL_ACCEPTS' OR
|
||||
variable_name LIKE 'SSL_CALLBACK_CACHE_HITS';
|
||||
END$$
|
||||
|
||||
DELIMITER ;$$
|
||||
|
||||
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT variable_name, variable_value FROM thread_status;
|
||||
|
||||
DROP TABLE thread_status;
|
||||
SET GLOBAL event_scheduler=0;
|
||||
--echo End of 5.1 tests
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include "event_db_repository.h"
|
||||
#include "sp_head.h"
|
||||
|
||||
/* That's a provisional solution */
|
||||
extern Event_db_repository events_event_db_repository;
|
||||
|
||||
#define EVEX_MAX_INTERVAL_VALUE 1000000000L
|
||||
|
||||
|
@ -101,8 +99,9 @@ Event_parse_data::new_instance(THD *thd)
|
|||
*/
|
||||
|
||||
Event_parse_data::Event_parse_data()
|
||||
:on_completion(Event_basic::ON_COMPLETION_DROP),
|
||||
status(Event_basic::ENABLED), do_not_create(FALSE),
|
||||
:on_completion(Event_basic::ON_COMPLETION_DROP),
|
||||
status(Event_basic::ENABLED),
|
||||
do_not_create(FALSE),
|
||||
item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
|
||||
starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
|
||||
item_expression(NULL), expression(0)
|
||||
|
@ -216,7 +215,7 @@ Event_parse_data::init_body(THD *thd)
|
|||
++body_begin;
|
||||
--body.length;
|
||||
}
|
||||
body.str= thd->strmake((char *)body_begin, body.length);
|
||||
body.str= thd->strmake(body_begin, body.length);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -589,6 +588,7 @@ Event_parse_data::check_parse_data(THD *thd)
|
|||
init_name(thd, identifier);
|
||||
|
||||
init_definer(thd);
|
||||
|
||||
ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) ||
|
||||
init_ends(thd);
|
||||
check_originator_id(thd);
|
||||
|
@ -638,7 +638,7 @@ Event_parse_data::init_definer(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set the originator id of the event to the server_id if executing on
|
||||
the master or set to the server_id of the master if executing on
|
||||
the slave. If executing on slave, also set status to SLAVESIDE_DISABLED.
|
||||
|
@ -720,7 +720,7 @@ Event_basic::load_string_fields(Field **fields, ...)
|
|||
|
||||
va_start(args, fields);
|
||||
field_name= (enum enum_events_table_field) va_arg(args, int);
|
||||
while (field_name != ET_FIELD_COUNT)
|
||||
while (field_name < ET_FIELD_COUNT)
|
||||
{
|
||||
field_value= va_arg(args, LEX_STRING *);
|
||||
if ((field_value->str= get_field(&mem_root, fields[field_name])) == NullS)
|
||||
|
@ -884,13 +884,19 @@ Event_job_data::load_from_row(THD *thd, TABLE *table)
|
|||
if (!table)
|
||||
goto error;
|
||||
|
||||
if (table->s->fields != ET_FIELD_COUNT)
|
||||
if (table->s->fields < ET_FIELD_COUNT)
|
||||
goto error;
|
||||
|
||||
LEX_STRING tz_name;
|
||||
load_string_fields(table->field, ET_FIELD_DB, &dbname, ET_FIELD_NAME, &name,
|
||||
ET_FIELD_BODY, &body, ET_FIELD_DEFINER, &definer,
|
||||
ET_FIELD_TIME_ZONE, &tz_name, ET_FIELD_COUNT);
|
||||
if (load_string_fields(table->field,
|
||||
ET_FIELD_DB, &dbname,
|
||||
ET_FIELD_NAME, &name,
|
||||
ET_FIELD_BODY, &body,
|
||||
ET_FIELD_DEFINER, &definer,
|
||||
ET_FIELD_TIME_ZONE, &tz_name,
|
||||
ET_FIELD_COUNT))
|
||||
goto error;
|
||||
|
||||
if (load_time_zone(thd, tz_name))
|
||||
goto error;
|
||||
|
||||
|
@ -936,19 +942,24 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
|
|||
{
|
||||
char *ptr;
|
||||
TIME time;
|
||||
LEX_STRING tz_name;
|
||||
|
||||
DBUG_ENTER("Event_queue_element::load_from_row");
|
||||
|
||||
if (!table)
|
||||
goto error;
|
||||
|
||||
if (table->s->fields != ET_FIELD_COUNT)
|
||||
if (table->s->fields < ET_FIELD_COUNT)
|
||||
goto error;
|
||||
|
||||
if (load_string_fields(table->field,
|
||||
ET_FIELD_DB, &dbname,
|
||||
ET_FIELD_NAME, &name,
|
||||
ET_FIELD_DEFINER, &definer,
|
||||
ET_FIELD_TIME_ZONE, &tz_name,
|
||||
ET_FIELD_COUNT))
|
||||
goto error;
|
||||
|
||||
LEX_STRING tz_name;
|
||||
load_string_fields(table->field, ET_FIELD_DB, &dbname, ET_FIELD_NAME, &name,
|
||||
ET_FIELD_DEFINER, &definer,
|
||||
ET_FIELD_TIME_ZONE, &tz_name, ET_FIELD_COUNT);
|
||||
if (load_time_zone(thd, tz_name))
|
||||
goto error;
|
||||
|
||||
|
@ -1032,6 +1043,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
|
|||
status = Event_queue_element::SLAVESIDE_DISABLED;
|
||||
break;
|
||||
case 'D' :
|
||||
default:
|
||||
status = Event_queue_element::DISABLED;
|
||||
break;
|
||||
}
|
||||
|
@ -1080,7 +1092,11 @@ Event_timed::load_from_row(THD *thd, TABLE *table)
|
|||
if (Event_queue_element::load_from_row(thd, table))
|
||||
goto error;
|
||||
|
||||
load_string_fields(table->field, ET_FIELD_BODY, &body, ET_FIELD_COUNT);
|
||||
if (load_string_fields(table->field,
|
||||
ET_FIELD_BODY, &body,
|
||||
ET_FIELD_COUNT))
|
||||
goto error;
|
||||
|
||||
|
||||
ptr= strchr(definer.str, '@');
|
||||
|
||||
|
@ -1635,10 +1651,8 @@ Event_queue_element::mark_last_executed(THD *thd)
|
|||
bool
|
||||
Event_queue_element::update_timing_fields(THD *thd)
|
||||
{
|
||||
TABLE *table;
|
||||
Field **fields;
|
||||
Open_tables_state backup;
|
||||
int ret= FALSE;
|
||||
Event_db_repository *db_repository= Events::get_db_repository();
|
||||
int ret;
|
||||
|
||||
DBUG_ENTER("Event_queue_element::update_timing_fields");
|
||||
|
||||
|
@ -1648,53 +1662,13 @@ Event_queue_element::update_timing_fields(THD *thd)
|
|||
if (!(status_changed || last_executed_changed))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
thd->reset_n_backup_open_tables_state(&backup);
|
||||
|
||||
if (events_event_db_repository.open_event_table(thd, TL_WRITE, &table))
|
||||
{
|
||||
ret= TRUE;
|
||||
goto done;
|
||||
}
|
||||
fields= table->field;
|
||||
if ((ret= events_event_db_repository.
|
||||
find_named_event(thd, dbname, name, table)))
|
||||
goto done;
|
||||
|
||||
store_record(table,record[1]);
|
||||
/* Don't update create on row update. */
|
||||
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
|
||||
|
||||
if (last_executed_changed)
|
||||
{
|
||||
TIME time;
|
||||
my_tz_UTC->gmt_sec_to_TIME(&time, last_executed);
|
||||
|
||||
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
|
||||
fields[ET_FIELD_LAST_EXECUTED]->store_time(&time,
|
||||
MYSQL_TIMESTAMP_DATETIME);
|
||||
last_executed_changed= FALSE;
|
||||
}
|
||||
if (status_changed)
|
||||
{
|
||||
fields[ET_FIELD_STATUS]->set_notnull();
|
||||
fields[ET_FIELD_STATUS]->store((longlong)status, TRUE);
|
||||
status_changed= FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Turn off row binlogging of event timing updates. These are not used
|
||||
for RBR of events replicated to the slave.
|
||||
*/
|
||||
if (thd->current_stmt_binlog_row_based)
|
||||
thd->clear_current_stmt_binlog_row_based();
|
||||
|
||||
if ((table->file->ha_update_row(table->record[1], table->record[0])))
|
||||
ret= TRUE;
|
||||
|
||||
done:
|
||||
close_thread_tables(thd);
|
||||
thd->restore_backup_open_tables_state(&backup);
|
||||
|
||||
ret= db_repository->update_timing_fields_for_event(thd,
|
||||
dbname, name,
|
||||
last_executed_changed,
|
||||
last_executed,
|
||||
status_changed,
|
||||
(ulonglong) status);
|
||||
last_executed_changed= status_changed= FALSE;
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
|
@ -1779,7 +1753,7 @@ Event_timed::get_create_event(THD *thd, String *buf)
|
|||
if (status == Event_timed::ENABLED)
|
||||
buf->append(STRING_WITH_LEN("ENABLE"));
|
||||
else if (status == Event_timed::SLAVESIDE_DISABLED)
|
||||
buf->append(STRING_WITH_LEN("SLAVESIDE_DISABLE"));
|
||||
buf->append(STRING_WITH_LEN("DISABLE ON SLAVE"));
|
||||
else
|
||||
buf->append(STRING_WITH_LEN("DISABLE"));
|
||||
|
||||
|
@ -1837,7 +1811,7 @@ Event_job_data::get_fake_create_event(String *buf)
|
|||
*/
|
||||
|
||||
int
|
||||
Event_job_data::execute(THD *thd)
|
||||
Event_job_data::execute(THD *thd, bool drop)
|
||||
{
|
||||
Security_context save_ctx;
|
||||
/* this one is local and not needed after exec */
|
||||
|
@ -1877,6 +1851,17 @@ Event_job_data::execute(THD *thd)
|
|||
definer_host.str, dbname.str));
|
||||
ret= -99;
|
||||
}
|
||||
if (drop)
|
||||
{
|
||||
sql_print_information("Event Scheduler: Dropping %s.%s",
|
||||
dbname.str, name.str);
|
||||
/*
|
||||
We must do it here since here we're under the right authentication
|
||||
ID of the event definer
|
||||
*/
|
||||
if (Events::drop_event(thd, dbname, name, FALSE))
|
||||
ret= 1;
|
||||
}
|
||||
|
||||
event_restore_security_context(thd, &save_ctx);
|
||||
done:
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#define EVEX_GET_FIELD_FAILED -2
|
||||
#define EVEX_COMPILE_ERROR -3
|
||||
#define EVEX_GENERAL_ERROR -4
|
||||
#define EVEX_BAD_PARAMS -5
|
||||
#define EVEX_MICROSECOND_UNSUP -6
|
||||
|
||||
|
@ -178,8 +177,6 @@ public:
|
|||
|
||||
ulong sql_mode;
|
||||
|
||||
uint execution_count;
|
||||
|
||||
Event_job_data();
|
||||
virtual ~Event_job_data();
|
||||
|
||||
|
@ -187,7 +184,7 @@ public:
|
|||
load_from_row(THD *thd, TABLE *table);
|
||||
|
||||
int
|
||||
execute(THD *thd);
|
||||
execute(THD *thd, bool drop);
|
||||
|
||||
int
|
||||
compile(THD *thd, MEM_ROOT *mem_root);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,12 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#define EVEX_OPEN_TABLE_FAILED -1
|
||||
/*
|
||||
@file
|
||||
This is a private header file of Events module. Please do not include it
|
||||
directly. All public declarations of Events module should be stored in
|
||||
events.h and event_data_objects.h.
|
||||
*/
|
||||
|
||||
enum enum_events_table_field
|
||||
{
|
||||
|
@ -70,17 +75,28 @@ public:
|
|||
drop_schema_events(THD *thd, LEX_STRING schema);
|
||||
|
||||
bool
|
||||
find_named_event(THD *thd, LEX_STRING db, LEX_STRING name, TABLE *table);
|
||||
find_named_event(LEX_STRING db, LEX_STRING name, TABLE *table);
|
||||
|
||||
bool
|
||||
load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *et);
|
||||
|
||||
int
|
||||
bool
|
||||
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
|
||||
|
||||
int
|
||||
bool
|
||||
fill_schema_events(THD *thd, TABLE_LIST *tables, const char *db);
|
||||
|
||||
bool
|
||||
update_timing_fields_for_event(THD *thd,
|
||||
LEX_STRING event_db_name,
|
||||
LEX_STRING event_name,
|
||||
bool update_last_executed,
|
||||
my_time_t last_executed,
|
||||
bool update_status,
|
||||
ulonglong status);
|
||||
public:
|
||||
static bool
|
||||
check_system_tables(THD *thd);
|
||||
private:
|
||||
void
|
||||
drop_events_by_field(THD *thd, enum enum_events_table_field field,
|
||||
|
@ -92,9 +108,7 @@ private:
|
|||
bool
|
||||
table_scan_all_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table);
|
||||
|
||||
static bool
|
||||
check_system_tables(THD *thd);
|
||||
|
||||
private:
|
||||
/* Prevent use of these */
|
||||
Event_db_repository(const Event_db_repository &);
|
||||
void operator=(Event_db_repository &);
|
||||
|
|
|
@ -72,39 +72,21 @@ event_queue_element_compare_q(void *vptr, byte* a, byte *b)
|
|||
Event_queue::Event_queue()
|
||||
:mutex_last_unlocked_at_line(0), mutex_last_locked_at_line(0),
|
||||
mutex_last_attempted_lock_at_line(0),
|
||||
mutex_queue_data_locked(FALSE), mutex_queue_data_attempting_lock(FALSE)
|
||||
mutex_queue_data_locked(FALSE),
|
||||
mutex_queue_data_attempting_lock(FALSE),
|
||||
next_activation_at(0)
|
||||
{
|
||||
mutex_last_unlocked_in_func= mutex_last_locked_in_func=
|
||||
mutex_last_attempted_lock_in_func= "";
|
||||
next_activation_at= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Inits mutexes.
|
||||
|
||||
SYNOPSIS
|
||||
Event_queue::init_mutexes()
|
||||
*/
|
||||
|
||||
void
|
||||
Event_queue::init_mutexes()
|
||||
{
|
||||
pthread_mutex_init(&LOCK_event_queue, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_queue_state, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Destroys mutexes.
|
||||
|
||||
SYNOPSIS
|
||||
Event_queue::deinit_mutexes()
|
||||
*/
|
||||
|
||||
void
|
||||
Event_queue::deinit_mutexes()
|
||||
Event_queue::~Event_queue()
|
||||
{
|
||||
deinit_queue();
|
||||
pthread_mutex_destroy(&LOCK_event_queue);
|
||||
pthread_cond_destroy(&COND_queue_state);
|
||||
}
|
||||
|
@ -176,34 +158,47 @@ Event_queue::deinit_queue()
|
|||
/**
|
||||
Adds an event to the queue.
|
||||
|
||||
SYNOPSIS
|
||||
Event_queue::create_event()
|
||||
dbname The schema of the new event
|
||||
name The name of the new event
|
||||
Compute the next execution time for an event, and if it is still
|
||||
active, add it to the queue. Otherwise delete it.
|
||||
The object is left intact in case of an error. Otherwise
|
||||
the queue container assumes ownership of it.
|
||||
|
||||
@param[in] thd thread handle
|
||||
@param[in] new_element a new element to add to the queue
|
||||
@param[out] created set to TRUE if no error and the element is
|
||||
added to the queue, FALSE otherwise
|
||||
|
||||
@retval TRUE an error occured. The value of created is undefined,
|
||||
the element was not deleted.
|
||||
@retval FALSE success
|
||||
*/
|
||||
|
||||
void
|
||||
Event_queue::create_event(THD *thd, Event_queue_element *new_element)
|
||||
bool
|
||||
Event_queue::create_event(THD *thd, Event_queue_element *new_element,
|
||||
bool *created)
|
||||
{
|
||||
DBUG_ENTER("Event_queue::create_event");
|
||||
DBUG_PRINT("enter", ("thd: 0x%lx et=%s.%s", (long) thd,
|
||||
new_element->dbname.str, new_element->name.str));
|
||||
|
||||
if ((new_element->status == Event_queue_element::DISABLED)
|
||||
|| (new_element->status == Event_queue_element::SLAVESIDE_DISABLED))
|
||||
delete new_element;
|
||||
else
|
||||
/* Will do nothing if the event is disabled */
|
||||
new_element->compute_next_execution_time();
|
||||
if (new_element->status != Event_queue_element::ENABLED)
|
||||
{
|
||||
new_element->compute_next_execution_time();
|
||||
DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
|
||||
|
||||
LOCK_QUEUE_DATA();
|
||||
queue_insert_safe(&queue, (byte *) new_element);
|
||||
dbug_dump_queue(thd->query_start());
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
UNLOCK_QUEUE_DATA();
|
||||
delete new_element;
|
||||
*created= FALSE;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
|
||||
|
||||
LOCK_QUEUE_DATA();
|
||||
*created= (queue_insert_safe(&queue, (byte *) new_element) == FALSE);
|
||||
dbug_dump_queue(thd->query_start());
|
||||
pthread_cond_broadcast(&COND_queue_state);
|
||||
UNLOCK_QUEUE_DATA();
|
||||
|
||||
DBUG_RETURN(!*created);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,23 +25,16 @@ class Event_queue
|
|||
{
|
||||
public:
|
||||
Event_queue();
|
||||
|
||||
void
|
||||
init_mutexes();
|
||||
|
||||
void
|
||||
deinit_mutexes();
|
||||
~Event_queue();
|
||||
|
||||
bool
|
||||
init_queue(THD *thd);
|
||||
|
||||
void
|
||||
deinit_queue();
|
||||
|
||||
/* Methods for queue management follow */
|
||||
|
||||
void
|
||||
create_event(THD *thd, Event_queue_element *new_element);
|
||||
bool
|
||||
create_event(THD *thd, Event_queue_element *new_element,
|
||||
bool *created);
|
||||
|
||||
void
|
||||
update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
|
||||
|
@ -64,9 +57,23 @@ public:
|
|||
void
|
||||
dump_internal_status();
|
||||
|
||||
private:
|
||||
void
|
||||
empty_queue();
|
||||
protected:
|
||||
|
||||
void
|
||||
deinit_queue();
|
||||
/* helper functions for working with mutexes & conditionals */
|
||||
void
|
||||
lock_data(const char *func, uint line);
|
||||
|
||||
void
|
||||
unlock_data(const char *func, uint line);
|
||||
|
||||
void
|
||||
cond_wait(THD *thd, struct timespec *abstime, const char* msg,
|
||||
const char *func, uint line);
|
||||
|
||||
void
|
||||
find_n_remove_event(LEX_STRING db, LEX_STRING name);
|
||||
|
||||
|
@ -98,16 +105,6 @@ protected:
|
|||
bool mutex_queue_data_attempting_lock;
|
||||
bool waiting_on_cond;
|
||||
|
||||
/* helper functions for working with mutexes & conditionals */
|
||||
void
|
||||
lock_data(const char *func, uint line);
|
||||
|
||||
void
|
||||
unlock_data(const char *func, uint line);
|
||||
|
||||
void
|
||||
cond_wait(THD *thd, struct timespec *abstime, const char* msg,
|
||||
const char *func, uint line);
|
||||
};
|
||||
|
||||
#endif /* _EVENT_QUEUE_H_ */
|
||||
|
|
|
@ -37,7 +37,6 @@ extern pthread_attr_t connection_attrib;
|
|||
|
||||
|
||||
Event_db_repository *Event_worker_thread::db_repository;
|
||||
Events *Event_worker_thread::events_facade;
|
||||
|
||||
|
||||
static
|
||||
|
@ -80,11 +79,11 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et)
|
|||
prefix.length(0);
|
||||
prefix.append("Event Scheduler: [");
|
||||
|
||||
append_identifier(thd, &prefix, et->definer.str, et->definer.length);
|
||||
prefix.append(et->definer.str, et->definer.length, system_charset_info);
|
||||
prefix.append("][", 2);
|
||||
append_identifier(thd,&prefix, et->dbname.str, et->dbname.length);
|
||||
prefix.append(et->dbname.str, et->dbname.length, system_charset_info);
|
||||
prefix.append('.');
|
||||
append_identifier(thd,&prefix, et->name.str, et->name.length);
|
||||
prefix.append(et->name.str, et->name.length, system_charset_info);
|
||||
prefix.append("] ", 2);
|
||||
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
|
||||
|
@ -95,7 +94,6 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et)
|
|||
err_msg.length(0);
|
||||
err_msg.append(prefix);
|
||||
err_msg.append(err->msg, strlen(err->msg), system_charset_info);
|
||||
err_msg.append("]");
|
||||
DBUG_ASSERT(err->level < 3);
|
||||
(sql_print_message_handlers[err->level])("%*s", err_msg.length(),
|
||||
err_msg.c_ptr());
|
||||
|
@ -239,7 +237,7 @@ event_scheduler_thread(void *arg)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Function that executes an event in a child thread. Setups the
|
||||
environment for the event execution and cleans after that.
|
||||
|
||||
|
@ -266,7 +264,7 @@ event_worker_thread(void *arg)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Function that executes an event in a child thread. Setups the
|
||||
environment for the event execution and cleans after that.
|
||||
|
||||
|
@ -311,104 +309,61 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
|
|||
|
||||
thd->enable_slow_log= TRUE;
|
||||
|
||||
ret= job_data->execute(thd);
|
||||
ret= job_data->execute(thd, event->dropped);
|
||||
|
||||
print_warnings(thd, job_data);
|
||||
|
||||
sql_print_information("Event Scheduler: "
|
||||
"[%s.%s of %s] executed in thread %lu. "
|
||||
"RetCode=%d", job_data->dbname.str, job_data->name.str,
|
||||
job_data->definer.str, thd->thread_id, ret);
|
||||
if (ret == EVEX_COMPILE_ERROR)
|
||||
switch (ret) {
|
||||
case 0:
|
||||
sql_print_information("Event Scheduler: "
|
||||
"COMPILE ERROR for event %s.%s of %s",
|
||||
"[%s].[%s.%s] executed successfully in thread %lu.",
|
||||
job_data->definer.str,
|
||||
job_data->dbname.str, job_data->name.str,
|
||||
job_data->definer.str);
|
||||
else if (ret == EVEX_MICROSECOND_UNSUP)
|
||||
sql_print_information("Event Scheduler: MICROSECOND is not supported");
|
||||
thd->thread_id);
|
||||
break;
|
||||
case EVEX_COMPILE_ERROR:
|
||||
sql_print_information("Event Scheduler: "
|
||||
"[%s].[%s.%s] event compilation failed.",
|
||||
job_data->definer.str,
|
||||
job_data->dbname.str, job_data->name.str);
|
||||
break;
|
||||
default:
|
||||
sql_print_information("Event Scheduler: "
|
||||
"[%s].[%s.%s] event execution failed.",
|
||||
job_data->definer.str,
|
||||
job_data->dbname.str, job_data->name.str);
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
delete job_data;
|
||||
|
||||
if (event->dropped)
|
||||
{
|
||||
sql_print_information("Event Scheduler: Dropping %s.%s",
|
||||
event->dbname.str, event->name.str);
|
||||
/*
|
||||
Using db_repository can lead to a race condition because we access
|
||||
the table without holding LOCK_metadata.
|
||||
Scenario:
|
||||
1. CREATE EVENT xyz AT ... (conn thread)
|
||||
2. execute xyz (worker)
|
||||
3. CREATE EVENT XYZ EVERY ... (conn thread)
|
||||
4. drop xyz (worker)
|
||||
5. XYZ was just created on disk but `drop xyz` of the worker dropped it.
|
||||
A consequent load to create Event_queue_element will fail.
|
||||
|
||||
If all operations are performed under LOCK_metadata there is no such
|
||||
problem. However, this comes at the price of introduction bi-directional
|
||||
association between class Events and class Event_worker_thread.
|
||||
*/
|
||||
events_facade->drop_event(thd, event->dbname, event->name, FALSE);
|
||||
}
|
||||
DBUG_PRINT("info", ("Done with Event %s.%s", event->dbname.str,
|
||||
event->name.str));
|
||||
|
||||
delete event;
|
||||
deinit_event_thread(thd);
|
||||
pthread_exit(0);
|
||||
/*
|
||||
Do not pthread_exit since we want local destructors for stack objects
|
||||
to be invoked.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Performs initialization of the scheduler data, outside of the
|
||||
threading primitives.
|
||||
|
||||
SYNOPSIS
|
||||
Event_scheduler::init_scheduler()
|
||||
*/
|
||||
|
||||
void
|
||||
Event_scheduler::init_scheduler(Event_queue *q)
|
||||
{
|
||||
LOCK_DATA();
|
||||
queue= q;
|
||||
started_events= 0;
|
||||
scheduler_thd= NULL;
|
||||
state= INITIALIZED;
|
||||
UNLOCK_DATA();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Event_scheduler::deinit_scheduler() {}
|
||||
|
||||
|
||||
/*
|
||||
Inits scheduler's threading primitives.
|
||||
|
||||
SYNOPSIS
|
||||
Event_scheduler::init_mutexes()
|
||||
*/
|
||||
|
||||
void
|
||||
Event_scheduler::init_mutexes()
|
||||
Event_scheduler::Event_scheduler(Event_queue *queue_arg)
|
||||
:state(UNINITIALIZED),
|
||||
scheduler_thd(NULL),
|
||||
queue(queue_arg),
|
||||
started_events(0)
|
||||
{
|
||||
pthread_mutex_init(&LOCK_scheduler_state, MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_state, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Deinits scheduler's threading primitives.
|
||||
|
||||
SYNOPSIS
|
||||
Event_scheduler::deinit_mutexes()
|
||||
*/
|
||||
|
||||
void
|
||||
Event_scheduler::deinit_mutexes()
|
||||
Event_scheduler::~Event_scheduler()
|
||||
{
|
||||
stop(); /* does nothing if not running */
|
||||
pthread_mutex_destroy(&LOCK_scheduler_state);
|
||||
pthread_cond_destroy(&COND_state);
|
||||
}
|
||||
|
@ -639,6 +594,9 @@ Event_scheduler::is_running()
|
|||
Stops the scheduler (again). Waits for acknowledgement from the
|
||||
scheduler that it has stopped - synchronous stopping.
|
||||
|
||||
Already running events will not be stopped. If the user needs
|
||||
them stopped manual intervention is needed.
|
||||
|
||||
SYNOPSIS
|
||||
Event_scheduler::stop()
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
This file is internal to Events module. Please do not include it directly.
|
||||
All public declarations of Events module are in events.h and
|
||||
event_data_objects.h.
|
||||
|
@ -41,10 +42,9 @@ class Event_worker_thread
|
|||
{
|
||||
public:
|
||||
static void
|
||||
init(Events *events, Event_db_repository *db_repo)
|
||||
init(Event_db_repository *db_repository_arg)
|
||||
{
|
||||
db_repository= db_repo;
|
||||
events_facade= events;
|
||||
db_repository= db_repository_arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -55,15 +55,15 @@ private:
|
|||
print_warnings(THD *thd, Event_job_data *et);
|
||||
|
||||
static Event_db_repository *db_repository;
|
||||
static Events *events_facade;
|
||||
};
|
||||
|
||||
|
||||
class Event_scheduler
|
||||
{
|
||||
public:
|
||||
Event_scheduler():state(UNINITIALIZED){}
|
||||
~Event_scheduler(){}
|
||||
Event_scheduler(Event_queue *event_queue_arg);
|
||||
~Event_scheduler();
|
||||
|
||||
|
||||
/* State changing methods follow */
|
||||
|
||||
|
@ -80,17 +80,6 @@ public:
|
|||
bool
|
||||
run(THD *thd);
|
||||
|
||||
void
|
||||
init_scheduler(Event_queue *queue);
|
||||
|
||||
void
|
||||
deinit_scheduler();
|
||||
|
||||
void
|
||||
init_mutexes();
|
||||
|
||||
void
|
||||
deinit_mutexes();
|
||||
|
||||
/* Information retrieving methods follow */
|
||||
bool
|
||||
|
|
982
sql/events.cc
982
sql/events.cc
File diff suppressed because it is too large
Load diff
106
sql/events.h
106
sql/events.h
|
@ -15,7 +15,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
class sp_name;
|
||||
/*
|
||||
@file
|
||||
A public interface of Events Scheduler module.
|
||||
*/
|
||||
|
||||
class Event_parse_data;
|
||||
class Event_db_repository;
|
||||
class Event_queue;
|
||||
|
@ -40,6 +44,22 @@ sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
|
|||
/**
|
||||
@class Events -- a facade to the functionality of the Event Scheduler.
|
||||
|
||||
Every public operation against the scheduler has to be executed via the
|
||||
interface provided by a static method of this class. No instance of this
|
||||
class is ever created and it has no non-static data members.
|
||||
|
||||
The life cycle of the Events module is the following:
|
||||
|
||||
At server start up:
|
||||
set_opt_event_scheduler() -> init_mutexes() -> init()
|
||||
When the server is running:
|
||||
create_event(), drop_event(), start_or_stop_event_scheduler(), etc
|
||||
At shutdown:
|
||||
deinit(), destroy_mutexes().
|
||||
|
||||
The peculiar initialization and shutdown cycle is an adaptation to the
|
||||
outside server startup/shutdown framework and mimics the rest of MySQL
|
||||
subsystems (ACL, time zone tables, etc).
|
||||
*/
|
||||
|
||||
class Events
|
||||
|
@ -53,47 +73,48 @@ public:
|
|||
EVENTS_DISABLED= 4
|
||||
};
|
||||
|
||||
static enum_opt_event_scheduler opt_event_scheduler;
|
||||
static TYPELIB opt_typelib;
|
||||
static TYPELIB var_typelib;
|
||||
/* Possible values of @@event_scheduler variable */
|
||||
static const TYPELIB var_typelib;
|
||||
|
||||
bool
|
||||
init();
|
||||
static bool
|
||||
set_opt_event_scheduler(char *argument);
|
||||
|
||||
void
|
||||
static const char *
|
||||
get_opt_event_scheduler_str();
|
||||
|
||||
/* A hack needed for Event_queue_element */
|
||||
static Event_db_repository *
|
||||
get_db_repository() { return db_repository; }
|
||||
|
||||
static bool
|
||||
init(my_bool opt_noacl);
|
||||
|
||||
static void
|
||||
deinit();
|
||||
|
||||
void
|
||||
static void
|
||||
init_mutexes();
|
||||
|
||||
void
|
||||
static void
|
||||
destroy_mutexes();
|
||||
|
||||
bool
|
||||
start_execution_of_events();
|
||||
static bool
|
||||
switch_event_scheduler_state(enum enum_opt_event_scheduler new_state);
|
||||
|
||||
bool
|
||||
stop_execution_of_events();
|
||||
|
||||
bool
|
||||
is_execution_of_events_started();
|
||||
|
||||
static Events *
|
||||
get_instance();
|
||||
|
||||
bool
|
||||
static bool
|
||||
create_event(THD *thd, Event_parse_data *parse_data, bool if_exists);
|
||||
|
||||
bool
|
||||
update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to);
|
||||
static bool
|
||||
update_event(THD *thd, Event_parse_data *parse_data,
|
||||
LEX_STRING *new_dbname, LEX_STRING *new_name);
|
||||
|
||||
bool
|
||||
static bool
|
||||
drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists);
|
||||
|
||||
void
|
||||
static void
|
||||
drop_schema_events(THD *thd, char *db);
|
||||
|
||||
bool
|
||||
static bool
|
||||
show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
|
||||
|
||||
/* Needed for both SHOW CREATE EVENT and INFORMATION_SCHEMA */
|
||||
|
@ -104,31 +125,28 @@ public:
|
|||
static int
|
||||
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
|
||||
|
||||
void
|
||||
static void
|
||||
dump_internal_status();
|
||||
|
||||
private:
|
||||
bool
|
||||
check_system_tables(THD *thd);
|
||||
static bool check_if_system_tables_error();
|
||||
|
||||
int
|
||||
static bool
|
||||
load_events_from_db(THD *thd);
|
||||
|
||||
/* Singleton DP is used */
|
||||
Events();
|
||||
~Events(){}
|
||||
|
||||
/* Singleton instance */
|
||||
static Events singleton;
|
||||
|
||||
Event_queue *event_queue;
|
||||
Event_scheduler *scheduler;
|
||||
Event_db_repository *db_repository;
|
||||
|
||||
pthread_mutex_t LOCK_event_metadata;
|
||||
|
||||
bool check_system_tables_error;
|
||||
private:
|
||||
/* Command line option names */
|
||||
static const TYPELIB opt_typelib;
|
||||
static pthread_mutex_t LOCK_event_metadata;
|
||||
static Event_queue *event_queue;
|
||||
static Event_scheduler *scheduler;
|
||||
static Event_db_repository *db_repository;
|
||||
/* Current state of Event Scheduler */
|
||||
static enum enum_opt_event_scheduler opt_event_scheduler;
|
||||
/* Set to TRUE if an error at start up */
|
||||
static bool check_system_tables_error;
|
||||
|
||||
private:
|
||||
/* Prevent use of these */
|
||||
Events(const Events &);
|
||||
void operator=(Events &);
|
||||
|
|
|
@ -885,7 +885,7 @@ static void close_connections(void)
|
|||
}
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
|
||||
|
||||
Events::get_instance()->deinit();
|
||||
Events::deinit();
|
||||
end_slave();
|
||||
|
||||
if (thread_count)
|
||||
|
@ -1330,7 +1330,7 @@ static void clean_up_mutexes()
|
|||
(void) pthread_mutex_destroy(&LOCK_bytes_sent);
|
||||
(void) pthread_mutex_destroy(&LOCK_bytes_received);
|
||||
(void) pthread_mutex_destroy(&LOCK_user_conn);
|
||||
Events::get_instance()->destroy_mutexes();
|
||||
Events::destroy_mutexes();
|
||||
#ifdef HAVE_OPENSSL
|
||||
(void) pthread_mutex_destroy(&LOCK_des_key_file);
|
||||
#ifndef HAVE_YASSL
|
||||
|
@ -3058,7 +3058,7 @@ static int init_thread_environment()
|
|||
(void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_cond_init(&COND_server_started,NULL);
|
||||
sp_cache_init();
|
||||
Events::get_instance()->init_mutexes();
|
||||
Events::init_mutexes();
|
||||
/* Parameter for threads created for connections */
|
||||
(void) pthread_attr_init(&connection_attrib);
|
||||
(void) pthread_attr_setdetachstate(&connection_attrib,
|
||||
|
@ -3844,21 +3844,15 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
|||
create_shutdown_thread();
|
||||
create_maintenance_thread();
|
||||
|
||||
if (Events::init(opt_noacl))
|
||||
unireg_abort(1);
|
||||
|
||||
sql_print_information(ER(ER_STARTUP),my_progname,server_version,
|
||||
((unix_sock == INVALID_SOCKET) ? (char*) ""
|
||||
: mysqld_unix_port),
|
||||
mysqld_port,
|
||||
MYSQL_COMPILATION_COMMENT);
|
||||
|
||||
if (!opt_noacl)
|
||||
{
|
||||
if (Events::get_instance()->init())
|
||||
unireg_abort(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Events::opt_event_scheduler = Events::EVENTS_DISABLED;
|
||||
}
|
||||
|
||||
/* Signal threads waiting for server to be started */
|
||||
pthread_mutex_lock(&LOCK_server_started);
|
||||
|
@ -7597,32 +7591,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
}
|
||||
#endif
|
||||
case OPT_EVENT_SCHEDULER:
|
||||
if (!argument)
|
||||
Events::opt_event_scheduler= Events::EVENTS_DISABLED;
|
||||
else
|
||||
{
|
||||
int type;
|
||||
/*
|
||||
type= 5 1 2 3 4
|
||||
(DISABLE ) - (OFF | ON) - (0 | 1)
|
||||
*/
|
||||
switch ((type=find_type(argument, &Events::opt_typelib, 1))) {
|
||||
case 0:
|
||||
fprintf(stderr, "Unknown option to event-scheduler: %s\n",argument);
|
||||
exit(1);
|
||||
case 5: /* OPT_DISABLED */
|
||||
Events::opt_event_scheduler= Events::EVENTS_DISABLED;
|
||||
break;
|
||||
case 2: /* OPT_ON */
|
||||
case 4: /* 1 */
|
||||
Events::opt_event_scheduler= Events::EVENTS_ON;
|
||||
break;
|
||||
case 1: /* OPT_OFF */
|
||||
case 3: /* 0 */
|
||||
Events::opt_event_scheduler= Events::EVENTS_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Events::set_opt_event_scheduler(argument))
|
||||
exit(1);
|
||||
break;
|
||||
case (int) OPT_SKIP_NEW:
|
||||
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
|
||||
|
|
|
@ -1686,7 +1686,7 @@ byte *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
|
|||
}
|
||||
|
||||
|
||||
bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names)
|
||||
bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
|
||||
{
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
const char *value;
|
||||
|
@ -3643,21 +3643,18 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
|
|||
SYNOPSIS
|
||||
thd in thread handler
|
||||
val in sql_mode value
|
||||
len out pointer on length of string
|
||||
|
||||
RETURN
|
||||
pointer to string with sql_mode representation
|
||||
rep out pointer pointer to string with sql_mode representation
|
||||
*/
|
||||
|
||||
byte *sys_var_thd_sql_mode::symbolic_mode_representation(THD *thd,
|
||||
ulonglong val,
|
||||
ulong *len)
|
||||
bool
|
||||
sys_var_thd_sql_mode::
|
||||
symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
|
||||
{
|
||||
char buff[256];
|
||||
char buff[STRING_BUFFER_USUAL_SIZE*8];
|
||||
String tmp(buff, sizeof(buff), &my_charset_latin1);
|
||||
ulong length;
|
||||
|
||||
tmp.length(0);
|
||||
|
||||
for (uint i= 0; val; val>>= 1, i++)
|
||||
{
|
||||
if (val & 1)
|
||||
|
@ -3668,20 +3665,25 @@ byte *sys_var_thd_sql_mode::symbolic_mode_representation(THD *thd,
|
|||
}
|
||||
}
|
||||
|
||||
if ((length= tmp.length()))
|
||||
length--;
|
||||
*len= length;
|
||||
return (byte*) thd->strmake(tmp.ptr(), length);
|
||||
if (tmp.length())
|
||||
tmp.length(tmp.length() - 1); /* trim the trailing comma */
|
||||
|
||||
rep->str= thd->strmake(tmp.ptr(), tmp.length());
|
||||
|
||||
rep->length= rep->str ? tmp.length() : 0;
|
||||
|
||||
return rep->length != tmp.length();
|
||||
}
|
||||
|
||||
|
||||
byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
|
||||
LEX_STRING *base)
|
||||
{
|
||||
LEX_STRING sql_mode;
|
||||
ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
|
||||
thd->variables.*offset);
|
||||
ulong length_unused;
|
||||
return symbolic_mode_representation(thd, val, &length_unused);
|
||||
(void) symbolic_mode_representation(thd, val, &sql_mode);
|
||||
return (byte *) sql_mode.str;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4012,24 +4014,13 @@ sys_var_event_scheduler::update(THD *thd, set_var *var)
|
|||
int res;
|
||||
/* here start the thread if not running. */
|
||||
DBUG_ENTER("sys_var_event_scheduler::update");
|
||||
if (Events::opt_event_scheduler == Events::EVENTS_DISABLED)
|
||||
{
|
||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED or --skip-grant-tables");
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
|
||||
|
||||
if (var->save_result.ulong_value == Events::EVENTS_ON)
|
||||
res= Events::get_instance()->start_execution_of_events();
|
||||
else if (var->save_result.ulong_value == Events::EVENTS_OFF)
|
||||
res= Events::get_instance()->stop_execution_of_events();
|
||||
else
|
||||
{
|
||||
assert(0); // Impossible
|
||||
}
|
||||
if (res)
|
||||
my_error(ER_EVENT_SET_VAR_ERROR, MYF(0));
|
||||
enum Events::enum_opt_event_scheduler
|
||||
new_state=
|
||||
(enum Events::enum_opt_event_scheduler) var->save_result.ulong_value;
|
||||
|
||||
res= Events::switch_event_scheduler_state(new_state);
|
||||
|
||||
DBUG_RETURN((bool) res);
|
||||
}
|
||||
|
@ -4038,15 +4029,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var)
|
|||
byte *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
|
||||
LEX_STRING *base)
|
||||
{
|
||||
int state;
|
||||
if (Events::opt_event_scheduler == Events::EVENTS_DISABLED)
|
||||
state= Events::EVENTS_DISABLED; // This should be DISABLED
|
||||
else if (Events::get_instance()->is_execution_of_events_started())
|
||||
state= Events::EVENTS_ON; // This should be ON
|
||||
else
|
||||
state= Events::EVENTS_OFF; // This should be OFF
|
||||
|
||||
return (byte*) Events::opt_typelib.type_names[state];
|
||||
return (byte *) Events::get_opt_event_scheduler_str();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
sys_vars++;
|
||||
}
|
||||
virtual bool check(THD *thd, set_var *var);
|
||||
bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names);
|
||||
bool check_enum(THD *thd, set_var *var, const TYPELIB *enum_names);
|
||||
bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
|
||||
virtual bool update(THD *thd, set_var *var)=0;
|
||||
virtual void set_default(THD *thd_arg, enum_var_type type) {}
|
||||
|
@ -450,8 +450,8 @@ public:
|
|||
}
|
||||
void set_default(THD *thd, enum_var_type type);
|
||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||
static byte *symbolic_mode_representation(THD *thd, ulonglong sql_mode,
|
||||
ulong *length);
|
||||
static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
|
||||
LEX_STRING *rep);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5884,8 +5884,8 @@ ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
|
|||
eng "Column count of mysql.%s is wrong. Expected %d, found %d. The table is probably corrupted"
|
||||
ger "Spaltenanzahl von mysql.%s falsch. %d erwartet, aber %d gefunden. Tabelle ist wahrscheinlich beschädigt"
|
||||
ER_CANNOT_LOAD_FROM_TABLE
|
||||
eng "Cannot load from mysql.%s. The table is probably corrupted. Please see the error log for details"
|
||||
ger "Kann mysql.%s nicht einlesen. Tabelle ist wahrscheinlich beschädigt, siehe Fehlerlog"
|
||||
eng "Cannot load from mysql.%s. The table is probably corrupted"
|
||||
ger "Kann mysql.%s nicht einlesen. Tabelle ist wahrscheinlich beschädigt"
|
||||
ER_EVENT_CANNOT_DELETE
|
||||
eng "Failed to delete the event from mysql.event"
|
||||
ger "Löschen des Events aus mysql.event fehlgeschlagen"
|
||||
|
|
|
@ -2104,24 +2104,18 @@ sp_head::show_create_procedure(THD *thd)
|
|||
String buffer(buff, sizeof(buff), system_charset_info);
|
||||
int res;
|
||||
List<Item> field_list;
|
||||
byte *sql_mode_str;
|
||||
ulong sql_mode_len;
|
||||
LEX_STRING sql_mode;
|
||||
bool full_access;
|
||||
DBUG_ENTER("sp_head::show_create_procedure");
|
||||
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
||||
|
||||
LINT_INIT(sql_mode_str);
|
||||
LINT_INIT(sql_mode_len);
|
||||
|
||||
if (check_show_routine_access(thd, this, &full_access))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
sql_mode_str=
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
|
||||
m_sql_mode,
|
||||
&sql_mode_len);
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode,
|
||||
&sql_mode);
|
||||
field_list.push_back(new Item_empty_string("Procedure", NAME_LEN));
|
||||
field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len));
|
||||
field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length));
|
||||
// 1024 is for not to confuse old clients
|
||||
Item_empty_string *definition=
|
||||
new Item_empty_string("Create Procedure", max(buffer.length(),1024));
|
||||
|
@ -2133,7 +2127,7 @@ sp_head::show_create_procedure(THD *thd)
|
|||
DBUG_RETURN(1);
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(m_name.str, m_name.length, system_charset_info);
|
||||
protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
|
||||
protocol->store((char*) sql_mode.str, sql_mode.length, system_charset_info);
|
||||
if (full_access)
|
||||
protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
|
||||
else
|
||||
|
@ -2176,23 +2170,18 @@ sp_head::show_create_function(THD *thd)
|
|||
String buffer(buff, sizeof(buff), system_charset_info);
|
||||
int res;
|
||||
List<Item> field_list;
|
||||
byte *sql_mode_str;
|
||||
ulong sql_mode_len;
|
||||
LEX_STRING sql_mode;
|
||||
bool full_access;
|
||||
DBUG_ENTER("sp_head::show_create_function");
|
||||
DBUG_PRINT("info", ("procedure %s", m_name.str));
|
||||
LINT_INIT(sql_mode_str);
|
||||
LINT_INIT(sql_mode_len);
|
||||
|
||||
if (check_show_routine_access(thd, this, &full_access))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
sql_mode_str=
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
|
||||
m_sql_mode,
|
||||
&sql_mode_len);
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode,
|
||||
&sql_mode);
|
||||
field_list.push_back(new Item_empty_string("Function",NAME_LEN));
|
||||
field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len));
|
||||
field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length));
|
||||
Item_empty_string *definition=
|
||||
new Item_empty_string("Create Function", max(buffer.length(),1024));
|
||||
definition->maybe_null= TRUE;
|
||||
|
@ -2203,7 +2192,7 @@ sp_head::show_create_function(THD *thd)
|
|||
DBUG_RETURN(1);
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(m_name.str, m_name.length, system_charset_info);
|
||||
protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
|
||||
protocol->store(sql_mode.str, sql_mode.length, system_charset_info);
|
||||
if (full_access)
|
||||
protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
|
||||
else
|
||||
|
|
|
@ -953,7 +953,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
|
|||
|
||||
exit:
|
||||
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
|
||||
Events::get_instance()->drop_schema_events(thd, db);
|
||||
Events::drop_schema_events(thd, db);
|
||||
/*
|
||||
If this database was the client's selected database, we silently
|
||||
change the client's selected database to nothing (to have an empty
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "sp.h"
|
||||
#include "sp_cache.h"
|
||||
#include "events.h"
|
||||
#include "event_data_objects.h"
|
||||
#include "sql_trigger.h"
|
||||
|
||||
/* Used in error handling only */
|
||||
|
@ -3181,13 +3180,16 @@ end_with_restore_list:
|
|||
|
||||
switch (lex->sql_command) {
|
||||
case SQLCOM_CREATE_EVENT:
|
||||
res= Events::get_instance()->
|
||||
create_event(thd, lex->event_parse_data,
|
||||
lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS);
|
||||
{
|
||||
bool if_not_exists= (lex->create_info.options &
|
||||
HA_LEX_CREATE_IF_NOT_EXISTS);
|
||||
res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_ALTER_EVENT:
|
||||
res= Events::get_instance()->update_event(thd, lex->event_parse_data,
|
||||
lex->spname);
|
||||
res= Events::update_event(thd, lex->event_parse_data,
|
||||
lex->spname ? &lex->spname->m_db : NULL,
|
||||
lex->spname ? &lex->spname->m_name : NULL);
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
|
@ -3205,39 +3207,16 @@ end_with_restore_list:
|
|||
}
|
||||
/* lex->unit.cleanup() is called outside, no need to call it here */
|
||||
break;
|
||||
case SQLCOM_DROP_EVENT:
|
||||
case SQLCOM_SHOW_CREATE_EVENT:
|
||||
{
|
||||
DBUG_ASSERT(lex->spname);
|
||||
if (! lex->spname->m_db.str)
|
||||
{
|
||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||
goto error;
|
||||
}
|
||||
if (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0,
|
||||
is_schema_db(lex->spname->m_db.str)))
|
||||
break;
|
||||
|
||||
if (lex->spname->m_name.length > NAME_LEN)
|
||||
{
|
||||
my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
|
||||
/* this jumps to the end of the function and skips own messaging */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (lex->sql_command == SQLCOM_SHOW_CREATE_EVENT)
|
||||
res= Events::get_instance()->show_create_event(thd, lex->spname->m_db,
|
||||
lex->spname->m_name);
|
||||
else
|
||||
{
|
||||
if (!(res= Events::get_instance()->drop_event(thd,
|
||||
lex->spname->m_db,
|
||||
lex->spname->m_name,
|
||||
lex->drop_if_exists)))
|
||||
send_ok(thd);
|
||||
}
|
||||
res= Events::show_create_event(thd, lex->spname->m_db,
|
||||
lex->spname->m_name);
|
||||
break;
|
||||
case SQLCOM_DROP_EVENT:
|
||||
if (!(res= Events::drop_event(thd,
|
||||
lex->spname->m_db, lex->spname->m_name,
|
||||
lex->drop_if_exists)))
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CREATE_FUNCTION: // UDF function
|
||||
{
|
||||
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
|
||||
|
|
|
@ -3761,8 +3761,7 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
|
|||
LEX_STRING *definer_buffer)
|
||||
{
|
||||
CHARSET_INFO *cs= system_charset_info;
|
||||
byte *sql_mode_str;
|
||||
ulong sql_mode_len;
|
||||
LEX_STRING sql_mode_rep;
|
||||
|
||||
restore_record(table, s->default_values);
|
||||
table->field[1]->store(db, strlen(db), cs);
|
||||
|
@ -3778,11 +3777,9 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
|
|||
table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
|
||||
table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
|
||||
|
||||
sql_mode_str=
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
|
||||
sql_mode,
|
||||
&sql_mode_len);
|
||||
table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
|
||||
&sql_mode_rep);
|
||||
table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
|
||||
table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
|
||||
return schema_table_store_record(thd, table);
|
||||
}
|
||||
|
@ -4308,13 +4305,13 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
|||
CHARSET_INFO *scs= system_charset_info;
|
||||
TIME time;
|
||||
Event_timed et;
|
||||
DBUG_ENTER("fill_events_copy_to_schema_tab");
|
||||
DBUG_ENTER("copy_event_to_schema_table");
|
||||
|
||||
restore_record(sch_table, s->default_values);
|
||||
|
||||
if (et.load_from_row(thd, event_table))
|
||||
{
|
||||
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0));
|
||||
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
@ -4349,13 +4346,11 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
|||
|
||||
/* SQL_MODE */
|
||||
{
|
||||
byte *sql_mode_str;
|
||||
ulong sql_mode_len= 0;
|
||||
sql_mode_str=
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
|
||||
&sql_mode_len);
|
||||
LEX_STRING sql_mode;
|
||||
sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
|
||||
&sql_mode);
|
||||
sch_table->field[ISE_SQL_MODE]->
|
||||
store((const char*)sql_mode_str, sql_mode_len, scs);
|
||||
store(sql_mode.str, sql_mode.length, scs);
|
||||
}
|
||||
|
||||
int not_used=0;
|
||||
|
|
|
@ -537,6 +537,6 @@ Estimated memory (with thread stack): %ld\n",
|
|||
(long) (thread_count * thread_stack + info.hblkhd + info.arena));
|
||||
#endif
|
||||
|
||||
Events::get_instance()->dump_internal_status();
|
||||
Events::dump_internal_status();
|
||||
puts("");
|
||||
}
|
||||
|
|
|
@ -949,7 +949,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token SIGNED_SYM
|
||||
%token SIMPLE_SYM /* SQL-2003-N */
|
||||
%token SLAVE
|
||||
%token SLAVESIDE_DISABLE_SYM
|
||||
%token SMALLINT /* SQL-2003-R */
|
||||
%token SNAPSHOT_SYM
|
||||
%token SOCKET_SYM
|
||||
|
@ -10010,7 +10009,6 @@ keyword_sp:
|
|||
| SIMPLE_SYM {}
|
||||
| SHARE_SYM {}
|
||||
| SHUTDOWN {}
|
||||
| SLAVESIDE_DISABLE_SYM {}
|
||||
| SNAPSHOT_SYM {}
|
||||
| SOUNDS_SYM {}
|
||||
| SQL_CACHE_SYM {}
|
||||
|
|
265
sql/table.cc
265
sql/table.cc
|
@ -250,7 +250,7 @@ void free_table_share(TABLE_SHARE *share)
|
|||
Currently these are:
|
||||
|
||||
help_category, help_keyword, help_relation, help_topic,
|
||||
proc,
|
||||
proc, event
|
||||
time_zone, time_zone_leap_second, time_zone_name, time_zone_transition,
|
||||
time_zone_transition_type
|
||||
|
||||
|
@ -283,7 +283,14 @@ inline bool is_system_table_name(const char *name, uint length)
|
|||
my_tolower(ci, name[0]) == 't' &&
|
||||
my_tolower(ci, name[1]) == 'i' &&
|
||||
my_tolower(ci, name[2]) == 'm' &&
|
||||
my_tolower(ci, name[3]) == 'e'
|
||||
my_tolower(ci, name[3]) == 'e' ||
|
||||
|
||||
/* mysql.event table */
|
||||
my_tolower(ci, name[0]) == 'e' &&
|
||||
my_tolower(ci, name[1]) == 'v' &&
|
||||
my_tolower(ci, name[2]) == 'e' &&
|
||||
my_tolower(ci, name[3]) == 'n' &&
|
||||
my_tolower(ci, name[4]) == 't'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -2432,153 +2439,143 @@ bool check_column_name(const char *name)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Checks whether a table is intact. Should be done *just* after the table has
|
||||
been opened.
|
||||
|
||||
SYNOPSIS
|
||||
table_check_intact()
|
||||
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)
|
||||
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
|
||||
is sent to the client in case types does not match.
|
||||
If different col number either
|
||||
ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE or
|
||||
ER_COL_COUNT_DOESNT_MATCH_CORRUPTED is used
|
||||
|
||||
RETURNS
|
||||
FALSE OK
|
||||
TRUE There was an error
|
||||
@param[in] table The table to check
|
||||
@param[in] table_f_count Expected number of columns in the table
|
||||
@param[in] table_def Expected structure of the table (column name
|
||||
and type)
|
||||
|
||||
@retval FALSE OK
|
||||
@retval TRUE There was an error. An error message is output
|
||||
to the error log. We do not push an error
|
||||
message into the error stack because this
|
||||
function is currently only called at start up,
|
||||
and such errors never reach the user.
|
||||
*/
|
||||
|
||||
my_bool
|
||||
table_check_intact(TABLE *table, const uint table_f_count,
|
||||
const TABLE_FIELD_W_TYPE *table_def,
|
||||
time_t *last_create_time, int error_num)
|
||||
const TABLE_FIELD_W_TYPE *table_def)
|
||||
{
|
||||
uint i;
|
||||
my_bool error= FALSE;
|
||||
my_bool fields_diff_count;
|
||||
DBUG_ENTER("table_check_intact");
|
||||
DBUG_PRINT("info",("table: %s expected_count: %d last_create_time: %ld",
|
||||
table->alias, table_f_count, *last_create_time));
|
||||
|
||||
if ((fields_diff_count= (table->s->fields != table_f_count)) ||
|
||||
(*last_create_time != table->file->stats.create_time))
|
||||
{
|
||||
DBUG_PRINT("info", ("I am suspecting, checking table"));
|
||||
if (fields_diff_count)
|
||||
{
|
||||
/* previous MySQL version */
|
||||
error= TRUE;
|
||||
if (MYSQL_VERSION_ID > table->s->mysql_version)
|
||||
{
|
||||
my_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, MYF(0), table->alias,
|
||||
table_f_count, table->s->fields, table->s->mysql_version,
|
||||
MYSQL_VERSION_ID);
|
||||
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
|
||||
table->alias, table_f_count, table->s->fields,
|
||||
table->s->mysql_version, MYSQL_VERSION_ID);
|
||||
DBUG_RETURN(error);
|
||||
DBUG_PRINT("info",("table: %s expected_count: %d",
|
||||
table->alias, table_f_count));
|
||||
|
||||
}
|
||||
else if (MYSQL_VERSION_ID == table->s->mysql_version)
|
||||
{
|
||||
my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED,MYF(0), table->alias,
|
||||
table_f_count, table->s->fields);
|
||||
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
|
||||
table_f_count, table->s->fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Moving from newer mysql to older one -> let's say not an error but
|
||||
will check the definition afterwards. If a column was added at the
|
||||
end then we don't care much since it's not in the middle.
|
||||
*/
|
||||
error= FALSE;
|
||||
}
|
||||
}
|
||||
/* definitely something has changed */
|
||||
char buffer[255];
|
||||
for (i=0 ; i < table_f_count; i++, table_def++)
|
||||
{
|
||||
String sql_type(buffer, sizeof(buffer), system_charset_info);
|
||||
sql_type.length(0);
|
||||
/*
|
||||
Name changes are not fatal, we use sequence numbers => no problem
|
||||
for us but this can show tampered table or broken table.
|
||||
*/
|
||||
if (i < table->s->fields)
|
||||
{
|
||||
Field *field= table->field[i];
|
||||
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,
|
||||
field->field_name);
|
||||
}
|
||||
|
||||
/*
|
||||
If the type does not match than something is really wrong
|
||||
Check up to length - 1. Why?
|
||||
1. datetime -> datetim -> the same
|
||||
2. int(11) -> int(11 -> the same
|
||||
3. set('one','two') -> set('one','two'
|
||||
so for sets if the same prefix is there it's ok if more are
|
||||
added as part of the set. The same is valid for enum. So a new
|
||||
table running on a old server will be valid.
|
||||
*/
|
||||
field->sql_type(sql_type);
|
||||
if (strncmp(sql_type.c_ptr_safe(), 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_safe());
|
||||
error= TRUE;
|
||||
}
|
||||
else if (table_def->cset.str && !field->has_charset())
|
||||
{
|
||||
sql_print_error("(%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);
|
||||
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 "
|
||||
"character set '%s' but found '%s'", table->alias,
|
||||
table_def->name.str, i, table_def->cset.str,
|
||||
field->charset()->csname);
|
||||
error= TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sql_print_error("(%s) Expected field %s at position %d to have type %s "
|
||||
" but no field found.", table->alias,
|
||||
table_def->name.str, i, table_def->type.str);
|
||||
error= TRUE;
|
||||
}
|
||||
}
|
||||
if (!error)
|
||||
*last_create_time= table->file->stats.create_time;
|
||||
else if (!fields_diff_count && error_num)
|
||||
my_error(error_num,MYF(0), table->alias, table_f_count, table->s->fields);
|
||||
}
|
||||
else
|
||||
fields_diff_count= (table->s->fields != table_f_count);
|
||||
if (fields_diff_count)
|
||||
{
|
||||
DBUG_PRINT("info", ("Table seems ok without thorough checking."));
|
||||
*last_create_time= table->file->stats.create_time;
|
||||
DBUG_PRINT("info", ("Column count has changed, checking the definition"));
|
||||
|
||||
/* previous MySQL version */
|
||||
if (MYSQL_VERSION_ID > table->s->mysql_version)
|
||||
{
|
||||
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
|
||||
table->alias, table_f_count, table->s->fields,
|
||||
table->s->mysql_version, MYSQL_VERSION_ID);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else if (MYSQL_VERSION_ID == table->s->mysql_version)
|
||||
{
|
||||
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
|
||||
table_f_count, table->s->fields);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
/*
|
||||
Something has definitely changed, but we're running an older
|
||||
version of MySQL with new system tables.
|
||||
Let's check column definitions. If a column was added at
|
||||
the end of the table, then we don't care much since such change
|
||||
is backward compatible.
|
||||
*/
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
char buffer[STRING_BUFFER_USUAL_SIZE];
|
||||
for (i=0 ; i < table_f_count; i++, table_def++)
|
||||
{
|
||||
String sql_type(buffer, sizeof(buffer), system_charset_info);
|
||||
sql_type.length(0);
|
||||
if (i < table->s->fields)
|
||||
{
|
||||
Field *field= table->field[i];
|
||||
|
||||
if (strncmp(field->field_name, table_def->name.str,
|
||||
table_def->name.length))
|
||||
{
|
||||
/*
|
||||
Name changes are not fatal, we use ordinal numbers to access columns.
|
||||
Still this can be a sign of a tampered table, output an error
|
||||
to the error log.
|
||||
*/
|
||||
sql_print_error("Incorrect definition of table %s.%s: "
|
||||
"expected column '%s' at position %d, found '%s'.",
|
||||
table->s->db.str, table->alias, table_def->name.str, i,
|
||||
field->field_name);
|
||||
}
|
||||
field->sql_type(sql_type);
|
||||
/*
|
||||
Generally, if column types don't match, then something is
|
||||
wrong.
|
||||
|
||||
However, we only compare column definitions up to the
|
||||
length of the original definition, since we consider the
|
||||
following definitions compatible:
|
||||
|
||||
1. DATETIME and DATETIM
|
||||
2. INT(11) and INT(11
|
||||
3. SET('one', 'two') and SET('one', 'two', 'more')
|
||||
|
||||
For SETs or ENUMs, if the same prefix is there it's OK to
|
||||
add more elements - they will get higher ordinal numbers and
|
||||
the new table definition is backward compatible with the
|
||||
original one.
|
||||
*/
|
||||
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
|
||||
table_def->type.length - 1))
|
||||
{
|
||||
sql_print_error("Incorrect definition of table %s.%s: "
|
||||
"expected column '%s' at position %d to have type "
|
||||
"%s, found type %s.", table->s->db.str, table->alias,
|
||||
table_def->name.str, i, table_def->type.str,
|
||||
sql_type.c_ptr_safe());
|
||||
error= TRUE;
|
||||
}
|
||||
else if (table_def->cset.str && !field->has_charset())
|
||||
{
|
||||
sql_print_error("Incorrect definition of table %s.%s: "
|
||||
"expected the type of column '%s' at position %d "
|
||||
"to have character set '%s' but the type has no "
|
||||
"character set.", table->s->db.str, table->alias,
|
||||
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("Incorrect definition of table %s.%s: "
|
||||
"expected the type of column '%s' at position %d "
|
||||
"to have character set '%s' but found "
|
||||
"character set '%s'.", table->s->db.str, table->alias,
|
||||
table_def->name.str, i, table_def->cset.str,
|
||||
field->charset()->csname);
|
||||
error= TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sql_print_error("Incorrect definition of table %s.%s: "
|
||||
"expected column '%s' at position %d to have type %s "
|
||||
" but the column is not found.",
|
||||
table->s->db.str, table->alias,
|
||||
table_def->name.str, i, table_def->type.str);
|
||||
error= TRUE;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
|
18
sql/table.h
18
sql/table.h
|
@ -689,6 +689,21 @@ class index_hint;
|
|||
typedef struct st_table_list
|
||||
{
|
||||
st_table_list() {} /* Remove gcc warning */
|
||||
|
||||
/**
|
||||
Prepare TABLE_LIST that consists of one table instance to use in
|
||||
simple_open_and_lock_tables
|
||||
*/
|
||||
inline void init_one_table(const char *db_name_arg,
|
||||
const char *table_name_arg,
|
||||
enum thr_lock_type lock_type_arg)
|
||||
{
|
||||
bzero((char*) this, sizeof(*this));
|
||||
db= (char*) db_name_arg;
|
||||
table_name= alias= (char*) table_name_arg;
|
||||
lock_type= lock_type_arg;
|
||||
}
|
||||
|
||||
/*
|
||||
List of tables local to a subquery (used by SQL_LIST). Considers
|
||||
views as leaves (unlike 'next_leaf' below). Created at parse time
|
||||
|
@ -1097,8 +1112,7 @@ typedef struct st_table_field_w_type
|
|||
|
||||
my_bool
|
||||
table_check_intact(TABLE *table, const uint table_f_count,
|
||||
const TABLE_FIELD_W_TYPE *table_def,
|
||||
time_t *last_create_time, int error_num);
|
||||
const TABLE_FIELD_W_TYPE *table_def);
|
||||
|
||||
static inline my_bitmap_map *tmp_use_all_columns(TABLE *table,
|
||||
MY_BITMAP *bitmap)
|
||||
|
|
Loading…
Reference in a new issue