summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shulga <Dmitry.Shulga@oracle.com>2011-06-10 00:03:17 +0700
committerDmitry Shulga <Dmitry.Shulga@oracle.com>2011-06-10 00:03:17 +0700
commit1cc304e33eee2c3fdf9ec46ab4ad481dd30ea274 (patch)
tree8682dccf8a8135c43ef8740a59d2f4f9ad1bfceb
parent6d20340c724c9ede8f7f135e5d853180163d5961 (diff)
downloadmariadb-git-1cc304e33eee2c3fdf9ec46ab4ad481dd30ea274.tar.gz
Fixed bug#11764334 (formerly bug#57156): ALTER EVENT CHANGES
THE EVENT STATUS. Any ALTER EVENT statement on a disabled event enabled it back (unless this ALTER EVENT statement explicitly disabled the event). The problem was that during processing of an ALTER EVENT statement value of status field was overwritten unconditionally even if new value was not specified explicitly. As a consequence this field was set to default value for status which corresponds to ENABLE. The solution is to check if status field was explicitly specified in ALTER EVENT statement before assigning new value to status field.
-rw-r--r--mysql-test/r/events_bugs.result16
-rw-r--r--mysql-test/t/events_bugs.test15
-rw-r--r--sql/event_db_repository.cc13
-rw-r--r--sql/event_parse_data.cc11
-rw-r--r--sql/event_parse_data.h1
-rw-r--r--sql/sql_yacc.yy3
6 files changed, 50 insertions, 9 deletions
diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result
index 740f94fb061..73cb4d58cdc 100644
--- a/mysql-test/r/events_bugs.result
+++ b/mysql-test/r/events_bugs.result
@@ -419,7 +419,7 @@ 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 character_set_client collation_connection Database Collation
-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 latin1 latin1_swedish_ci latin1_swedish_ci
+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 latin1 latin1_swedish_ci latin1_swedish_ci
DROP EVENT e1;
SET TIME_ZONE='+05:00';
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY STARTS '2006-01-01 00:00:00' DO
@@ -796,6 +796,20 @@ COUNT(*)
DROP EVENT IF EXISTS event_Bug12546938;
DROP TABLE table_bug12546938;
SET GLOBAL EVENT_SCHEDULER = OFF;
+DROP DATABASE IF EXISTS event_test11764334;
+CREATE DATABASE event_test11764334;
+USE event_test11764334;
+CREATE EVENT ev1 ON SCHEDULE EVERY 3 SECOND DISABLE DO SELECT 1;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
+event_test11764334 ev1 root@localhost SYSTEM RECURRING NULL 3 SECOND 2011-06-09 19:59:01 NULL DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
+ALTER EVENT ev1 ON SCHEDULE EVERY 4 SECOND;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
+event_test11764334 ev1 root@localhost SYSTEM RECURRING NULL 4 SECOND 2011-06-09 19:59:01 NULL DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
+DROP EVENT ev1;
+DROP DATABASE event_test11764334;
+USE test;
DROP DATABASE events_test;
SET GLOBAL event_scheduler= 'ON';
SET @@global.concurrent_insert= @concurrent_insert;
diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test
index 4601448763c..3617a96c008 100644
--- a/mysql-test/t/events_bugs.test
+++ b/mysql-test/t/events_bugs.test
@@ -1286,6 +1286,21 @@ DROP EVENT IF EXISTS event_Bug12546938;
DROP TABLE table_bug12546938;
SET GLOBAL EVENT_SCHEDULER = OFF;
+#
+# Bug#11764334 - 57156: ALTER EVENT CHANGES THE EVENT STATUS
+#
+--disable_warnings
+DROP DATABASE IF EXISTS event_test11764334;
+--enable_warnings
+CREATE DATABASE event_test11764334;
+USE event_test11764334;
+CREATE EVENT ev1 ON SCHEDULE EVERY 3 SECOND DISABLE DO SELECT 1;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+ALTER EVENT ev1 ON SCHEDULE EVERY 4 SECOND;
+SHOW EVENTS IN event_test11764334 WHERE NAME='ev1';
+DROP EVENT ev1;
+DROP DATABASE event_test11764334;
+USE test;
###########################################################################
#
# End of tests
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 9efd3bca675..50339165b20 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -226,9 +226,16 @@ mysql_event_fill_row(THD *thd,
if (fields[f_num= ET_FIELD_NAME]->store(et->name.str, et->name.length, scs))
goto err_truncate;
- /* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/
+ /* ON_COMPLETION field is NOT NULL thus not calling set_notnull()*/
rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE);
- rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
+
+ /*
+ Set STATUS value unconditionally in case of CREATE EVENT.
+ For ALTER EVENT set it only if value of this field was changed.
+ Since STATUS field is NOT NULL call to set_notnull() is not needed.
+ */
+ if (!is_update || et->status_changed)
+ rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
/*
@@ -694,8 +701,6 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, FALSE))
goto end;
- table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE);
-
if ((ret= table->file->ha_write_row(table->record[0])))
{
table->file->print_error(ret, MYF(0));
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index 86905b38627..fb5c69ea2c5 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -46,9 +46,8 @@ Event_parse_data::new_instance(THD *thd)
Event_parse_data::Event_parse_data()
:on_completion(Event_parse_data::ON_COMPLETION_DEFAULT),
- status(Event_parse_data::ENABLED),
- do_not_create(FALSE),
- body_changed(FALSE),
+ status(Event_parse_data::ENABLED), status_changed(false),
+ do_not_create(FALSE), body_changed(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)
@@ -140,6 +139,7 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
else if (status == Event_parse_data::ENABLED)
{
status= Event_parse_data::DISABLED;
+ status_changed= true;
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_EVENT_EXEC_TIME_IN_THE_PAST,
ER(ER_EVENT_EXEC_TIME_IN_THE_PAST));
@@ -569,7 +569,10 @@ void Event_parse_data::check_originator_id(THD *thd)
DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED."));
if ((status == Event_parse_data::ENABLED) ||
(status == Event_parse_data::DISABLED))
- status = Event_parse_data::SLAVESIDE_DISABLED;
+ {
+ status= Event_parse_data::SLAVESIDE_DISABLED;
+ status_changed= true;
+ }
originator = thd->server_id;
}
else
diff --git a/sql/event_parse_data.h b/sql/event_parse_data.h
index 8b42eb23937..6ab2812f8b9 100644
--- a/sql/event_parse_data.h
+++ b/sql/event_parse_data.h
@@ -49,6 +49,7 @@ public:
int on_completion;
int status;
+ bool status_changed;
longlong originator;
/*
do_not_create will be set if STARTS time is in the past and
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4e24e69af42..3cd36be944f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2024,16 +2024,19 @@ opt_ev_status:
| ENABLE_SYM
{
Lex->event_parse_data->status= Event_parse_data::ENABLED;
+ Lex->event_parse_data->status_changed= true;
$$= 1;
}
| DISABLE_SYM ON SLAVE
{
Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
+ Lex->event_parse_data->status_changed= true;
$$= 1;
}
| DISABLE_SYM
{
Lex->event_parse_data->status= Event_parse_data::DISABLED;
+ Lex->event_parse_data->status_changed= true;
$$= 1;
}
;