Commit 19a22f87 authored by thek@adventure.(none)'s avatar thek@adventure.(none)

Bug#35997 Event scheduler seems to let the server crash, if it is embedded.

The event scheduler was not designed to work in embedded mode. This
patch disables and excludes the event scheduler when the server is
compiled for embedded build.
parent ee6373ab
......@@ -73,12 +73,10 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
event_scheduler.cc events.cc event_data_objects.cc \
event_queue.cc event_db_repository.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc
sql_servers.cc event_parse_data.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources)
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
......
set global event_scheduler=ON;
ERROR HY000: Unknown system variable 'event_scheduler'
--source include/is_embedded.inc
--error 1193
set global event_scheduler=ON;
......@@ -2,6 +2,8 @@
# Tests that require transactions
#
-- source include/have_innodb.inc
-- source include/not_embedded.inc
--disable_warnings
drop database if exists events_test;
drop database if exists mysqltest_no_such_database;
......
......@@ -73,7 +73,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
parse_file.h sql_view.h sql_trigger.h \
sql_array.h sql_cursor.h events.h scheduler.h \
event_db_repository.h event_queue.h \
sql_plugin.h authors.h \
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
contributors.h sql_servers.h
......@@ -120,7 +120,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
event_queue.cc event_db_repository.cc events.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc
sql_servers.cc event_parse_data.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
......@@ -140,6 +140,7 @@ DEFS = -DMYSQL_SERVER \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
-DPLUGINDIR="\"$(pkgplugindir)\"" \
-DHAVE_EVENT_SCHEDULER \
@DEFS@
BUILT_MAINT_SRC = sql_yacc.cc sql_yacc.h
......
This diff is collapsed.
......@@ -22,10 +22,7 @@
@file event_data_objects.h
*/
#define EVEX_GET_FIELD_FAILED -2
#define EVEX_BAD_PARAMS -5
#define EVEX_MICROSECOND_UNSUP -6
#include "event_parse_data.h"
class Event_queue_element_for_exec
{
......@@ -54,23 +51,6 @@ class Event_basic
MEM_ROOT mem_root;
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 name;
......@@ -201,83 +181,6 @@ class Event_job_data : public Event_basic
};
class Event_parse_data : public Sql_alloc
{
public:
int on_completion;
int status;
longlong originator;
/*
do_not_create will be set if STARTS time is in the past and
on_completion == ON_COMPLETION_DROP.
*/
bool do_not_create;
bool body_changed;
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING definer;// combination of user and host
LEX_STRING comment;
Item* item_starts;
Item* item_ends;
Item* item_execute_at;
my_time_t starts;
my_time_t ends;
my_time_t execute_at;
my_bool starts_null;
my_bool ends_null;
my_bool execute_at_null;
sp_name *identifier;
Item* item_expression;
longlong expression;
interval_type interval;
static Event_parse_data *
new_instance(THD *thd);
bool
check_parse_data(THD *thd);
private:
void
init_definer(THD *thd);
void
init_name(THD *thd, sp_name *spn);
int
init_execute_at(THD *thd);
int
init_interval(THD *thd);
int
init_starts(THD *thd);
int
init_ends(THD *thd);
Event_parse_data();
~Event_parse_data();
void
report_bad_value(const char *item_name, Item *bad_item);
void
check_if_in_the_past(THD *thd, my_time_t ltime_utc);
Event_parse_data(const Event_parse_data &); /* Prevent use of these */
void check_originator_id(THD *thd);
void operator=(Event_parse_data &);
};
/* Compares only the schema part of the identifier */
bool
event_basic_db_equal(LEX_STRING db, Event_basic *et);
......
This diff is collapsed.
/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef _EVENT_PARSE_DATA_H_
#define _EVENT_PARSE_DATA_H_
#define EVEX_GET_FIELD_FAILED -2
#define EVEX_BAD_PARAMS -5
#define EVEX_MICROSECOND_UNSUP -6
#define EVEX_MAX_INTERVAL_VALUE 1000000000L
class Event_parse_data : public Sql_alloc
{
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
};
int on_completion;
int status;
longlong originator;
/*
do_not_create will be set if STARTS time is in the past and
on_completion == ON_COMPLETION_DROP.
*/
bool do_not_create;
bool body_changed;
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING definer;// combination of user and host
LEX_STRING comment;
Item* item_starts;
Item* item_ends;
Item* item_execute_at;
my_time_t starts;
my_time_t ends;
my_time_t execute_at;
my_bool starts_null;
my_bool ends_null;
my_bool execute_at_null;
sp_name *identifier;
Item* item_expression;
longlong expression;
interval_type interval;
static Event_parse_data *
new_instance(THD *thd);
bool
check_parse_data(THD *thd);
private:
void
init_definer(THD *thd);
void
init_name(THD *thd, sp_name *spn);
int
init_execute_at(THD *thd);
int
init_interval(THD *thd);
int
init_starts(THD *thd);
int
init_ends(THD *thd);
Event_parse_data();
~Event_parse_data();
void
report_bad_value(const char *item_name, Item *bad_item);
void
check_if_in_the_past(THD *thd, my_time_t ltime_utc);
Event_parse_data(const Event_parse_data &); /* Prevent use of these */
void check_originator_id(THD *thd);
void operator=(Event_parse_data &);
};
#endif
......@@ -65,10 +65,10 @@ int event_queue_element_compare_q(void *vptr, uchar* a, uchar *b)
my_time_t lhs = left->execute_at;
my_time_t rhs = right->execute_at;
if (left->status == Event_queue_element::DISABLED)
return right->status != Event_queue_element::DISABLED;
if (left->status == Event_parse_data::DISABLED)
return right->status != Event_parse_data::DISABLED;
if (right->status == Event_queue_element::DISABLED)
if (right->status == Event_parse_data::DISABLED)
return 1;
return (lhs < rhs ? -1 : (lhs > rhs ? 1 : 0));
......@@ -198,7 +198,7 @@ Event_queue::create_event(THD *thd, Event_queue_element *new_element,
/* Will do nothing if the event is disabled */
new_element->compute_next_execution_time();
if (new_element->status != Event_queue_element::ENABLED)
if (new_element->status != Event_parse_data::ENABLED)
{
delete new_element;
*created= FALSE;
......@@ -236,8 +236,8 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
DBUG_ENTER("Event_queue::update_event");
DBUG_PRINT("enter", ("thd: 0x%lx et=[%s.%s]", (long) thd, dbname.str, name.str));
if ((new_element->status == Event_queue_element::DISABLED) ||
(new_element->status == Event_queue_element::SLAVESIDE_DISABLED))
if ((new_element->status == Event_parse_data::DISABLED) ||
(new_element->status == Event_parse_data::SLAVESIDE_DISABLED))
{
DBUG_PRINT("info", ("The event is disabled."));
/*
......@@ -452,7 +452,7 @@ Event_queue::recalculate_activation_times(THD *thd)
for (i= queue.elements; i > 0; i--)
{
Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1);
if (element->status != Event_queue_element::DISABLED)
if (element->status != Event_parse_data::DISABLED)
break;
/*
This won't cause queue re-order, because we remove
......@@ -615,14 +615,14 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
DBUG_PRINT("info", ("Ready for execution"));
top->mark_last_executed(thd);
if (top->compute_next_execution_time())
top->status= Event_queue_element::DISABLED;
top->status= Event_parse_data::DISABLED;
DBUG_PRINT("info", ("event %s status is %d", top->name.str, top->status));
top->execution_count++;
(*event_name)->dropped= top->dropped;
top->update_timing_fields(thd);
if (top->status == Event_queue_element::DISABLED)
if (top->status == Event_parse_data::DISABLED)
{
DBUG_PRINT("info", ("removing from the queue"));
sql_print_information("Event Scheduler: Last execution of %s.%s. %s",
......
......@@ -861,6 +861,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
bool
Events::init(my_bool opt_noacl)
{
THD *thd;
bool res= FALSE;
......@@ -954,7 +955,6 @@ Events::init(my_bool opt_noacl)
DBUG_RETURN(res);
}
/*
Cleans up scheduler's resources. Called at server shutdown.
......@@ -1170,7 +1170,7 @@ Events::load_events_from_db(THD *thd)
goto end;
}
drop_on_completion= (et->on_completion ==
Event_queue_element::ON_COMPLETION_DROP);
Event_parse_data::ON_COMPLETION_DROP);
if (event_queue->create_event(thd, et, &created))
......
......@@ -3498,7 +3498,9 @@ 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();
#ifdef HAVE_EVENT_SCHEDULER
Events::init_mutexes();
#endif
/* Parameter for threads created for connections */
(void) pthread_attr_init(&connection_attrib);
(void) pthread_attr_setdetachstate(&connection_attrib,
......@@ -7831,8 +7833,12 @@ mysqld_get_one_option(int optid,
}
#endif
case OPT_EVENT_SCHEDULER:
#ifndef HAVE_EVENT_SCHEDULER
sql_perror("Event scheduler is not supported in embedded build.");
#else
if (Events::set_opt_event_scheduler(argument))
exit(1);
#endif
break;
case (int) OPT_SKIP_NEW:
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
......
......@@ -241,7 +241,10 @@ static sys_var_long_ptr sys_delayed_insert_timeout(&vars, "delayed_insert_timeou
static sys_var_long_ptr sys_delayed_queue_size(&vars, "delayed_queue_size",
&delayed_queue_size);
#ifdef HAVE_EVENT_SCHEDULER
static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
#endif
static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
&expire_logs_days);
static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
......@@ -4026,13 +4029,12 @@ uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
return (uchar*) thd->strdup(buf);
}
#ifdef HAVE_EVENT_SCHEDULER
bool sys_var_event_scheduler::check(THD *thd, set_var *var)
{
return check_enum(thd, var, &Events::var_typelib);
}
/*
The update method of the global variable event_scheduler.
If event_scheduler is switched from 0 to 1 then the scheduler main
......@@ -4071,7 +4073,7 @@ uchar *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
{
return (uchar *) Events::get_opt_event_scheduler_str();
}
#endif
/****************************************************************************
Used templates
......
......@@ -1085,7 +1085,7 @@ class sys_var_thd_lc_time_names :public sys_var_thd
virtual void set_default(THD *thd, enum_var_type type);
};
#ifdef HAVE_EVENT_SCHEDULER
class sys_var_event_scheduler :public sys_var_long_ptr
{
/* We need a derived class only to have a warn_deprecated() */
......@@ -1101,6 +1101,7 @@ class sys_var_event_scheduler :public sys_var_long_ptr
return type != STRING_RESULT && type != INT_RESULT;
}
};
#endif
extern void fix_binlog_format_after_update(THD *thd, enum_var_type type);
......
......@@ -922,7 +922,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
ha_drop_database(path);
query_cache_invalidate1(db);
(void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */
#ifdef HAVE_EVENT_SCHEDULER
Events::drop_schema_events(thd, db);
#endif
error = 0;
}
}
......
......@@ -1998,7 +1998,12 @@ mysql_execute_command(THD *thd)
DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
switch (lex->sql_command) {
case SQLCOM_SHOW_EVENTS:
#ifndef HAVE_EVENT_SCHEDULER
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
break;
#endif
case SQLCOM_SHOW_STATUS_PROC:
case SQLCOM_SHOW_STATUS_FUNC:
res= execute_sqlcom_select(thd, all_tables);
......@@ -3483,6 +3488,7 @@ mysql_execute_command(THD *thd)
}
case SQLCOM_CREATE_EVENT:
case SQLCOM_ALTER_EVENT:
#ifdef HAVE_EVENT_SCHEDULER
do
{
DBUG_ASSERT(lex->event_parse_data);
......@@ -3536,6 +3542,10 @@ mysql_execute_command(THD *thd)
lex->drop_if_exists)))
my_ok(thd);
break;
#else
my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
break;
#endif
case SQLCOM_CREATE_FUNCTION: // UDF function
{
if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
......
......@@ -25,8 +25,10 @@
#include "sql_trigger.h"
#include "authors.h"
#include "contributors.h"
#ifdef HAVE_EVENT_SCHEDULER
#include "events.h"
#include "event_data_objects.h"
#endif
#include <my_dir.h>
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
......@@ -287,7 +289,9 @@ static struct show_privileges_st sys_privileges[]=
{"Create user", "Server Admin", "To create new users"},
{"Delete", "Tables", "To delete existing rows"},
{"Drop", "Databases,Tables", "To drop databases, tables, and views"},
#ifdef HAVE_EVENT_SCHEDULER
{"Event","Server Admin","To create, alter, drop and execute events"},
#endif
{"Execute", "Functions,Procedures", "To execute stored routines"},
{"File", "File access on server", "To read and write files on the server"},
{"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
......@@ -4959,7 +4963,7 @@ static interval_type get_real_interval_type(interval_type i_type)
#endif
#ifdef HAVE_EVENT_SCHEDULER
/*
Loads an event from mysql.event and copies it's data to a row of
I_S.EVENTS
......@@ -5079,14 +5083,14 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
switch (et.status)
{
case Event_timed::ENABLED:
case Event_parse_data::ENABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs);
break;
case Event_timed::SLAVESIDE_DISABLED:
case Event_parse_data::SLAVESIDE_DISABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("SLAVESIDE_DISABLED"),
scs);
break;
case Event_timed::DISABLED:
case Event_parse_data::DISABLED:
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs);
break;
default:
......@@ -5095,7 +5099,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table->field[ISE_ORIGINATOR]->store(et.originator, TRUE);
/* on_completion */
if (et.on_completion == Event_timed::ON_COMPLETION_DROP)
if (et.on_completion == Event_parse_data::ON_COMPLETION_DROP)
sch_table->field[ISE_ON_COMPLETION]->
store(STRING_WITH_LEN("NOT PRESERVE"), scs);
else
......@@ -5145,7 +5149,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
DBUG_RETURN(0);
}
#endif
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
{
......@@ -6541,8 +6545,10 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
{"ENGINES", engines_fields_info, create_schema_table,
fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
#ifdef HAVE_EVENT_SCHEDULER
{"EVENTS", events_fields_info, create_schema_table,
Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
#endif
{"FILES", files_fields_info, create_schema_table,
fill_schema_files, 0, 0, -1, -1, 0, 0},
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
......
......@@ -27,7 +27,9 @@
#include <sys/malloc.h>
#endif
#ifdef HAVE_EVENT_SCHEDULER
#include "events.h"
#endif
static const char *lock_descriptions[] =
{
......@@ -539,6 +541,8 @@ Estimated memory (with thread stack): %ld\n",
(long) (thread_count * my_thread_stack_size + info.hblkhd + info.arena));
#endif
#ifdef HAVE_EVENT_SCHEDULER
Events::dump_internal_status();
#endif
puts("");
}
......@@ -42,7 +42,7 @@
#include "sp_pcontext.h"
#include "sp_rcontext.h"
#include "sp.h"
#include "event_data_objects.h"
#include "event_parse_data.h"
#include <myisam.h>
#include <myisammrg.h>
......@@ -1783,7 +1783,6 @@ event_tail:
LEX *lex=Lex;
lex->create_info.options= $2;
if (!(lex->event_parse_data= Event_parse_data::new_instance(thd)))
MYSQL_YYABORT;
lex->event_parse_data->identifier= $3;
......@@ -1840,17 +1839,17 @@ opt_ev_status:
/* empty */ { $$= 0; }
| ENABLE_SYM
{
Lex->event_parse_data->status= Event_basic::ENABLED;
Lex->event_parse_data->status= Event_parse_data::ENABLED;
$$= 1;
}
| DISABLE_SYM ON SLAVE
{
Lex->event_parse_data->status= Event_basic::SLAVESIDE_DISABLED;
Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
$$= 1;
}
| DISABLE_SYM
{
Lex->event_parse_data->status= Event_basic::DISABLED;
Lex->event_parse_data->status= Event_parse_data::DISABLED;
$$= 1;
}
;
......@@ -1883,13 +1882,13 @@ ev_on_completion:
ON COMPLETION_SYM PRESERVE_SYM
{
Lex->event_parse_data->on_completion=
Event_basic::ON_COMPLETION_PRESERVE;
Event_parse_data::ON_COMPLETION_PRESERVE;
$$= 1;
}
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{
Lex->event_parse_data->on_completion=
Event_basic::ON_COMPLETION_DROP;
Event_parse_data::ON_COMPLETION_DROP;
$$= 1;
}
;
......
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