Commit 4a0f5887 authored by unknown's avatar unknown

Merge cbell@bk-internal.mysql.com:/home/bk/mysql-5.1-new-rpl

into  mysql_cab_desk.:C:/source/c++/mysql-5.1-new-rpl


mysql-test/t/events.test:
  Auto merged
sql/event_queue.cc:
  Auto merged
sql/events.cc:
  Auto merged
sql/lex.h:
  Auto merged
sql/slave.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
BitKeeper/deleted/.del-init_db.sql~a77d572c39d5a1f8:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
BitKeeper/deleted/.del-mysql_create_system_tables.sh:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
mysql-test/r/events.result:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
mysql-test/r/events_grant.result:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
mysql-test/r/events_restart_phase1.result:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
mysql-test/r/system_mysql_db.result:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
mysql-test/t/events_restart_phase1.test:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
scripts/mysql_system_tables.sql:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
scripts/mysql_system_tables_fix.sql:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
sql/event_data_objects.cc:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
sql/event_data_objects.h:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
sql/event_db_repository.cc:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
sql/event_db_repository.h:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
sql/sql_udf.cc:
  WL#3629 : Replication of Invocation and Invoked Features
  
  Manual merge prior to pushing patches.
parents cbbb4034 7e43b1f5
##################################################################
# Author: Giuseppe, Chuck Bell #
# Date: 17-January-2007 #
# Purpose: To test that event effects are replicated #
# in both row based and statement based format #
##################################################################
--disable_warnings
DROP EVENT IF EXISTS test.justonce;
drop table if exists t1,t2;
--enable_warnings
# first, we need a table to record something from an event
eval CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`c` VARCHAR(50) NOT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=$engine_type DEFAULT CHARSET=utf8;
INSERT INTO t1 (c) VALUES ('manually');
# then, we create the event
CREATE EVENT test.justonce ON SCHEDULE AT NOW() + INTERVAL 2 SECOND DO INSERT INTO t1
(c) VALUES ('from justonce');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
# wait 3 seconds, so the event can trigger
--real_sleep 3
# check that table t1 contains something
--echo "in the master"
--enable_info
--replace_column 3 TIMESTAMP
SELECT * FROM t1;
--disable_info
sync_slave_with_master;
--echo "in the slave"
--enable_info
--replace_column 3 TIMESTAMP
SELECT * FROM t1;
--disable_info
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
# Create an event on the slave and check to see what the originator is.
--disable_warnings
DROP EVENT IF EXISTS test.slave_once;
--enable_warnings
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
--disable_warnings
DROP EVENT IF EXISTS test.slave_once;
--enable_warnings
connection master;
# BUG#20384 - disable events on slave
--disable_warnings
DROP EVENT IF EXISTS test.justonce;
--enable_warnings
CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND DO
INSERT INTO t1(c) VALUES ('from er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
sync_slave_with_master;
--echo "in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
connection master;
--echo "in the master"
ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND DO INSERT into t1(c) VALUES ('from alter er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
sync_slave_with_master;
--echo "in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
connection master;
--echo "in the master"
DROP EVENT test.er;
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
--disable_info
sync_slave_with_master;
--echo "in the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
--echo "in the master"
connection master;
DROP TABLE t1;
#####################################################################
# Author: Chuck Bell #
# Date: 2006-12-21 #
# Purpose: To test that UDFs are replicated in both row based and #
# statement based format. This tests work completed in WL#3629. #
# #
# This test is designed to exercise two of the three types of UDFs: #
# 1) UDFs via loadable libraries, and 2) UDFs with a SQL body. #
#####################################################################
--source include/have_udf.inc
#
# To run this tests the "sql/udf_example.c" need to be compiled into
# udf_example.so and LD_LIBRARY_PATH should be setup to point out where
# the library are.
#
connection master;
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Test 1) Test UDFs via loadable libraries
#
--echo "*** Test 1) Test UDFs via loadable libraries ***
--echo "Running on the master"
--enable_info
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
--error ER_CANT_FIND_DL_ENTRY
eval CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
SELECT * FROM mysql.func;
--disable_info
save_master_pos;
connection slave;
sync_with_master;
# Check to see that UDF CREATE statements were replicated
--echo "Running on the slave"
--enable_info
SELECT * FROM mysql.func;
--disable_info
connection master;
# Use the UDFs to do something
--echo "Running on the master"
--enable_info
eval CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=$engine_type;
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
SELECT * FROM t1 ORDER BY sum;
--disable_info
sync_slave_with_master;
# Check to see if data was replicated
--echo "Running on the slave"
--enable_info
SELECT * FROM t1 ORDER BY sum;
# Check to see that the functions are available for execution on the slave
SELECT myfunc_int(25);
SELECT myfunc_double(75.00);
--disable_info
connection master;
# Drop the functions
--echo "Running on the master"
--enable_info
DROP FUNCTION myfunc_double;
DROP FUNCTION myfunc_int;
SELECT * FROM mysql.func;
--disable_info
sync_slave_with_master;
# Check to see if the UDFs were dropped on the slave
--echo "Running on the slave"
--enable_info
SELECT * FROM mysql.func;
--disable_info
connection master;
# Cleanup
--echo "Running on the master"
--enable_info
DROP TABLE t1;
--disable_info
#
# Test 2) Test UDFs with SQL body
#
--echo "*** Test 2) Test UDFs with SQL body ***
--echo "Running on the master"
--enable_info
CREATE FUNCTION myfuncsql_int(i INT) RETURNS INTEGER DETERMINISTIC RETURN i;
CREATE FUNCTION myfuncsql_double(d DOUBLE) RETURNS INTEGER DETERMINISTIC RETURN d * 0.95;
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
--disable_info
sync_slave_with_master;
# Check to see that UDF CREATE statements were replicated
--echo "Running on the slave"
--enable_info
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
--disable_info
connection master;
# Use the UDFs to do something
--echo "Running on the master"
--enable_info
eval CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=$engine_type;
INSERT INTO t1 VALUES(myfuncsql_int(100), myfuncsql_double(50.00));
INSERT INTO t1 VALUES(myfuncsql_int(10), myfuncsql_double(5.00));
INSERT INTO t1 VALUES(myfuncsql_int(200), myfuncsql_double(25.00));
INSERT INTO t1 VALUES(myfuncsql_int(1), myfuncsql_double(500.00));
SELECT * FROM t1 ORDER BY sum;
--disable_info
sync_slave_with_master;
# Check to see if data was replicated
--echo "Running on the slave"
--enable_info
SELECT * FROM t1 ORDER BY sum;
--disable_info
connection master;
# Modify the UDFs to add a comment
--echo "Running on the master"
--enable_info
ALTER FUNCTION myfuncsql_int COMMENT "This was altered.";
ALTER FUNCTION myfuncsql_double COMMENT "This was altered.";
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
--disable_info
sync_slave_with_master;
# Check to see if data was replicated
--echo "Running on the slave"
--enable_info
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
# Check to see that the functions are available for execution on the slave
SELECT myfuncsql_int(25);
SELECT myfuncsql_double(75.00);
--disable_info
connection master;
# Drop the functions
--echo "Running on the master"
--enable_info
DROP FUNCTION myfuncsql_double;
DROP FUNCTION myfuncsql_int;
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
--disable_info
sync_slave_with_master;
# Check to see if the UDFs were dropped on the slave
--echo "Running on the slave"
--enable_info
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
--disable_info
connection master;
# Cleanup
--echo "Running on the master"
--enable_info
DROP TABLE t1;
--disable_info
...@@ -193,7 +193,7 @@ create event ...@@ -193,7 +193,7 @@ create event
SHOW CREATE EVENT ðóóò21; SHOW CREATE EVENT ðóóò21;
Event sql_mode time_zone Create Event Event sql_mode time_zone Create Event
ðóóò21 SYSTEM CREATE EVENT `ðóóò21` ON SCHEDULE EVERY '51 0:0:35' DAY_SECOND STARTS '#' ON COMPLETION NOT PRESERVE ENABLE COMMENT 'òîâà å 1251 êîìåíòàð' DO select 1 ðóóò21 SYSTEM CREATE EVENT `ðóóò21` ON SCHEDULE EVERY '51 0:0:35' DAY_SECOND STARTS '#' ON COMPLETION NOT PRESERVE ENABLE COMMENT 'òîâà å 1251 êîìåíòàð' DO select 1
insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND"); insert into mysql.event (db, name, body, definer, interval_value, interval_field, originator) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND", 1);
show create event root22; show create event root22;
ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND' ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
SHOW EVENTS; SHOW EVENTS;
...@@ -225,8 +225,8 @@ drop event ...@@ -225,8 +225,8 @@ drop event
set names latin1; set names latin1;
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing"; CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status 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 events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
ALTER TABLE mysql.event ADD dummy INT FIRST; ALTER TABLE mysql.event ADD dummy INT FIRST;
SHOW EVENTS; SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted
...@@ -235,8 +235,8 @@ SHOW EVENTS; ...@@ -235,8 +235,8 @@ SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted
ALTER TABLE mysql.event DROP dummy2; ALTER TABLE mysql.event DROP dummy2;
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status 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 events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
CREATE TABLE event_like LIKE mysql.event; CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event; INSERT INTO event_like SELECT * FROM mysql.event;
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
...@@ -258,10 +258,11 @@ event CREATE TABLE `event` ( ...@@ -258,10 +258,11 @@ event CREATE TABLE `event` (
`last_executed` datetime DEFAULT NULL, `last_executed` datetime DEFAULT NULL,
`starts` datetime DEFAULT NULL, `starts` datetime DEFAULT NULL,
`ends` datetime DEFAULT NULL, `ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED') NOT NULL DEFAULT 'ENABLED', `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP', `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 '', `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 '', `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', `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
PRIMARY KEY (`db`,`name`) PRIMARY KEY (`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
...@@ -270,8 +271,8 @@ ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error l ...@@ -270,8 +271,8 @@ ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error l
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
"This should work" "This should work"
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status 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 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 ''; ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
...@@ -286,8 +287,8 @@ CREATE TABLE mysql.event like event_like; ...@@ -286,8 +287,8 @@ CREATE TABLE mysql.event like event_like;
INSERT INTO mysql.event SELECT * FROM event_like; INSERT INTO mysql.event SELECT * FROM event_like;
DROP TABLE event_like; DROP TABLE event_like;
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status 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 events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
DROP EVENT intact_check; DROP EVENT intact_check;
create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5; 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; select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
...@@ -400,5 +401,5 @@ ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ...@@ -400,5 +401,5 @@ ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
SHOW EVENTS FROM ``; SHOW EVENTS FROM ``;
ERROR 42000: Incorrect database name '' ERROR 42000: Incorrect database name ''
SHOW EVENTS FROM `events\\test`; SHOW EVENTS FROM `events\\test`;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
drop database events_test; drop database events_test;
...@@ -2,8 +2,8 @@ CREATE DATABASE IF NOT EXISTS events_test; ...@@ -2,8 +2,8 @@ CREATE DATABASE IF NOT EXISTS events_test;
use events_test; use events_test;
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123; CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123;
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME; SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME;
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT
NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE NULL events_test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE
...@@ -29,8 +29,8 @@ ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_te ...@@ -29,8 +29,8 @@ ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_te
USE events_test; USE events_test;
"We should see one event"; "We should see one event";
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
SELECT CONCAT("Let's create some new events from the name of ", USER()); SELECT CONCAT("Let's create some new events from the name of ", USER());
CONCAT("Let's create some new events from the name of ", USER()) CONCAT("Let's create some new events from the name of ", USER())
Let's create some new events from the name of ev_test@localhost Let's create some new events from the name of ev_test@localhost
...@@ -40,18 +40,18 @@ CREATE EVENT two_event ON SCHEDULE EVERY 20 SECOND ON COMPLETION NOT PRESERVE CO ...@@ -40,18 +40,18 @@ CREATE EVENT two_event ON SCHEDULE EVERY 20 SECOND ON COMPLETION NOT PRESERVE CO
CREATE EVENT three_event ON SCHEDULE EVERY 20 SECOND ON COMPLETION PRESERVE COMMENT "three event" DO SELECT 123; CREATE EVENT three_event ON SCHEDULE EVERY 20 SECOND ON COMPLETION PRESERVE COMMENT "three event" DO SELECT 123;
"Now we should see 3 events:"; "Now we should see 3 events:";
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED events_test one_event root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1
events_test three_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED events_test three_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED 1
events_test two_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED events_test two_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED 1
"This should show us only 2 events:"; "This should show us only 2 events:";
SHOW EVENTS LIKE 't%event'; SHOW EVENTS LIKE 't%event';
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
events_test three_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED events_test three_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED 1
events_test two_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED events_test two_event ev_test@localhost SYSTEM RECURRING NULL 20 # # NULL ENABLED 1
"This should show us no events:"; "This should show us no events:";
SHOW EVENTS FROM test LIKE '%'; SHOW EVENTS FROM test LIKE '%';
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator
GRANT EVENT ON events_test2.* TO ev_test@localhost; GRANT EVENT ON events_test2.* TO ev_test@localhost;
USE events_test2; USE events_test2;
CREATE EVENT four_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42; CREATE EVENT four_event ON SCHEDULE EVERY 20 SECOND DO SELECT 42;
......
...@@ -7,6 +7,6 @@ create event abc2 on schedule every 1 second do insert into execution_log value( ...@@ -7,6 +7,6 @@ create event abc2 on schedule every 1 second do insert into execution_log value(
create event abc3 on schedule every 1 second do insert into execution_log value('abc3'); create event abc3 on schedule every 1 second do insert into execution_log value('abc3');
select name from execution_log; select name from execution_log;
name 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','SYSTEM'); 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','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');
"Now we restart the server" "Now we restart the server"
set global event_scheduler=1;
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set binlog_format=row;
DROP EVENT IF EXISTS test.justonce;
drop table if exists t1,t2;
CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`c` VARCHAR(50) NOT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 (c) VALUES ('manually');
CREATE EVENT test.justonce ON SCHEDULE AT NOW() + INTERVAL 2 SECOND DO INSERT INTO t1
(c) VALUES ('from justonce');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce ENABLED 1
"in the master"
SELECT * FROM t1;
id c ts
1 manually TIMESTAMP
2 from justonce TIMESTAMP
affected rows: 2
"in the slave"
SELECT * FROM t1;
id c ts
1 manually TIMESTAMP
2 from justonce TIMESTAMP
affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
db name status originator
test slave_once ENABLED 2
DROP EVENT IF EXISTS test.slave_once;
DROP EVENT IF EXISTS test.justonce;
CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND DO
INSERT INTO t1(c) VALUES ('from er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT INTO t1(c) VALUES ('from er')
"in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT INTO t1(c) VALUES ('from er')
"in the master"
ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND DO INSERT into t1(c) VALUES ('from alter er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT into t1(c) VALUES ('from alter er')
"in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT into t1(c) VALUES ('from alter er')
"in the master"
DROP EVENT test.er;
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"in the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"in the master"
DROP TABLE t1;
set binlog_format=statement;
DROP EVENT IF EXISTS test.justonce;
drop table if exists t1,t2;
CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`c` VARCHAR(50) NOT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 (c) VALUES ('manually');
CREATE EVENT test.justonce ON SCHEDULE AT NOW() + INTERVAL 2 SECOND DO INSERT INTO t1
(c) VALUES ('from justonce');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce ENABLED 1
"in the master"
SELECT * FROM t1;
id c ts
1 manually TIMESTAMP
2 from justonce TIMESTAMP
affected rows: 2
"in the slave"
SELECT * FROM t1;
id c ts
1 manually TIMESTAMP
2 from justonce TIMESTAMP
affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once');
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
db name status originator
test slave_once ENABLED 2
DROP EVENT IF EXISTS test.slave_once;
DROP EVENT IF EXISTS test.justonce;
CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND DO
INSERT INTO t1(c) VALUES ('from er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT INTO t1(c) VALUES ('from er')
"in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT INTO t1(c) VALUES ('from er')
"in the master"
ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND DO INSERT into t1(c) VALUES ('from alter er');
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT into t1(c) VALUES ('from alter er')
"in the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT into t1(c) VALUES ('from alter er')
"in the master"
DROP EVENT test.er;
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"in the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"in the master"
DROP TABLE t1;
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set binlog_format=row;
drop table if exists t1;
"*** Test 1) Test UDFs via loadable libraries ***
"Running on the master"
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Can't find symbol 'myfunc_nonexist' in library
SELECT * FROM mysql.func;
name ret dl type
myfunc_double 1 udf_example.dll function
myfunc_int 2 udf_example.dll function
affected rows: 2
"Running on the slave"
SELECT * FROM mysql.func;
name ret dl type
myfunc_double 1 udf_example.dll function
myfunc_int 2 udf_example.dll function
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
SELECT myfunc_int(25);
myfunc_int(25)
25
affected rows: 1
SELECT myfunc_double(75.00);
myfunc_double(75.00)
50.00
affected rows: 1
"Running on the master"
DROP FUNCTION myfunc_double;
affected rows: 0
DROP FUNCTION myfunc_int;
affected rows: 0
SELECT * FROM mysql.func;
name ret dl type
affected rows: 0
"Running on the slave"
SELECT * FROM mysql.func;
name ret dl type
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
"*** Test 2) Test UDFs with SQL body ***
"Running on the master"
CREATE FUNCTION myfuncsql_int(i INT) RETURNS INTEGER DETERMINISTIC RETURN i;
affected rows: 0
CREATE FUNCTION myfuncsql_double(d DOUBLE) RETURNS INTEGER DETERMINISTIC RETURN d * 0.95;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfuncsql_int(100), myfuncsql_double(50.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(10), myfuncsql_double(5.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(200), myfuncsql_double(25.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(1), myfuncsql_double(500.00));
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 475
10 5
100 47
200 24
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 475
10 5
100 47
200 24
affected rows: 4
"Running on the master"
ALTER FUNCTION myfuncsql_int COMMENT "This was altered.";
affected rows: 0
ALTER FUNCTION myfuncsql_double COMMENT "This was altered.";
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
SELECT myfuncsql_int(25);
myfuncsql_int(25)
25
affected rows: 1
SELECT myfuncsql_double(75.00);
myfuncsql_double(75.00)
71
affected rows: 1
"Running on the master"
DROP FUNCTION myfuncsql_double;
affected rows: 0
DROP FUNCTION myfuncsql_int;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
affected rows: 0
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
set binlog_format=statement;
drop table if exists t1;
"*** Test 1) Test UDFs via loadable libraries ***
"Running on the master"
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Can't find symbol 'myfunc_nonexist' in library
SELECT * FROM mysql.func;
name ret dl type
myfunc_int 2 udf_example.dll function
myfunc_double 1 udf_example.dll function
affected rows: 2
"Running on the slave"
SELECT * FROM mysql.func;
name ret dl type
myfunc_int 2 udf_example.dll function
myfunc_double 1 udf_example.dll function
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
SELECT myfunc_int(25);
myfunc_int(25)
25
affected rows: 1
SELECT myfunc_double(75.00);
myfunc_double(75.00)
50.00
affected rows: 1
"Running on the master"
DROP FUNCTION myfunc_double;
affected rows: 0
DROP FUNCTION myfunc_int;
affected rows: 0
SELECT * FROM mysql.func;
name ret dl type
affected rows: 0
"Running on the slave"
SELECT * FROM mysql.func;
name ret dl type
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
"*** Test 2) Test UDFs with SQL body ***
"Running on the master"
CREATE FUNCTION myfuncsql_int(i INT) RETURNS INTEGER DETERMINISTIC RETURN i;
affected rows: 0
CREATE FUNCTION myfuncsql_double(d DOUBLE) RETURNS INTEGER DETERMINISTIC RETURN d * 0.95;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfuncsql_int(100), myfuncsql_double(50.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(10), myfuncsql_double(5.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(200), myfuncsql_double(25.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(1), myfuncsql_double(500.00));
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 475
10 5
100 47
200 24
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 475
10 5
100 47
200 24
affected rows: 4
"Running on the master"
ALTER FUNCTION myfuncsql_int COMMENT "This was altered.";
affected rows: 0
ALTER FUNCTION myfuncsql_double COMMENT "This was altered.";
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 0.95 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
SELECT myfuncsql_int(25);
myfuncsql_int(25)
25
affected rows: 1
SELECT myfuncsql_double(75.00);
myfuncsql_double(75.00)
71
affected rows: 1
"Running on the master"
DROP FUNCTION myfuncsql_double;
affected rows: 0
DROP FUNCTION myfuncsql_int;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
affected rows: 0
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%';
db name type param_list body comment
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
...@@ -220,10 +220,11 @@ event CREATE TABLE `event` ( ...@@ -220,10 +220,11 @@ event CREATE TABLE `event` (
`last_executed` datetime DEFAULT NULL, `last_executed` datetime DEFAULT NULL,
`starts` datetime DEFAULT NULL, `starts` datetime DEFAULT NULL,
`ends` datetime DEFAULT NULL, `ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED') NOT NULL DEFAULT 'ENABLED', `status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP', `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 '', `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 '', `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', `time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
PRIMARY KEY (`db`,`name`) PRIMARY KEY (`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
......
...@@ -179,7 +179,7 @@ set names cp1251; ...@@ -179,7 +179,7 @@ set names cp1251;
create event 21 on schedule every '50:23:59:95' day_second COMMENT ' 1251 ' do select 1; create event 21 on schedule every '50:23:59:95' day_second COMMENT ' 1251 ' do select 1;
--replace_regex /STARTS '[^']+'/STARTS '#'/ --replace_regex /STARTS '[^']+'/STARTS '#'/
SHOW CREATE EVENT 21; SHOW CREATE EVENT 21;
insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND"); insert into mysql.event (db, name, body, definer, interval_value, interval_field, originator) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND", 1);
--error ER_NOT_SUPPORTED_YET --error ER_NOT_SUPPORTED_YET
show create event root22; show create event root22;
--error ER_NOT_SUPPORTED_YET --error ER_NOT_SUPPORTED_YET
......
...@@ -14,6 +14,6 @@ create event abc3 on schedule every 1 second do insert into execution_log value( ...@@ -14,6 +14,6 @@ create event abc3 on schedule every 1 second do insert into execution_log value(
--sleep 1.5 --sleep 1.5
select name from execution_log; 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','SYSTEM'); 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','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');
--echo "Now we restart the server" --echo "Now we restart the server"
##################################################################
# Author: Giuseppe #
# Date: 2006-12-20 #
# Purpose: To test that event effects are replicated #
# in both row based and statement based format #
##################################################################
set global event_scheduler=1;
--source include/not_embedded.inc
--source include/master-slave.inc
let $engine_type= MyISAM;
set binlog_format=row;
# Embedded server doesn't support binlogging
--source include/rpl_events.inc
set binlog_format=statement;
# Embedded server doesn't support binlogging
--source include/rpl_events.inc
###################################################################
# Author: Chuck Bell #
# Date: 2006-12-21 #
# Purpose: To test that UDFs are replicated in both row based and #
# statement based format. This tests work completed in WL#3629. #
###################################################################
--source include/not_embedded.inc
--source include/master-slave.inc
let $engine_type= MyISAM;
set binlog_format=row;
# Embedded server doesn't support binlogging
--source include/rpl_udf.inc
set binlog_format=statement;
# Embedded server doesn't support binlogging
--source include/rpl_udf.inc
...@@ -70,7 +70,7 @@ CALL create_slow_log_table(); ...@@ -70,7 +70,7 @@ CALL create_slow_log_table();
DROP PROCEDURE create_slow_log_table; DROP PROCEDURE create_slow_log_table;
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, 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, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events'; CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, 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, modified TIMESTAMP NOT NULL, 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') DEFAULT '' NOT NULL, 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';
CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM; CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
......
...@@ -477,6 +477,8 @@ ALTER TABLE event ADD sql_mode ...@@ -477,6 +477,8 @@ ALTER TABLE event ADD sql_mode
'HIGH_NOT_PRECEDENCE' 'HIGH_NOT_PRECEDENCE'
) DEFAULT '' NOT NULL AFTER on_completion; ) DEFAULT '' NOT NULL AFTER on_completion;
ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default ''; ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default '';
ALTER TABLE event ADD COLUMN originator INT(10) NOT NULL;
ALTER TABLE event MODIFY COLUMN status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED';
ALTER TABLE event ADD COLUMN time_zone char(64) CHARACTER SET latin1 ALTER TABLE event ADD COLUMN time_zone char(64) CHARACTER SET latin1
NOT NULL DEFAULT 'SYSTEM' AFTER comment; NOT NULL DEFAULT 'SYSTEM' AFTER comment;
......
...@@ -101,7 +101,8 @@ Event_parse_data::new_instance(THD *thd) ...@@ -101,7 +101,8 @@ Event_parse_data::new_instance(THD *thd)
*/ */
Event_parse_data::Event_parse_data() Event_parse_data::Event_parse_data()
:on_completion(ON_COMPLETION_DROP), status(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), item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE), starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
item_expression(NULL), expression(0) item_expression(NULL), expression(0)
...@@ -588,9 +589,9 @@ Event_parse_data::check_parse_data(THD *thd) ...@@ -588,9 +589,9 @@ Event_parse_data::check_parse_data(THD *thd)
init_name(thd, identifier); init_name(thd, identifier);
init_definer(thd); init_definer(thd);
ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) || ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) ||
init_ends(thd); init_ends(thd);
check_originator_id(thd);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -637,6 +638,31 @@ Event_parse_data::init_definer(THD *thd) ...@@ -637,6 +638,31 @@ 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.
SYNOPSIS
Event_parse_data::check_originator_id()
*/
void Event_parse_data::check_originator_id(THD *thd)
{
/* Disable replicated events on slave. */
if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) ||
(thd->system_thread == SYSTEM_THREAD_SLAVE_IO))
{
DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED."));
if ((status == Event_basic::ENABLED) ||
(status == Event_basic::DISABLED))
status = Event_basic::SLAVESIDE_DISABLED;
originator = thd->server_id;
}
else
originator = server_id;
}
/* /*
Constructor Constructor
...@@ -995,8 +1021,23 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table) ...@@ -995,8 +1021,23 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
goto error; goto error;
DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", name.str, ptr)); DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", name.str, ptr));
status= (ptr[0]=='E'? Event_queue_element::ENABLED:
Event_queue_element::DISABLED); /* Set event status (ENABLED | SLAVESIDE_DISABLED | DISABLED) */
switch (ptr[0])
{
case 'E' :
status = Event_queue_element::ENABLED;
break;
case 'S' :
status = Event_queue_element::SLAVESIDE_DISABLED;
break;
case 'D' :
status = Event_queue_element::DISABLED;
break;
}
if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS)
goto error;
originator = table->field[ET_FIELD_ORIGINATOR]->val_int();
/* ToDo : Andrey . Find a way not to allocate ptr on event_mem_root */ /* ToDo : Andrey . Find a way not to allocate ptr on event_mem_root */
if ((ptr= get_field(&mem_root, if ((ptr= get_field(&mem_root,
...@@ -1343,7 +1384,7 @@ Event_queue_element::compute_next_execution_time() ...@@ -1343,7 +1384,7 @@ Event_queue_element::compute_next_execution_time()
(long) starts, (long) ends, (long) last_executed, (long) starts, (long) ends, (long) last_executed,
(long) this)); (long) this));
if (status == Event_queue_element::DISABLED) if (status != Event_queue_element::ENABLED)
{ {
DBUG_PRINT("compute_next_execution_time", DBUG_PRINT("compute_next_execution_time",
("Event %s is DISABLED", name.str)); ("Event %s is DISABLED", name.str));
...@@ -1641,6 +1682,13 @@ Event_queue_element::update_timing_fields(THD *thd) ...@@ -1641,6 +1682,13 @@ Event_queue_element::update_timing_fields(THD *thd)
status_changed= FALSE; 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]))) if ((table->file->ha_update_row(table->record[1], table->record[0])))
ret= TRUE; ret= TRUE;
...@@ -1731,6 +1779,8 @@ Event_timed::get_create_event(THD *thd, String *buf) ...@@ -1731,6 +1779,8 @@ Event_timed::get_create_event(THD *thd, String *buf)
if (status == Event_timed::ENABLED) if (status == Event_timed::ENABLED)
buf->append(STRING_WITH_LEN("ENABLE")); buf->append(STRING_WITH_LEN("ENABLE"));
else if (status == Event_timed::SLAVESIDE_DISABLED)
buf->append(STRING_WITH_LEN("SLAVESIDE_DISABLE"));
else else
buf->append(STRING_WITH_LEN("DISABLE")); buf->append(STRING_WITH_LEN("DISABLE"));
......
...@@ -22,11 +22,9 @@ ...@@ -22,11 +22,9 @@
#define EVEX_BAD_PARAMS -5 #define EVEX_BAD_PARAMS -5
#define EVEX_MICROSECOND_UNSUP -6 #define EVEX_MICROSECOND_UNSUP -6
class sp_head; class sp_head;
class Sql_alloc; class Sql_alloc;
class Event_queue_element_for_exec class Event_queue_element_for_exec
{ {
public: public:
...@@ -54,6 +52,24 @@ protected: ...@@ -54,6 +52,24 @@ protected:
MEM_ROOT mem_root; MEM_ROOT mem_root;
public: public:
/*
ENABLED = feature can function normally (is turned on)
SLAVESIDE_DISABLED = feature is turned off on slave
DISABLED = feature is turned off
*/
enum enum_status
{
ENABLED = 1,
DISABLED,
SLAVESIDE_DISABLED
};
enum enum_on_completion
{
ON_COMPLETION_DROP = 1,
ON_COMPLETION_PRESERVE
};
LEX_STRING dbname; LEX_STRING dbname;
LEX_STRING name; LEX_STRING name;
LEX_STRING definer;// combination of user and host LEX_STRING definer;// combination of user and host
...@@ -83,20 +99,9 @@ protected: ...@@ -83,20 +99,9 @@ protected:
bool last_executed_changed; bool last_executed_changed;
public: public:
enum enum_status int on_completion;
{ int status;
ENABLED = 1, longlong originator;
DISABLED
};
enum enum_on_completion
{
ON_COMPLETION_DROP = 1,
ON_COMPLETION_PRESERVE
};
enum enum_on_completion on_completion;
enum enum_status status;
my_time_t last_executed; my_time_t last_executed;
my_time_t execute_at; my_time_t execute_at;
...@@ -216,19 +221,10 @@ private: ...@@ -216,19 +221,10 @@ private:
class Event_parse_data : public Sql_alloc class Event_parse_data : public Sql_alloc
{ {
public: public:
enum enum_status
{
ENABLED = 1,
DISABLED
};
enum enum_on_completion int on_completion;
{ int status;
ON_COMPLETION_DROP = 1, longlong originator;
ON_COMPLETION_PRESERVE
};
enum enum_on_completion on_completion;
enum enum_status status;
/* /*
do_not_create will be set if STARTS time is in the past and do_not_create will be set if STARTS time is in the past and
on_completion == ON_COMPLETION_DROP. on_completion == ON_COMPLETION_DROP.
...@@ -298,6 +294,7 @@ private: ...@@ -298,6 +294,7 @@ private:
check_if_in_the_past(THD *thd, my_time_t ltime_utc); check_if_in_the_past(THD *thd, my_time_t ltime_utc);
Event_parse_data(const Event_parse_data &); /* Prevent use of these */ Event_parse_data(const Event_parse_data &); /* Prevent use of these */
void Event_parse_data::check_originator_id(THD *thd);
void operator=(Event_parse_data &); void operator=(Event_parse_data &);
}; };
......
...@@ -94,7 +94,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = ...@@ -94,7 +94,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
}, },
{ {
{ C_STRING_WITH_LEN("status") }, { C_STRING_WITH_LEN("status") },
{ C_STRING_WITH_LEN("enum('ENABLED','DISABLED')") }, { C_STRING_WITH_LEN("enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')") },
{NULL, 0} {NULL, 0}
}, },
{ {
...@@ -119,6 +119,11 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = ...@@ -119,6 +119,11 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
{ C_STRING_WITH_LEN("char(64)") }, { C_STRING_WITH_LEN("char(64)") },
{ C_STRING_WITH_LEN("utf8") } { C_STRING_WITH_LEN("utf8") }
}, },
{
{ C_STRING_WITH_LEN("originator") },
{ C_STRING_WITH_LEN("int(10)") },
{NULL, 0}
},
{ {
{ C_STRING_WITH_LEN("time_zone") }, { C_STRING_WITH_LEN("time_zone") },
{ C_STRING_WITH_LEN("char(64)") }, { C_STRING_WITH_LEN("char(64)") },
...@@ -175,6 +180,9 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, ...@@ -175,6 +180,9 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE); fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
/* /*
Change the SQL_MODE only if body was present in an ALTER EVENT and of course Change the SQL_MODE only if body was present in an ALTER EVENT and of course
always during CREATE EVENT. always during CREATE EVENT.
...@@ -564,7 +572,6 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -564,7 +572,6 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
goto err; goto err;
} }
DBUG_PRINT("info", ("name: %.*s", parse_data->name.length, DBUG_PRINT("info", ("name: %.*s", parse_data->name.length,
parse_data->name.str)); parse_data->name.str));
...@@ -632,6 +639,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -632,6 +639,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
if ((ret= mysql_event_fill_row(thd, table, parse_data, FALSE))) if ((ret= mysql_event_fill_row(thd, table, parse_data, FALSE)))
goto err; goto err;
table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE);
/* Close active transaction only if We are going to modify disk */ /* Close active transaction only if We are going to modify disk */
if (end_active_trans(thd)) if (end_active_trans(thd))
goto err; goto err;
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
enum enum_events_table_field enum enum_events_table_field
{ {
ET_FIELD_DB = 0, ET_FIELD_DB = 0,
ET_FIELD_NAME, ET_FIELD_NAME,
ET_FIELD_BODY, ET_FIELD_BODY,
ET_FIELD_DEFINER, ET_FIELD_DEFINER,
...@@ -35,6 +35,7 @@ enum enum_events_table_field ...@@ -35,6 +35,7 @@ enum enum_events_table_field
ET_FIELD_ON_COMPLETION, ET_FIELD_ON_COMPLETION,
ET_FIELD_SQL_MODE, ET_FIELD_SQL_MODE,
ET_FIELD_COMMENT, ET_FIELD_COMMENT,
ET_FIELD_ORIGINATOR,
ET_FIELD_TIME_ZONE, ET_FIELD_TIME_ZONE,
ET_FIELD_COUNT /* a cool trick to count the number of fields :) */ ET_FIELD_COUNT /* a cool trick to count the number of fields :) */
}; };
......
...@@ -199,7 +199,8 @@ Event_queue::create_event(THD *thd, Event_queue_element *new_element) ...@@ -199,7 +199,8 @@ Event_queue::create_event(THD *thd, Event_queue_element *new_element)
DBUG_PRINT("enter", ("thd: 0x%lx et=%s.%s", (long) thd, DBUG_PRINT("enter", ("thd: 0x%lx et=%s.%s", (long) thd,
new_element->dbname.str, new_element->name.str)); new_element->dbname.str, new_element->name.str));
if (new_element->status == Event_queue_element::DISABLED) if ((new_element->status == Event_queue_element::DISABLED)
|| (new_element->status == Event_queue_element::SLAVESIDE_DISABLED))
delete new_element; delete new_element;
else else
{ {
...@@ -235,7 +236,8 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name, ...@@ -235,7 +236,8 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
DBUG_ENTER("Event_queue::update_event"); DBUG_ENTER("Event_queue::update_event");
DBUG_PRINT("enter", ("thd: 0x%lx et=[%s.%s]", (long) thd, dbname.str, name.str)); DBUG_PRINT("enter", ("thd: 0x%lx et=[%s.%s]", (long) thd, dbname.str, name.str));
if (new_element->status == Event_queue_element::DISABLED) if ((new_element->status == Event_queue_element::DISABLED) ||
(new_element->status == Event_queue_element::SLAVESIDE_DISABLED))
{ {
DBUG_PRINT("info", ("The event is disabled.")); DBUG_PRINT("info", ("The event is disabled."));
/* /*
......
...@@ -324,7 +324,15 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) ...@@ -324,7 +324,15 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/*
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE EVENT command.
*/
if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */ /* On error conditions my_error() is called so no need to handle here */
if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists)) && if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists)) &&
!parse_data->do_not_create) !parse_data->do_not_create)
...@@ -340,8 +348,16 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) ...@@ -340,8 +348,16 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists)
DBUG_ASSERT(ret == OP_LOAD_ERROR); DBUG_ASSERT(ret == OP_LOAD_ERROR);
delete new_element; delete new_element;
} }
else else /* Binlog the create event. */
{
event_queue->create_event(thd, new_element); event_queue->create_event(thd, new_element);
if (mysql_bin_log.is_open())
{
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
}
}
} }
pthread_mutex_unlock(&LOCK_event_metadata); pthread_mutex_unlock(&LOCK_event_metadata);
...@@ -383,7 +399,15 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to) ...@@ -383,7 +399,15 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/*
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for UPDATE EVENT command.
*/
if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */ /* On error conditions my_error() is called so no need to handle here */
if (!(ret= db_repository->update_event(thd, parse_data, new_dbname, new_name))) if (!(ret= db_repository->update_event(thd, parse_data, new_dbname, new_name)))
{ {
...@@ -398,9 +422,17 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to) ...@@ -398,9 +422,17 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to)
DBUG_ASSERT(ret == OP_LOAD_ERROR); DBUG_ASSERT(ret == OP_LOAD_ERROR);
delete new_element; delete new_element;
} }
else else /* Binlog the alter event. */
{
event_queue->update_event(thd, parse_data->dbname, parse_data->name, event_queue->update_event(thd, parse_data->dbname, parse_data->name,
new_element); new_element);
if (mysql_bin_log.is_open())
{
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
}
}
} }
pthread_mutex_unlock(&LOCK_event_metadata); pthread_mutex_unlock(&LOCK_event_metadata);
...@@ -435,10 +467,26 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ...@@ -435,10 +467,26 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/*
Turn off row binlogging of this statement and use statement-based so
that all supporting tables are updated for DROP EVENT command.
*/
if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */ /* On error conditions my_error() is called so no need to handle here */
if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists))) if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists)))
{
event_queue->drop_event(thd, dbname, name); event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */
if (mysql_bin_log.is_open())
{
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
}
}
pthread_mutex_unlock(&LOCK_event_metadata); pthread_mutex_unlock(&LOCK_event_metadata);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -467,6 +467,7 @@ static SYMBOL symbols[] = { ...@@ -467,6 +467,7 @@ static SYMBOL symbols[] = {
{ "SIGNED", SYM(SIGNED_SYM)}, { "SIGNED", SYM(SIGNED_SYM)},
{ "SIMPLE", SYM(SIMPLE_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)},
{ "SLAVE", SYM(SLAVE)}, { "SLAVE", SYM(SLAVE)},
{ "SLAVESIDE_DISABLE", SYM(SLAVESIDE_DISABLE_SYM)},
{ "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)},
{ "SMALLINT", SYM(SMALLINT)}, { "SMALLINT", SYM(SMALLINT)},
{ "SOCKET", SYM(SOCKET_SYM)}, { "SOCKET", SYM(SOCKET_SYM)},
......
...@@ -2423,10 +2423,25 @@ Slave SQL thread aborted. Can't execute init_slave query"); ...@@ -2423,10 +2423,25 @@ Slave SQL thread aborted. Can't execute init_slave query");
/* Print any warnings issued */ /* Print any warnings issued */
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list); List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
MYSQL_ERROR *err; MYSQL_ERROR *err;
/*
Added controlled slave thread cancel for replication
of user-defined variables.
*/
bool udf_error = false;
while ((err= it++)) while ((err= it++))
{
if (err->code == ER_CANT_OPEN_LIBRARY)
udf_error = true;
sql_print_warning("Slave: %s Error_code: %d",err->msg, err->code); sql_print_warning("Slave: %s Error_code: %d",err->msg, err->code);
}
sql_print_error("\ if (udf_error)
sql_print_error("Error loading user-defined library, slave SQL "
"thread aborted. Install the missing library, and restart the "
"slave SQL thread with \"SLAVE START\". We stopped at log '%s' "
"position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos,
llbuff));
else
sql_print_error("\
Error running query, slave SQL thread aborted. Fix the problem, and restart \ Error running query, slave SQL thread aborted. Fix the problem, and restart \
the slave SQL thread with \"SLAVE START\". We stopped at log \ the slave SQL thread with \"SLAVE START\". We stopped at log \
'%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff)); '%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff));
......
...@@ -3923,7 +3923,6 @@ create_sp_error: ...@@ -3923,7 +3923,6 @@ create_sp_error:
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0)) if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
goto error; goto error;
/* Does NOT write to binlog */
if (!(res = mysql_drop_function(thd, &lex->spname->m_name))) if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
{ {
send_ok(thd); send_ok(thd);
......
...@@ -53,7 +53,8 @@ enum enum_i_s_events_fields ...@@ -53,7 +53,8 @@ enum enum_i_s_events_fields
ISE_CREATED, ISE_CREATED,
ISE_LAST_ALTERED, ISE_LAST_ALTERED,
ISE_LAST_EXECUTED, ISE_LAST_EXECUTED,
ISE_EVENT_COMMENT ISE_EVENT_COMMENT,
ISE_ORIGINATOR
}; };
...@@ -4403,10 +4404,23 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -4403,10 +4404,23 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
} }
/* status */ /* status */
if (et.status == Event_timed::ENABLED)
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs); switch (et.status)
else {
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs); case Event_timed::ENABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs);
break;
case Event_timed::SLAVESIDE_DISABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("SLAVESIDE_DISABLED"),
scs);
break;
case Event_timed::DISABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs);
break;
default:
DBUG_ASSERT(0);
}
sch_table->field[ISE_ORIGINATOR]->store(et.originator, TRUE);
/* on_completion */ /* on_completion */
if (et.on_completion == Event_timed::ON_COMPLETION_DROP) if (et.on_completion == Event_timed::ON_COMPLETION_DROP)
...@@ -4945,9 +4959,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) ...@@ -4945,9 +4959,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
TABLE *table; TABLE *table;
DBUG_ENTER("mysql_schema_table"); DBUG_ENTER("mysql_schema_table");
if (!(table= table_list->schema_table->create_table(thd, table_list))) if (!(table= table_list->schema_table->create_table(thd, table_list)))
{
DBUG_RETURN(1); DBUG_RETURN(1);
}
table->s->tmp_table= SYSTEM_TMP_TABLE; table->s->tmp_table= SYSTEM_TMP_TABLE;
table->grant.privilege= SELECT_ACL; table->grant.privilege= SELECT_ACL;
/* /*
...@@ -5445,13 +5457,14 @@ ST_FIELD_INFO events_fields_info[]= ...@@ -5445,13 +5457,14 @@ ST_FIELD_INFO events_fields_info[]=
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0}, {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
{"STARTS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Starts"}, {"STARTS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Starts"},
{"ENDS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Ends"}, {"ENDS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Ends"},
{"STATUS", 8, MYSQL_TYPE_STRING, 0, 0, "Status"}, {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status"},
{"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0}, {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0},
{"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0}, {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
{"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0}, {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
{"LAST_EXECUTED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0}, {"LAST_EXECUTED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
{"EVENT_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"EVENT_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0} {"ORIGINATOR", 10, MYSQL_TYPE_LONG, 0, 0, "Originator"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
}; };
......
...@@ -403,6 +403,13 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -403,6 +403,13 @@ int mysql_create_function(THD *thd,udf_func *udf)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/*
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE FUNCTION command.
*/
if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf); rw_wrlock(&THR_LOCK_udf);
if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length))) if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length)))
{ {
...@@ -466,6 +473,15 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -466,6 +473,15 @@ int mysql_create_function(THD *thd,udf_func *udf)
goto err; goto err;
} }
rw_unlock(&THR_LOCK_udf); rw_unlock(&THR_LOCK_udf);
/* Binlog the create function. */
if (mysql_bin_log.is_open())
{
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
}
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
...@@ -484,11 +500,20 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) ...@@ -484,11 +500,20 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
char *exact_name_str; char *exact_name_str;
uint exact_name_len; uint exact_name_len;
DBUG_ENTER("mysql_drop_function"); DBUG_ENTER("mysql_drop_function");
if (!initialized) if (!initialized)
{ {
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/*
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for DROP FUNCTION command.
*/
if (thd->current_stmt_binlog_row_based)
thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf); rw_wrlock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str, if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str,
(uint) udf_name->length))) (uint) udf_name->length)))
...@@ -524,6 +549,15 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) ...@@ -524,6 +549,15 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
close_thread_tables(thd); close_thread_tables(thd);
rw_unlock(&THR_LOCK_udf); rw_unlock(&THR_LOCK_udf);
/* Binlog the drop function. */
if (mysql_bin_log.is_open())
{
thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
thd->query, thd->query_length, FALSE, FALSE);
}
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
rw_unlock(&THR_LOCK_udf); rw_unlock(&THR_LOCK_udf);
......
...@@ -948,6 +948,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -948,6 +948,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SIGNED_SYM %token SIGNED_SYM
%token SIMPLE_SYM /* SQL-2003-N */ %token SIMPLE_SYM /* SQL-2003-N */
%token SLAVE %token SLAVE
%token SLAVESIDE_DISABLE_SYM
%token SMALLINT /* SQL-2003-R */ %token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM %token SNAPSHOT_SYM
%token SOCKET_SYM %token SOCKET_SYM
...@@ -1770,12 +1771,17 @@ ev_schedule_time: EVERY_SYM expr interval ...@@ -1770,12 +1771,17 @@ ev_schedule_time: EVERY_SYM expr interval
opt_ev_status: /* empty */ { $$= 0; } opt_ev_status: /* empty */ { $$= 0; }
| ENABLE_SYM | ENABLE_SYM
{ {
Lex->event_parse_data->status= Event_parse_data::ENABLED; Lex->event_parse_data->status= Event_basic::ENABLED;
$$= 1;
}
| SLAVESIDE_DISABLE_SYM
{
Lex->event_parse_data->status= Event_basic::SLAVESIDE_DISABLED;
$$= 1; $$= 1;
} }
| DISABLE_SYM | DISABLE_SYM
{ {
Lex->event_parse_data->status= Event_parse_data::DISABLED; Lex->event_parse_data->status= Event_basic::DISABLED;
$$= 1; $$= 1;
} }
; ;
...@@ -1805,13 +1811,13 @@ ev_on_completion: ...@@ -1805,13 +1811,13 @@ ev_on_completion:
ON COMPLETION_SYM PRESERVE_SYM ON COMPLETION_SYM PRESERVE_SYM
{ {
Lex->event_parse_data->on_completion= Lex->event_parse_data->on_completion=
Event_parse_data::ON_COMPLETION_PRESERVE; Event_basic::ON_COMPLETION_PRESERVE;
$$= 1; $$= 1;
} }
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{ {
Lex->event_parse_data->on_completion= Lex->event_parse_data->on_completion=
Event_parse_data::ON_COMPLETION_DROP; Event_basic::ON_COMPLETION_DROP;
$$= 1; $$= 1;
} }
; ;
...@@ -9998,6 +10004,7 @@ keyword_sp: ...@@ -9998,6 +10004,7 @@ keyword_sp:
| SIMPLE_SYM {} | SIMPLE_SYM {}
| SHARE_SYM {} | SHARE_SYM {}
| SHUTDOWN {} | SHUTDOWN {}
| SLAVESIDE_DISABLE_SYM {}
| SNAPSHOT_SYM {} | SNAPSHOT_SYM {}
| SOUNDS_SYM {} | SOUNDS_SYM {}
| SQL_CACHE_SYM {} | SQL_CACHE_SYM {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment