Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-08-16 19:55:14+02:00, andrey@stripped +16 -0
WL#3337 (Event scheduler new architecture)
Fixes from review.
1) Move Event_queue::check_system_tables() to Events::check_system_tables()
2) Create artificial THD in Events::init(). Hence, don't create a separate thread
in Event_queue::init_queue() to load the events from disk.
3) Whitespace changes.
4) Added const modifier wherever is feasible.
5) Whitespace fixes.
6) Method comments fixes.
7) Changed method which return value to be void wherever the
return value wasn't actually used (drop_schema_events())
8) Other small changes.
All but the const change are according review of WL#3337 patch code by Kostja
sql/event_data_objects.cc@stripped, 2006-08-16 19:55:08+02:00, andrey@stripped +44 -37
Changes that does not affect the execution:
- Whitespace changes
- Adding consts wherever feasible.
- Use initialization list for the constructor of Event_parse_data
- Shorten comments so they don't span till column 80
- Rename a parameter of event_basic_identifier_equal
sql/event_data_objects.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +10 -9
- White space changes
- Add const modifier wherever is feasible
sql/event_db_repository.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +89 -113
- Fix usage of initialized value in case of ha_write_row() has failed.
Changes that does not affect the actual execution
- Add const modifier wherever is feasible
- Fix function comments Returns -> RETURN VALUE
Synopsis -> SYNOPSIS
- Remove usage of macros for checking the values against the maximal
length of a column. The column already has this value. This makes
the code more transparent to changes.
- Modify methods to return bool instead of int, when only one error code
is returned.
- Fixed long comment, which mentions possible valgrind problem. Made it short.
- Made methods void where the return value is not actually used
(drop_schema_events(), drop_events_by_field())
sql/event_db_repository.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +21 -21
- Remove unneeded declaration
- Add const modifier wherever is feasible
- Make drop_schema_events() and drop_events_by_field() void as their
return value is unused.
- Change methods to return bool instead of int, because they return
actually only one error code.
sql/event_queue.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +59 -190
- The queue won't create a separate thread to load events on start up.
It gets the THD from the caller. The thd in the caller is artificially
and temporarily created.
- White space changes
- Added a better comment for Event_queue::init()
- Added const modifier wherever is feasible
- Whitespace changes
- Fixed method comments
- Changed find_n_remove_event() to destroy the removed object.
Helpful against memory leaks (this is according to Kostja's review).
Also made it void.
- Shortened comments so they don't span till column 80.
sql/event_queue.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +17 -19
- Add possibility to pass THD instance to used during init_queue() call.
This saves creation of a temporary THD (and a thread) inside init_queue().
- Whitespace changes
- Added const modifier wherever is feasible
- Made find_n_remove_event() void
sql/event_scheduler.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +6 -6
- Fix warning about usage of uninitialized variable in Event_scheduler::run()
- Added const modifiers wherever is feasible
sql/event_scheduler.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +6 -6
- Whitespace changes
- Added const modifier to execute_top()'s declaration
sql/events.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +229 -47
- Create a temporary THD to be used to initialize the queue.
- Move Event_queue::check_system_tables to Events::check_system_tables()
Check the tables only on start-up. If not in order then throw an error
message anytime any query which uses events DDL is used.
- If there was a problem during loading of events from disk on server start,
disable the queue functionality but allow creation on disk. The server needs
to be restarted to bring the queue to operation, if the problem that prevented
loading has been fixed.
- Added const modifier wherever is feasible
- Fixed methods' comments (parameter names)
- Whitespace changes
- Changed drop_schema_events() to be void, as its value is actually
not used in sql_db.cc
- Renamed is_started() to is_execution_of_events_started()
sql/events.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +33 -19
- Event_queue::check_system_tables() -> Events::check_system_tables()
db_ok -> TRUE, no problems during loading of events on server boot.
FALSE, there was an error.
- Whitespace changes
- Added const modifier wherever is feasible
- Moved friend declaration to be after the comment about it
- Changed drop_schema_event() to be void, as its value is not used
sql/set_var.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +1 -1
is_started() renamed to is_execution_of_events_started()
sql/share/errmsg.txt@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +2 -0
New error message for the case when the system tables were not what Events subsystem
expects, on server-start.
sql/sql_db.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +1 -1
drop_schema_events() changed to be void. The return value wasn't
actually used.
sql/sql_yacc.yy@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +20 -19
- Fixed comments
- Removed unneeded assigment Lex->spname= NULL. It is NULL-ed in lex_init()
- Changed an umlaut to be in ascii and not utf8
sql/table.cc@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +22 -22
Added const modifier to table_check_intact()
Fixed the comments of table_check_intact()
sql/table.h@stripped, 2006-08-16 19:55:09+02:00, andrey@stripped +3 -3
Added const modifier to the third parameter of table_check_intact()
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: andrey
# Host: example.com
# Root: /work/mysql-5.1-runtime-wl3337
--- 1.140/sql/sql_db.cc 2006-08-16 19:55:26 +02:00
+++ 1.141/sql/sql_db.cc 2006-08-16 19:55:26 +02:00
@@ -949,7 +949,7 @@ bool mysql_rm_db(THD *thd,char *db,bool
exit:
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
- error= Events::get_instance()->drop_schema_events(thd, db);
+ Events::get_instance()->drop_schema_events(thd, db);
/*
If this database was the client's selected database, we silently
change the client's selected database to nothing (to have an empty
--- 1.492/sql/sql_yacc.yy 2006-08-16 19:55:26 +02:00
+++ 1.493/sql/sql_yacc.yy 2006-08-16 19:55:26 +02:00
@@ -1445,11 +1445,11 @@ ev_sql_stmt:
{
LEX *lex=Lex;
- // return back to the original memory root ASAP
+ /* return back to the original memory root ASAP */
lex->sphead->init_strings(YYTHD, lex);
lex->sphead->restore_thd_mem_root(YYTHD);
- lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
+ lex->sp_chistics.suid= SP_IS_SUID; //always the definer!
Lex->event_parse_data->init_body(YYTHD);
}
@@ -1568,10 +1568,10 @@ create_function_tail:
sp->m_type= TYPE_ENUM_FUNCTION;
lex->sphead= sp;
/*
- * We have to turn of CLIENT_MULTI_QUERIES while parsing a
- * stored procedure, otherwise yylex will chop it into pieces
- * at each ';'.
- */
+ We have to turn off CLIENT_MULTI_QUERIES while parsing a
+ stored procedure, otherwise yylex will chop it into pieces
+ at each ';'.
+ */
$<ulong_num>$= YYTHD->client_capabilities &
CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
lex->sphead->m_param_begin= lex->tok_start+1;
@@ -4673,25 +4673,24 @@ alter:
{}
| ALTER EVENT_SYM sp_name
/*
- BE CAREFUL when you add a new rule to update the block where
- YYTHD->client_capabilities is set back to original value
+ BE CAREFUL when you add a new rule to update the block where
+ YYTHD->client_capabilities is set back to original value
*/
{
/*
- It is safe to use Lex->spname because
- ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
- is not allowed. Lex->spname is used in the case of RENAME TO
- If it had to be supported spname had to be added to
- Event_parse_data.
+ It is safe to use Lex->spname because
+ ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
+ is not allowed. Lex->spname is used in the case of RENAME TO
+ If it had to be supported spname had to be added to
+ Event_parse_data.
*/
- Lex->spname= NULL;
if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
YYABORT;
Lex->event_parse_data->identifier= $3;
/*
- We have to turn of CLIENT_MULTI_QUERIES while parsing a
+ We have to turn off CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
at each ';'.
*/
@@ -4757,9 +4756,11 @@ ev_alter_on_schedule_completion: /* empt
opt_ev_rename_to: /* empty */ { $$= 0;}
| RENAME TO_SYM sp_name
{
- LEX *lex=Lex;
- lex->spname= $3; //use lex's spname to hold the new name
- //the original name is in the Event_parse_data object
+ /*
+ Use lex's spname to hold the new name.
+ The original name is in the Event_parse_data object
+ */
+ Lex->spname= $3;
$$= 1;
}
;
@@ -4783,7 +4784,7 @@ alter_commands:
| remove_partitioning
| partitioning
/*
- This part was added for release 5.1 by Mikael Ronström.
+ This part was added for release 5.1 by Mikael Ronström.
From here we insert a number of commands to manage the partitions of a
partitioned table such as adding partitions, dropping partitions,
reorganising partitions in various manners. In future releases the list
--- 1.239/sql/table.cc 2006-08-16 19:55:26 +02:00
+++ 1.240/sql/table.cc 2006-08-16 19:55:26 +02:00
@@ -2352,28 +2352,28 @@ bool check_column_name(const char *name)
Checks whether a table is intact. Should be done *just* after the table has
been opened.
- Synopsis
+ SYNOPSIS
table_check_intact()
- table - the table to check
- table_f_count - expected number of columns in the table
- table_def - expected structure of the table (column name and type)
- last_create_time- the table->file->create_time of the table in memory
- we have checked last time
- error_num - ER_XXXX from the error messages file. When 0 no error
- is sent to the client in case types does not match.
- If different col number either
- ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE or
- ER_COL_COUNT_DOESNT_MATCH_CORRUPTED is used
+ table The table to check
+ table_f_count Expected number of columns in the table
+ table_def Expected structure of the table (column name and type)
+ last_create_time The table->file->create_time of the table in memory
+ we have checked last time
+ error_num ER_XXXX from the error messages file. When 0 no error
+ is sent to the client in case types does not match.
+ If different col number either
+ ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE or
+ ER_COL_COUNT_DOESNT_MATCH_CORRUPTED is used
RETURNS
- 0 - OK
- 1 - There was an error
+ FALSE OK
+ TRUE There was an error
*/
my_bool
-table_check_intact(TABLE *table, uint table_f_count,
- TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
- int error_num)
+table_check_intact(TABLE *table, const uint table_f_count,
+ const TABLE_FIELD_W_TYPE *table_def,
+ time_t *last_create_time, int error_num)
{
uint i;
my_bool error= FALSE;
@@ -2388,7 +2388,7 @@ table_check_intact(TABLE *table, uint ta
DBUG_PRINT("info", ("I am suspecting, checking table"));
if (fields_diff_count)
{
- // previous MySQL version
+ /* previous MySQL version */
error= TRUE;
if (MYSQL_VERSION_ID > table->s->mysql_version)
{
@@ -2411,22 +2411,22 @@ table_check_intact(TABLE *table, uint ta
else
{
/*
- moving from newer mysql to older one -> let's say not an error but
+ Moving from newer mysql to older one -> let's say not an error but
will check the definition afterwards. If a column was added at the
end then we don't care much since it's not in the middle.
*/
error= FALSE;
}
}
- //definitely something has changed
+ /* definitely something has changed */
char buffer[255];
for (i=0 ; i < table_f_count; i++, table_def++)
{
String sql_type(buffer, sizeof(buffer), system_charset_info);
sql_type.length(0);
/*
- name changes are not fatal, we use sequence numbers => no prob for us
- but this can show tampered table or broken table.
+ Name changes are not fatal, we use sequence numbers => no problem
+ for us but this can show tampered table or broken table.
*/
if (i < table->s->fields)
{
@@ -2440,7 +2440,7 @@ table_check_intact(TABLE *table, uint ta
}
/*
- IF the type does not match than something is really wrong
+ If the type does not match than something is really wrong
Check up to length - 1. Why?
1. datetime -> datetim -> the same
2. int(11) -> int(11 -> the same
--- 1.148/sql/table.h 2006-08-16 19:55:26 +02:00
+++ 1.149/sql/table.h 2006-08-16 19:55:26 +02:00
@@ -965,9 +965,9 @@ typedef struct st_table_field_w_type
my_bool
-table_check_intact(TABLE *table, uint table_f_count,
- TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
- int error_num);
+table_check_intact(TABLE *table, const uint table_f_count,
+ const TABLE_FIELD_W_TYPE * const table_def,
+ time_t *last_create_time, int error_num);
static inline my_bitmap_map *tmp_use_all_columns(TABLE *table,
MY_BITMAP *bitmap)
--- 1.58/sql/events.cc 2006-08-16 19:55:26 +02:00
+++ 1.59/sql/events.cc 2006-08-16 19:55:26 +02:00
@@ -90,7 +90,9 @@ ulong Events::opt_event_scheduler= 2;
1 s > t
*/
-int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
+int
+sortcmp_lex_string(const LEX_STRING s, const LEX_STRING t,
+ CHARSET_INFO * const cs)
{
return cs->coll->strnncollsp(cs, (uchar *) s.str,s.length,
(uchar *) t.str,t.length, 0);
@@ -265,7 +267,7 @@ common_1_lev_code:
int
Events::open_event_table(THD *thd, enum thr_lock_type lock_type,
- TABLE **table)
+ TABLE **table)
{
return db_repository->open_event_table(thd, lock_type, table);
}
@@ -277,7 +279,7 @@ Events::open_event_table(THD *thd, enum
SYNOPSIS
Events::create_event()
thd [in] THD
- et [in] Event's data from parsing stage
+ parse_data [in] Event's data from parsing stage
if_not_exists [in] Whether IF NOT EXISTS was specified in the DDL
rows_affected [out] How many rows were affected
@@ -291,18 +293,25 @@ Events::open_event_table(THD *thd, enum
*/
int
-Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists,
- uint *rows_affected)
+Events::create_event(THD *thd, Event_parse_data * const parse_data,
+ bool if_not_exists, uint *rows_affected)
{
int ret;
DBUG_ENTER("Events::create_event");
+ if (unlikely(init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
pthread_mutex_lock(&LOCK_event_metadata);
/* 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,
rows_affected)))
{
- if ((ret= event_queue->create_event(thd, parse_data->dbname,
+ if (init_state >= Events::QUEUE_INITIALIZED &&
+ (ret= event_queue->create_event(thd, parse_data->dbname,
parse_data->name)))
{
DBUG_ASSERT(ret == OP_LOAD_ERROR);
@@ -321,7 +330,7 @@ Events::create_event(THD *thd, Event_par
SYNOPSIS
Events::update_event()
thd [in] THD
- et [in] Event's data from parsing stage
+ parse_data [in] Event's data from parsing stage
rename_to [in] Set in case of RENAME TO.
rows_affected [out] How many rows were affected.
@@ -336,19 +345,27 @@ Events::create_event(THD *thd, Event_par
*/
int
-Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to,
- uint *rows_affected)
+Events::update_event(THD *thd, Event_parse_data * const parse_data,
+ const sp_name * const rename_to, uint *rows_affected)
{
int ret;
DBUG_ENTER("Events::update_event");
- LEX_STRING *new_dbname= rename_to? &rename_to->m_db: NULL;
- LEX_STRING *new_name= rename_to? &rename_to->m_name: NULL;
+ const LEX_STRING * const new_dbname= rename_to ? &rename_to->m_db: NULL;
+ const LEX_STRING * const new_name= rename_to ? &rename_to->m_name: NULL;
+
+ if (unlikely(init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
pthread_mutex_lock(&LOCK_event_metadata);
/* 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= event_queue->update_event(thd, parse_data->dbname,
+ if (init_state >= Events::QUEUE_INITIALIZED &&
+ (ret= event_queue->update_event(thd, parse_data->dbname,
parse_data->name, new_dbname, new_name)))
{
DBUG_ASSERT(ret == OP_LOAD_ERROR);
@@ -388,13 +405,18 @@ Events::drop_event(THD *thd, LEX_STRING
{
int ret;
DBUG_ENTER("Events::drop_event");
+ if (unlikely(init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */
if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists,
rows_affected)))
{
- if (!only_from_disk)
+ if (init_state >= Events::QUEUE_INITIALIZED && !only_from_disk)
event_queue->drop_event(thd, dbname, name);
}
pthread_mutex_unlock(&LOCK_event_metadata);
@@ -409,27 +431,29 @@ Events::drop_event(THD *thd, LEX_STRING
Events::drop_schema_events()
thd Thread
db ASCIIZ schema name
-
- RETURN VALUE
- 0 OK
- !0 Error
*/
-int
+void
Events::drop_schema_events(THD *thd, char *db)
{
- int ret= 0;
- LEX_STRING db_lex= {db, strlen(db)};
+ LEX_STRING const db_lex= { db, strlen(db) };
DBUG_ENTER("Events::drop_schema_events");
DBUG_PRINT("enter", ("dropping events from %s", db));
+ if (unlikely(init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ /* Don't send an error message because OK packet has been already sent */
+ DBUG_VOID_RETURN;
+ }
pthread_mutex_lock(&LOCK_event_metadata);
- event_queue->drop_schema_events(thd, db_lex);
- ret= db_repository->drop_schema_events(thd, db_lex);
+ if (init_state >= Events::QUEUE_INITIALIZED)
+ event_queue->drop_schema_events(thd, db_lex);
+ db_repository->drop_schema_events(thd, db_lex);
pthread_mutex_unlock(&LOCK_event_metadata);
- DBUG_RETURN(ret);
+ DBUG_VOID_RETURN;
}
@@ -438,8 +462,8 @@ Events::drop_schema_events(THD *thd, cha
SYNOPSIS
Events::show_create_event()
- thd THD
- spn the name of the event (db, name)
+ thd Thread context
+ spn The name of the event (db, name)
RETURN VALUE
0 OK
@@ -447,7 +471,7 @@ Events::drop_schema_events(THD *thd, cha
*/
int
-Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
+Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) const
{
CHARSET_INFO *scs= system_charset_info;
int ret;
@@ -455,6 +479,12 @@ Events::show_create_event(THD *thd, LEX_
DBUG_ENTER("Events::show_create_event");
DBUG_PRINT("enter", ("name: %s@%s", dbname.str, name.str));
+ if (unlikely(init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
ret= db_repository->load_named_event(thd, dbname, name, et);
@@ -481,8 +511,8 @@ Events::show_create_event(THD *thd, LEX_
field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len));
- field_list.
- push_back(new Item_empty_string("Create Event", show_str.length()));
+ field_list.push_back(new Item_empty_string("Create Event",
+ show_str.length()));
if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
@@ -511,7 +541,7 @@ err:
SYNOPSIS
Events::fill_schema_events()
- thd Thread
+ thd Thread context
tables The schema table
cond Unused
@@ -524,7 +554,14 @@ int
Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
{
char *db= NULL;
+ Events *myself= get_instance();
DBUG_ENTER("Events::fill_schema_events");
+ if (unlikely(myself->init_state < Events::SYSTEM_TABLES_CHECKED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", myself->init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ }
/*
If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
be NULL. Let's do an assert anyway.
@@ -537,8 +574,7 @@ Events::fill_schema_events(THD *thd, TAB
DBUG_RETURN(1);
db= thd->lex->select_lex.db;
}
- DBUG_RETURN(get_instance()->db_repository->
- fill_schema_events(thd, tables, db));
+ DBUG_RETURN(myself->db_repository->fill_schema_events(thd, tables, db));
}
@@ -552,31 +588,64 @@ Events::fill_schema_events(THD *thd, TAB
This function is not synchronized.
RETURN VALUE
- 0 OK
- 1 Error in case the scheduler can't start
+ FALSE OK
+ TRUE Error in case the scheduler can't start
*/
bool
Events::init()
{
- int res;
+ THD *thd;
+ bool res= FALSE;
DBUG_ENTER("Events::init");
- if (event_queue->init_queue(db_repository, scheduler))
+
+ /*
+ We need a temporary THD during boot.
+ */
+ if (!(thd= new THD()))
{
- sql_print_information("SCHEDULER: Error while loading from disk.");
- DBUG_RETURN(TRUE);
+ res= TRUE;
+ goto end;
+ }
+ /*
+ The thread stack does not start from this function but we cannot
+ guess the real value. So better some value that doesn't assert than
+ no value.
+ */
+ thd->thread_stack= (char*) &thd;
+ thd->store_globals();
+
+ if (check_system_tables(thd))
+ {
+ sql_print_error("SCHEDULER: The system tables are damaged. "
+ "The scheduler subsystem will be unusable during this run.");
+ goto end;
}
+ init_state= Events::SYSTEM_TABLES_CHECKED;
+
+ if (event_queue->init_queue(thd, db_repository, scheduler))
+ {
+ sql_print_error("SCHEDULER: Error while loading from disk.");
+ goto end;
+ }
+ init_state= Events::QUEUE_INITIALIZED;
+
scheduler->init_scheduler(event_queue);
+ init_state= Events::SCHEDULER_INITIALIZED;
- /* it should be an assignment! */
if (opt_event_scheduler)
{
DBUG_ASSERT(opt_event_scheduler == 1 || opt_event_scheduler == 2);
if (opt_event_scheduler == 1)
- DBUG_RETURN(scheduler->start());
+ res= scheduler->start();
}
- DBUG_RETURN(FALSE);
+end:
+ delete thd;
+ /* Remember that we don't have a THD */
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+
+ DBUG_RETURN(res);
}
@@ -594,11 +663,15 @@ void
Events::deinit()
{
DBUG_ENTER("Events::deinit");
+ DBUG_PRINT("info", ("init_state=%d", init_state));
- scheduler->stop();
- scheduler->deinit_scheduler();
-
- event_queue->deinit_queue();
+ if (likely(init_state >= Events::SCHEDULER_INITIALIZED))
+ {
+ scheduler->stop();
+ scheduler->deinit_scheduler();
+ }
+ if (likely(init_state >= Events::QUEUE_INITIALIZED))
+ event_queue->deinit_queue();
DBUG_VOID_RETURN;
}
@@ -610,6 +683,14 @@ Events::deinit()
SYNOPSIS
Events::init_mutexes()
thd Thread
+
+ NOTES
+ db_repository, event_queue and scheduler are allocated on the
+ stack to get a facade of class Events which won't lead to
+ recompilation of the clients that use events.h every time some
+ internal class has been changed. If they were static parts, and
+ not static pointers, then a change of the interface of one of the
+ classes will lead to recompile of every client of Events.
*/
void
@@ -670,13 +751,23 @@ Events::dump_internal_status(THD *thd)
Protocol *protocol= thd->protocol;
List<Item> field_list;
+ if (unlikely(init_state < Events::QUEUE_INITIALIZED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
field_list.push_back(new Item_empty_string("Name", 30));
field_list.push_back(new Item_empty_string("Value",20));
if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
- if (scheduler->dump_internal_status(thd) ||
+ if (scheduler->dump_internal_status(thd))
+ DBUG_RETURN(TRUE);
+
+ if (init_state < Events::SCHEDULER_INITIALIZED ||
event_queue->dump_internal_status(thd))
DBUG_RETURN(TRUE);
@@ -700,6 +791,12 @@ bool
Events::start_execution_of_events()
{
DBUG_ENTER("Events::start_execution_of_events");
+ if (unlikely(init_state < Events::SCHEDULER_INITIALIZED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(scheduler->start());
}
@@ -721,6 +818,12 @@ bool
Events::stop_execution_of_events()
{
DBUG_ENTER("Events::stop_execution_of_events");
+ if (unlikely(init_state < Events::SCHEDULER_INITIALIZED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(scheduler->stop());
}
@@ -737,8 +840,87 @@ Events::stop_execution_of_events()
*/
bool
-Events::is_started()
+Events::is_execution_of_events_started() const
{
- DBUG_ENTER("Events::is_started");
+ DBUG_ENTER("Events::is_execution_of_events_started");
+ if (unlikely(init_state < Events::SCHEDULER_INITIALIZED))
+ {
+ DBUG_PRINT("info", ("init_state=%d", init_state));
+ my_error(ER_EVENTS_DB_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
DBUG_RETURN(scheduler->get_state() == Event_scheduler::RUNNING);
+}
+
+
+
+/*
+ Opens mysql.db and mysql.user and checks whether:
+ 1. mysql.db has column Event_priv at column 20 (0 based);
+ 2. mysql.user has column Event_priv at column 29 (0 based);
+
+ SYNOPSIS
+ Events::check_system_tables()
+ thd Thread
+
+ RETURN VALUE
+ FALSE OK
+ TRUE Error
+*/
+
+bool
+Events::check_system_tables(THD *thd)
+{
+ TABLE_LIST tables;
+ bool not_used;
+ Open_tables_state backup;
+ bool ret= FALSE;
+
+ DBUG_ENTER("Events::check_system_tables");
+ DBUG_PRINT("enter", ("thd=0x%lx", thd));
+
+ thd->reset_n_backup_open_tables_state(&backup);
+
+ bzero((char*) &tables, sizeof(tables));
+ tables.db= (char*) "mysql";
+ tables.table_name= tables.alias= (char*) "db";
+ tables.lock_type= TL_READ;
+
+ if ((ret= simple_open_n_lock_tables(thd, &tables)))
+ {
+ sql_print_error("SCHEDULER: Cannot open mysql.db");
+ ret= TRUE;
+ }
+ ret= table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT,
+ mysql_db_table_fields, &mysql_db_table_last_check,
+ ER_CANNOT_LOAD_FROM_TABLE);
+ close_thread_tables(thd);
+
+ bzero((char*) &tables, sizeof(tables));
+ tables.db= (char*) "mysql";
+ tables.table_name= tables.alias= (char*) "user";
+ tables.lock_type= TL_READ;
+
+ if (simple_open_n_lock_tables(thd, &tables))
+ {
+ sql_print_error("SCHEDULER: Cannot open mysql.user");
+ ret= TRUE;
+ }
+ else
+ {
+ if (tables.table->s->fields < 29 ||
+ strncmp(tables.table->field[29]->field_name,
+ STRING_WITH_LEN("Event_priv")))
+ {
+ sql_print_error("mysql.user has no `Event_priv` column at position %d",
+ 29);
+ ret= TRUE;
+ }
+ close_thread_tables(thd);
+ }
+
+end:
+ thd->restore_backup_open_tables_state(&backup);
+
+ DBUG_RETURN(ret);
}
--- 1.43/sql/events.h 2006-08-16 19:55:26 +02:00
+++ 1.44/sql/events.h 2006-08-16 19:55:26 +02:00
@@ -36,66 +36,66 @@ enum enum_events_error_code
};
int
-sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
-
+sortcmp_lex_string(const LEX_STRING s, const LEX_STRING t,
+ CHARSET_INFO * const cs);
class Events
{
public:
- friend class Event_queue_element;
/*
Quite NOT the best practice and will be removed once
Event_timed::drop() and Event_timed is fixed not do drop directly
or other scheme will be found.
*/
+ friend class Event_queue_element;
static ulong opt_event_scheduler;
static TYPELIB opt_typelib;
bool
init();
-
+
void
deinit();
void
init_mutexes();
-
+
void
destroy_mutexes();
bool
start_execution_of_events();
-
+
bool
stop_execution_of_events();
-
+
bool
- is_started();
+ is_execution_of_events_started() const;
- static Events*
+ static Events *
get_instance();
int
- create_event(THD *thd, Event_parse_data *parse_data, bool if_exists,
- uint *rows_affected);
+ create_event(THD *thd, Event_parse_data * const parse_data,
+ bool if_exists, uint *rows_affected);
int
- update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to,
- uint *rows_affected);
+ update_event(THD *thd, Event_parse_data * const parse_data,
+ const sp_name * const rename_to, uint *rows_affected);
int
drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists,
uint *rows_affected, bool only_from_disk);
- int
+ void
drop_schema_events(THD *thd, char *db);
int
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
int
- show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
+ show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) const;
/* Needed for both SHOW CREATE EVENT and INFORMATION_SCHEMA */
static int
@@ -104,23 +104,37 @@ public:
static int
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
-
+
bool
dump_internal_status(THD *thd);
private:
+ enum enum_events_init_state
+ {
+ UNINITIALIZED= 0,
+ SYSTEM_TABLES_CHECKED,
+ QUEUE_INITIALIZED,
+ SCHEDULER_INITIALIZED
+ };
+
+ bool
+ check_system_tables(THD *thd);
+
/* Singleton DP is used */
- Events(){}
+ Events():init_state(Events::UNINITIALIZED)
+ {}
~Events(){}
/* Singleton instance */
static Events singleton;
Event_queue *event_queue;
- Event_scheduler *scheduler;
+ Event_scheduler *scheduler;
Event_db_repository *db_repository;
- pthread_mutex_t LOCK_event_metadata;
+ enum enum_events_init_state init_state;
+
+ pthread_mutex_t LOCK_event_metadata;
/* Prevent use of these */
Events(const Events &);
--- 1.12/sql/event_db_repository.cc 2006-08-16 19:55:26 +02:00
+++ 1.13/sql/event_db_repository.cc 2006-08-16 19:55:26 +02:00
@@ -22,14 +22,12 @@
#include "sp.h"
#include "sp_head.h"
-#define EVEX_DB_FIELD_LEN 64
-#define EVEX_NAME_FIELD_LEN 64
-
+static
time_t mysql_event_last_create_time= 0L;
static
-TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
+TABLE_FIELD_W_TYPE const event_table_fields[ET_FIELD_COUNT] =
{
{
{(char *) STRING_WITH_LEN("db")},
@@ -250,20 +248,21 @@ err_truncate:
/*
Performs an index scan of event_table (mysql.event) and fills schema_table.
- Synopsis
+ SYNOPSIS
Event_db_repository::index_read_for_db_for_i_s()
thd Thread
schema_table The I_S.EVENTS table
event_table The event table to use for loading (mysql.event)
- Returns
+ RETURN VALUE
0 OK
1 Error
*/
-int
+bool
Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table,
- TABLE *event_table, char *db)
+ TABLE *event_table,
+ const char *db)
{
int ret=0;
CHARSET_INFO *scs= system_charset_info;
@@ -305,33 +304,33 @@ Event_db_repository::index_read_for_db_f
event_table->file->ha_index_end();
/* ret is guaranteed to be != 0 */
if (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND)
- DBUG_RETURN(0);
- DBUG_RETURN(1);
+ DBUG_RETURN(FALSE);
+ DBUG_RETURN(TRUE);
}
/*
Performs a table scan of event_table (mysql.event) and fills schema_table.
- Synopsis
+ SYNOPSIS
Events_db_repository::table_scan_all_for_i_s()
thd Thread
schema_table The I_S.EVENTS in memory table
event_table The event table to use for loading.
- Returns
- 0 OK
- 1 Error
+ RETURN VALUE
+ FALSE OK
+ TRUE Error
*/
-int
+bool
Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table,
TABLE *event_table)
{
int ret;
READ_RECORD read_record_info;
-
DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
+
init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
/*
@@ -350,7 +349,7 @@ Event_db_repository::table_scan_all_for_
end_read_record(&read_record_info);
/* ret is guaranteed to be != 0 */
- DBUG_RETURN(ret == -1? 0:1);
+ DBUG_RETURN(ret == -1? FALSE:TRUE);
}
@@ -358,19 +357,20 @@ Event_db_repository::table_scan_all_for_
Fills I_S.EVENTS with data loaded from mysql.event. Also used by
SHOW EVENTS
- Synopsis
+ SYNOPSIS
Event_db_repository::fill_schema_events()
thd Thread
tables The schema table
db If not NULL then get events only from this schema
- Returns
- 0 OK
- 1 Error
+ RETURN VALUE
+ FALSE OK
+ TRUE Error
*/
-int
-Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables, char *db)
+bool
+Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
+ const char *db)
{
TABLE *schema_table= tables->table;
TABLE *event_table= NULL;
@@ -385,7 +385,7 @@ Event_db_repository::fill_schema_events(
{
sql_print_error("Table mysql.event is damaged.");
thd->restore_backup_open_tables_state(&backup);
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
}
/*
@@ -455,20 +455,20 @@ Event_db_repository::open_event_table(TH
/*
- Checks parameters which we got from the parsing phase.
+ Checks parameters which we got from the parsing phase.
- SYNOPSIS
- check_parse_params()
- thd THD
- et event's data
+ SYNOPSIS
+ check_parse_params()
+ thd Thread context
+ parse_data Event's data
- RETURNS
- 0 OK
- EVEX_BAD_PARAMS Error (reported)
+ RETURN VALUE
+ FALSE OK
+ TRUE Error (reported)
*/
-static int
-check_parse_params(THD *thd, Event_parse_data *parse_data)
+static bool
+check_parse_params(THD *thd, Event_parse_data * const parse_data)
{
const char *pos= NULL;
Item *bad_item;
@@ -477,24 +477,16 @@ check_parse_params(THD *thd, Event_parse
DBUG_ENTER("check_parse_params");
if (parse_data->check_parse_data(thd))
- DBUG_RETURN(EVEX_BAD_PARAMS);
-
- if (!parse_data->dbname.str ||
- (thd->lex->sql_command == SQLCOM_ALTER_EVENT &&
thd->lex->spname &&
- !thd->lex->spname->m_db.str))
- {
- my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
- DBUG_RETURN(EVEX_BAD_PARAMS);
- }
+ DBUG_RETURN(TRUE);
if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0,
is_schema_db(parse_data->dbname.str)) ||
(thd->lex->sql_command == SQLCOM_ALTER_EVENT &&
thd->lex->spname &&
(check_access(thd, EVENT_ACL, thd->lex->spname->m_db.str, 0, 0, 0,
is_schema_db(thd->lex->spname->m_db.str)))))
- DBUG_RETURN(EVEX_BAD_PARAMS);
+ DBUG_RETURN(TRUE);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -504,7 +496,7 @@ check_parse_params(THD *thd, Event_parse
SYNOPSIS
Event_db_repository::create_event()
thd [in] THD
- et [in] Object containing info about the event
+ parse_data [in] Object containing info about the event
create_if_not [in] Whether to generate anwarning in case event exists
rows_affected [out] How many rows were affected
@@ -517,8 +509,8 @@ check_parse_params(THD *thd, Event_parse
::update_event. The name of the event is inside "et".
*/
-int
-Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
+bool
+Event_db_repository::create_event(THD *thd, Event_parse_data * const parse_data,
my_bool create_if_not, uint *rows_affected)
{
int ret= 0;
@@ -531,6 +523,9 @@ Event_db_repository::create_event(THD *t
DBUG_ENTER("Event_db_repository::create_event");
*rows_affected= 0;
+ if (check_parse_params(thd, parse_data))
+ goto err;
+
DBUG_PRINT("info", ("open mysql.event for update"));
if (open_event_table(thd, TL_WRITE, &table))
{
@@ -538,8 +533,6 @@ Event_db_repository::create_event(THD *t
goto err;
}
- if (check_parse_params(thd, parse_data))
- goto err;
DBUG_PRINT("info", ("name: %.*s", parse_data->name.length,
parse_data->name.str));
@@ -570,16 +563,17 @@ Event_db_repository::create_event(THD *t
if (system_charset_info->cset->
numchars(system_charset_info, parse_data->dbname.str,
- parse_data->dbname.str +
- parse_data->dbname.length) > EVEX_DB_FIELD_LEN)
+ parse_data->dbname.str + parse_data->dbname.length) >
+ table->field[ET_FIELD_DB]->char_length())
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->dbname.str);
goto err;
}
+
if (system_charset_info->cset->
numchars(system_charset_info, parse_data->name.str,
- parse_data->name.str +
- parse_data->name.length) > EVEX_DB_FIELD_LEN)
+ parse_data->name.str + parse_data->name.length) >
+ table->field[ET_FIELD_NAME]->char_length())
{
my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->name.str);
goto err;
@@ -622,36 +616,18 @@ ok:
if (dbchanged)
(void) mysql_change_db(thd, old_db.str, 1);
/*
- When valgrinded, the following call may lead to the following error:
-
- Syscall param pwrite64(buf) points to uninitialised byte(s)
- at 0x406003B: do_pwrite64 (in /lib/tls/libpthread.so.0)
- by 0x40600EF: pwrite64 (in /lib/tls/libpthread.so.0)
- by 0x856FF74: my_pwrite (my_pread.c:146)
- by 0x85734E1: flush_cached_blocks (mf_keycache.c:2280)
- ....
- Address 0x6618110 is 56 bytes inside a block of size 927,772 alloc'd
- at 0x401C451: malloc (vg_replace_malloc.c:149)
- by 0x8578CDC: _mymalloc (safemalloc.c:138)
- by 0x858E5E2: my_large_malloc (my_largepage.c:65)
- by 0x8570634: init_key_cache (mf_keycache.c:343)
- by 0x82EDA51: ha_init_key_cache(char const*, st_key_cache*) (handler.cc:2509)
- by 0x8212071: process_key_caches(int (*)(char const*, st_key_cache*))
- (set_var.cc:3824)
- by 0x8206D75: init_server_components() (mysqld.cc:3304)
- by 0x8207163: main (mysqld.cc:3578)
-
- I think it is safe not to think about it.
+ This statement may cause a spooky valgrind warning at startup
+ inside init_key_cache on my system (ahristov, 2006/08/10)
*/
close_thread_tables(thd);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
err:
if (dbchanged)
(void) mysql_change_db(thd, old_db.str, 1);
if (table)
close_thread_tables(thd);
- DBUG_RETURN(EVEX_GENERAL_ERROR);
+ DBUG_RETURN(TRUE);
}
@@ -665,8 +641,8 @@ err:
et event's data
RETURN VALUE
- 0 OK
- EVEX_GENERAL_ERROR Error occured and reported
+ FALSE OK
+ TRUE Error (reported)
NOTES
sp_name is passed since this is the name of the event to
@@ -674,12 +650,12 @@ err:
*/
bool
-Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
- LEX_STRING *new_dbname, LEX_STRING *new_name)
+Event_db_repository::update_event(THD *thd, Event_parse_data * const parse_data,
+ const LEX_STRING * const new_dbname,
+ const LEX_STRING * const new_name)
{
CHARSET_INFO *scs= system_charset_info;
TABLE *table= NULL;
- int ret;
DBUG_ENTER("Event_db_repository::update_event");
if (open_event_table(thd, TL_WRITE, &table))
@@ -698,7 +674,7 @@ Event_db_repository::update_event(THD *t
DBUG_PRINT("info", ("rename to: %s@%s", new_dbname->str, new_name->str));
/* first look whether we overwrite */
- if (new_dbname)
+ if (new_name)
{
if (!sortcmp_lex_string(parse_data->name, *new_name, scs) &&
!sortcmp_lex_string(parse_data->dbname, *new_dbname, scs))
@@ -747,9 +723,10 @@ Event_db_repository::update_event(THD *t
if (end_active_trans(thd))
goto err;
- if (table->file->ha_update_row(table->record[1], table->record[0]))
+ int res;
+ if ((res= table->file->ha_update_row(table->record[1], table->record[0])))
{
- my_error(ER_EVENT_STORE_FAILED, MYF(0), parse_data->name.str, ret);
+ my_error(ER_EVENT_STORE_FAILED, MYF(0), parse_data->name.str, res);
goto err;
}
@@ -782,8 +759,9 @@ err:
*/
bool
-Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
- bool drop_if_exists, uint *rows_affected)
+Event_db_repository::drop_event(THD *thd, const LEX_STRING db,
+ const LEX_STRING name, bool drop_if_exists,
+ uint *rows_affected)
{
TABLE *table= NULL;
Open_tables_state backup;
@@ -844,8 +822,8 @@ done:
*/
bool
-Event_db_repository::find_named_event(THD *thd, LEX_STRING db, LEX_STRING name,
- TABLE *table)
+Event_db_repository::find_named_event(THD *thd, const LEX_STRING db,
+ const LEX_STRING name, TABLE * const table)
{
byte key[MAX_KEY_LENGTH];
DBUG_ENTER("Event_db_repository::find_named_event");
@@ -887,16 +865,14 @@ Event_db_repository::find_named_event(TH
Event_db_repository::drop_schema_events()
thd Thread
schema The database to clean from events
-
- RETURN VALUE
- 0 OK
- !0 Error (Reported)
*/
-int
+void
Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema)
{
- return drop_events_by_field(thd, ET_FIELD_DB, schema);
+ DBUG_ENTER("Event_db_repository::drop_schema_events");
+ drop_events_by_field(thd, ET_FIELD_DB, schema);
+ DBUG_VOID_RETURN;
}
@@ -909,28 +885,29 @@ Event_db_repository::drop_schema_events(
table mysql.event TABLE
field Which field of the row to use for matching
field_value The value that should match
-
- RETURN VALUE
- 0 OK
- !0 Error from ha_delete_row
*/
-int
+void
Event_db_repository::drop_events_by_field(THD *thd,
enum enum_events_table_field field,
- LEX_STRING field_value)
+ const LEX_STRING field_value)
{
int ret= 0;
TABLE *table= NULL;
- Open_tables_state backup;
READ_RECORD read_record_info;
DBUG_ENTER("Event_db_repository::drop_events_by_field");
DBUG_PRINT("enter", ("field=%d field_value=%s", field, field_value.str));
if (open_event_table(thd, TL_WRITE, &table))
{
- my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
- DBUG_RETURN(1);
+ /*
+ Currently being used only for DROP DATABASE - In this case we don't need
+ error message since the OK packet has been sent. But for DROP USER we
+ could need it.
+
+ my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
+ */
+ DBUG_VOID_RETURN;
}
/* only enabled events are in memory, so we go now and delete the rest */
@@ -939,22 +916,20 @@ Event_db_repository::drop_events_by_fiel
{
char *et_field= get_field(thd->mem_root, table->field[field]);
- LEX_STRING et_field_lex= {et_field, strlen(et_field)};
+ LEX_STRING et_field_lex= { et_field, strlen(et_field) };
DBUG_PRINT("info", ("Current event %s name=%s", et_field,
get_field(thd->mem_root, table->field[ET_FIELD_NAME])));
if (!sortcmp_lex_string(et_field_lex, field_value, system_charset_info))
{
DBUG_PRINT("info", ("Dropping"));
- if ((ret= table->file->ha_delete_row(table->record[0])))
- my_error(ER_EVENT_DROP_FAILED, MYF(0),
- get_field(thd->mem_root, table->field[ET_FIELD_NAME]));
+ ret= table->file->ha_delete_row(table->record[0]);
}
}
end_read_record(&read_record_info);
- thd->version--; /* Force close to free memory */
+ close_thread_tables(thd);
- DBUG_RETURN(ret);
+ DBUG_VOID_RETURN;
}
@@ -964,10 +939,10 @@ Event_db_repository::drop_events_by_fiel
SYNOPSIS
Event_db_repository::load_named_event()
- thd [in] THD
+ thd [in] Thread context
dbname [in] Event's db name
name [in] Event's name
- etn_new [out] The loaded event
+ etn [out] The loaded event
RETURN VALUE
FALSE OK
@@ -975,8 +950,9 @@ Event_db_repository::drop_events_by_fiel
*/
bool
-Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
- LEX_STRING name, Event_basic *etn)
+Event_db_repository::load_named_event(THD *thd, const LEX_STRING dbname,
+ const LEX_STRING name,
+ Event_basic * const etn)
{
TABLE *table= NULL;
int ret= 0;
--- 1.8/sql/event_db_repository.h 2006-08-16 19:55:26 +02:00
+++ 1.9/sql/event_db_repository.h 2006-08-16 19:55:26 +02:00
@@ -47,9 +47,6 @@ events_table_index_read_for_db(THD *thd,
int
events_table_scan_all(THD *thd, TABLE *schema_table, TABLE *event_table);
-int
-fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
-
class Event_basic;
class Event_parse_data;
@@ -58,43 +55,46 @@ class Event_db_repository
public:
Event_db_repository(){}
- int
- create_event(THD *thd, Event_parse_data *parse_data, my_bool create_if_not,
- uint *rows_affected);
+ bool
+ create_event(THD *thd, Event_parse_data * const parse_data,
+ my_bool create_if_not, uint *rows_affected);
bool
- update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname,
- LEX_STRING *new_name);
+ update_event(THD *thd, Event_parse_data * const parse_data,
+ const LEX_STRING * const new_dbname,
+ const LEX_STRING * const new_name);
bool
- drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists,
- uint *rows_affected);
+ drop_event(THD *thd, const LEX_STRING db, const LEX_STRING name,
+ bool drop_if_exists, uint *rows_affected);
- int
- drop_schema_events(THD *thd, LEX_STRING schema);
+ void
+ drop_schema_events(THD *thd, const LEX_STRING schema);
bool
- find_named_event(THD *thd, LEX_STRING db, LEX_STRING name, TABLE *table);
+ find_named_event(THD *thd, const LEX_STRING db, const LEX_STRING name,
+ TABLE * const table);
bool
- load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *et);
+ load_named_event(THD *thd, const LEX_STRING dbname, const LEX_STRING name,
+ Event_basic * const et);
int
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
- int
- fill_schema_events(THD *thd, TABLE_LIST *tables, char *db);
+ bool
+ fill_schema_events(THD *thd, TABLE_LIST *tables, const char *db);
private:
- int
+ void
drop_events_by_field(THD *thd, enum enum_events_table_field field,
- LEX_STRING field_value);
- int
+ const LEX_STRING field_value);
+ bool
index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table,
- char *db);
+ const char *db);
- int
+ bool
table_scan_all_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table);
static bool
--- 1.11/sql/event_queue.cc 2006-08-16 19:55:26 +02:00
+++ 1.12/sql/event_queue.cc 2006-08-16 19:55:26 +02:00
@@ -73,35 +73,6 @@ event_queue_element_compare_q(void *vptr
}
-pthread_handler_t
-event_queue_loader_thread(void *arg)
-{
- /* needs to be first for thread_stack */
- THD *thd= (THD *)((struct event_queue_param *) arg)->thd;
- struct event_queue_param *param= (struct event_queue_param *) arg;
- thd->thread_stack= (char *) &thd;
-
- if (post_init_event_thread(thd))
- goto end;
-
- DBUG_ENTER("event_queue_loader_thread");
-
-
- pthread_mutex_lock(¶m->LOCK_loaded);
- param->queue->check_system_tables(thd);
- param->queue->load_events_from_db(thd);
-
- param->loading_finished= TRUE;
- pthread_cond_signal(¶m->COND_loaded);
-
- pthread_mutex_unlock(¶m->LOCK_loaded);
-
-end:
- deinit_event_thread(thd);
- DBUG_RETURN(0); // Against gcc warnings
-}
-
-
/*
Constructor of class Event_queue.
@@ -150,7 +121,12 @@ Event_queue::deinit_mutexes()
/*
- Inits the queue
+ This is a queue's constructor. Until this method is called, the
+ queue is unusable. We don't use a C++ constructor instead in
+ order to be able to check the return value. The queue is
+ initialized once at server startup. Initialization can fail in
+ case of a failure reading events from the database or out of
+ memory.
SYNOPSIS
Event_queue::init()
@@ -161,9 +137,9 @@ Event_queue::deinit_mutexes()
*/
bool
-Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched)
+Event_queue::init_queue(THD *thd, Event_db_repository *db_repo,
+ Event_scheduler *sched)
{
- THD *new_thd;
pthread_t th;
bool res;
struct event_queue_param *event_queue_param_value= NULL;
@@ -186,43 +162,16 @@ Event_queue::init_queue(Event_db_reposit
if (sizeof(my_time_t) != sizeof(time_t))
{
sql_print_error("SCHEDULER: sizeof(my_time_t) != sizeof(time_t) ."
- "The scheduler may not work correctly. Stopping.");
+ "The scheduler may not work correctly. Stopping");
DBUG_ASSERT(0);
goto err;
}
- if (!(new_thd= new THD))
- goto err;
-
- pre_init_event_thread(new_thd);
- new_thd->security_ctx->set_user((char*)"event_scheduler_loader");
-
- event_queue_param_value= (struct event_queue_param *)
- my_malloc(sizeof(struct event_queue_param), MYF(0));
-
- event_queue_param_value->thd= new_thd;
- event_queue_param_value->queue= this;
- event_queue_param_value->loading_finished= FALSE;
- pthread_mutex_init(&event_queue_param_value->LOCK_loaded, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&event_queue_param_value->COND_loaded, NULL);
-
- pthread_mutex_lock(&event_queue_param_value->LOCK_loaded);
- DBUG_PRINT("info", ("Forking new thread for scheduduler. THD=0x%lx", new_thd));
- if (!(res= pthread_create(&th, &connection_attrib, event_queue_loader_thread,
- (void*)event_queue_param_value)))
- {
- do {
- pthread_cond_wait(&event_queue_param_value->COND_loaded,
- &event_queue_param_value->LOCK_loaded);
- } while (event_queue_param_value->loading_finished == FALSE);
- }
-
- pthread_mutex_unlock(&event_queue_param_value->LOCK_loaded);
- pthread_mutex_destroy(&event_queue_param_value->LOCK_loaded);
- pthread_cond_destroy(&event_queue_param_value->COND_loaded);
- my_free((char *)event_queue_param_value, MYF(0));
-
+ res= load_events_from_db(thd);
UNLOCK_QUEUE_DATA();
+ if (res)
+ deinit_queue();
+
DBUG_RETURN(res);
err:
@@ -267,7 +216,8 @@ Event_queue::deinit_queue()
*/
int
-Event_queue::create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
+Event_queue::create_event(THD *thd, const LEX_STRING dbname,
+ const LEX_STRING name)
{
int res;
Event_queue_element *new_element;
@@ -312,20 +262,21 @@ Event_queue::create_event(THD *thd, LEX_
*/
int
-Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
- LEX_STRING *new_schema, LEX_STRING *new_name)
+Event_queue::update_event(THD *thd,
+ const LEX_STRING dbname, const LEX_STRING name,
+ const LEX_STRING * const new_schema,
+ const LEX_STRING * const new_name)
{
int res;
- Event_queue_element *old_element= NULL,
- *new_element;
+ Event_queue_element *new_element;
DBUG_ENTER("Event_queue::update_event");
DBUG_PRINT("enter", ("thd=0x%lx et=[%s.%s]", thd, dbname.str, name.str));
new_element= new Event_queue_element();
- res= db_repository->load_named_event(thd, new_schema? *new_schema:dbname,
- new_name? *new_name:name, new_element);
+ res= db_repository->load_named_event(thd, new_schema ? *new_schema:dbname,
+ new_name ? *new_name:name, new_element);
if (res)
{
delete new_element;
@@ -345,16 +296,12 @@ Event_queue::update_event(THD *thd, LEX_
new_element->compute_next_execution_time();
LOCK_QUEUE_DATA();
- if (!(old_element= find_n_remove_event(dbname, name)))
- {
- DBUG_PRINT("info", ("%s.%s not cached, probably was DISABLED",
- dbname.str, name.str));
- }
+ find_n_remove_event(dbname, name);
+
/* If not disabled event */
if (new_element)
{
- DBUG_PRINT("info", ("new event in the Q 0x%lx old 0x%lx",
- new_element, old_element));
+ DBUG_PRINT("info", ("new event in the Q 0x%lx", new_element));
queue_insert_safe(&queue, (byte *) new_element);
}
dbug_dump_queue(thd->query_start());
@@ -363,8 +310,6 @@ Event_queue::update_event(THD *thd, LEX_
if (new_element)
notify_observers();
- if (old_element)
- delete old_element;
end:
DBUG_PRINT("info", ("res=%d", res));
DBUG_RETURN(res);
@@ -382,22 +327,16 @@ end:
*/
void
-Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
+Event_queue::drop_event(THD *thd, const LEX_STRING dbname, const LEX_STRING name)
{
int res;
- Event_queue_element *element;
DBUG_ENTER("Event_queue::drop_event");
DBUG_PRINT("enter", ("thd=0x%lx name=0x%lx", thd, name));
LOCK_QUEUE_DATA();
- element= find_n_remove_event(dbname, name);
+ find_n_remove_event(dbname, name);
dbug_dump_queue(thd->query_start());
UNLOCK_QUEUE_DATA();
-
- if (element)
- delete element;
- else
- DBUG_PRINT("info", ("No such event found, probably DISABLED"));
/*
We don't signal here because the scheduler will catch the change
@@ -426,13 +365,13 @@ Event_queue::drop_event(THD *thd, LEX_ST
*/
void
-Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
- bool (*comparator)(LEX_STRING, Event_basic *))
+Event_queue::drop_matching_events(THD *thd, const LEX_STRING pattern,
+ bool (*comparator)(const LEX_STRING, const Event_basic * const))
{
+ uint i= 0;
DBUG_ENTER("Event_queue::drop_matching_events");
DBUG_PRINT("enter", ("pattern=%s", pattern.str));
- uint i= 0;
while (i < queue.elements)
{
Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i);
@@ -440,10 +379,10 @@ Event_queue::drop_matching_events(THD *t
if (comparator(pattern, et))
{
/*
- The queue is ordered. If we remove an element, then all elements after
- it will shift one position to the left, if we imagine it as an array
- from left to the right. In this case we should not increment the
- counter and the (i < queue.elements) condition is ok.
+ The queue is ordered. If we remove an element, then all elements
+ after it will shift one position to the left, if we imagine it as
+ an array from left to the right. In this case we should not
+ increment the counter and the (i < queue.elements) condition is ok.
*/
queue_remove(&queue, i);
delete et;
@@ -453,12 +392,12 @@ Event_queue::drop_matching_events(THD *t
}
/*
We don't call notify_observers() . If we remove the top event:
- 1. The queue is empty. The scheduler will wake up at some time and realize
- that the queue is empty. If create_event() comes inbetween it will
- signal the scheduler
- 2. The queue is not empty, but the next event after the previous top, won't
- be executed any time sooner than the element we removed. Hence, we may
- not notify the scheduler and it will realize the change when it
+ 1. The queue is empty. The scheduler will wake up at some time and
+ realize that the queue is empty. If create_event() comes inbetween
+ it will signal the scheduler
+ 2. The queue is not empty, but the next event after the previous top,
+ won't be executed any time sooner than the element we removed. Hence,
+ we may not notify the scheduler and it will realize the change when it
wakes up from timedwait.
*/
@@ -472,15 +411,12 @@ Event_queue::drop_matching_events(THD *t
SYNOPSIS
Event_queue::drop_schema_events()
- thd THD
- db The schema name
-
- RETURN VALUE
- >=0 Number of dropped events
+ thd HD
+ schema The schema name
*/
void
-Event_queue::drop_schema_events(THD *thd, LEX_STRING schema)
+Event_queue::drop_schema_events(THD *thd, const LEX_STRING schema)
{
DBUG_ENTER("Event_queue::drop_schema_events");
LOCK_QUEUE_DATA();
@@ -516,17 +452,13 @@ Event_queue::notify_observers()
db The schema of the event to find
name The event to find
- RETURN VALUE
- NULL Not found
- otherwise Address
-
NOTE
The caller should do the locking also the caller is responsible for
actual signalling in case an event is removed from the queue.
*/
-Event_queue_element *
-Event_queue::find_n_remove_event(LEX_STRING db, LEX_STRING name)
+void
+Event_queue::find_n_remove_event(const LEX_STRING db, const LEX_STRING name)
{
uint i;
DBUG_ENTER("Event_queue::find_n_remove_event");
@@ -539,11 +471,12 @@ Event_queue::find_n_remove_event(LEX_STR
if (event_basic_identifier_equal(db, name, et))
{
queue_remove(&queue, i);
- DBUG_RETURN(et);
+ delete et;
+ break;
}
}
- DBUG_RETURN(NULL);
+ DBUG_VOID_RETURN;
}
@@ -583,7 +516,7 @@ Event_queue::load_events_from_db(THD *th
if ((ret= db_repository->open_event_table(thd, TL_READ, &table)))
{
- sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open.");
+ sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open");
DBUG_RETURN(EVEX_OPEN_TABLE_FAILED);
}
@@ -625,14 +558,17 @@ Event_queue::load_events_from_db(THD *th
temp_job_data.load_from_row(table);
- /* We load only on scheduler root just to check whether the body compiles */
+ /*
+ We load only on scheduler root just to check whether the body
+ compiles.
+ */
switch (ret= temp_job_data.compile(thd, thd->mem_root)) {
case EVEX_MICROSECOND_UNSUP:
sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not "
"supported but found in mysql.event");
break;
case EVEX_COMPILE_ERROR:
- sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load.",
+ sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load",
et->dbname.str, et->name.str);
break;
default:
@@ -663,12 +599,10 @@ end:
else
{
ret= 0;
- sql_print_information("SCHEDULER: Loaded %d event%s", count, (count == 1)?"":"s");
+ sql_print_information("SCHEDULER: Loaded %d event%s", count,
+ (count == 1)?"":"s");
}
- /* Force close to free memory */
- thd->version--;
-
close_thread_tables(thd);
DBUG_PRINT("info", ("Status code %d. Loaded %d event(s)", ret, count));
@@ -677,71 +611,6 @@ end:
/*
- Opens mysql.db and mysql.user and checks whether:
- 1. mysql.db has column Event_priv at column 20 (0 based);
- 2. mysql.user has column Event_priv at column 29 (0 based);
-
- SYNOPSIS
- Event_queue::check_system_tables()
- thd Thread
-
- RETURN VALUE
- FALSE OK
- TRUE Error
-*/
-
-void
-Event_queue::check_system_tables(THD *thd)
-{
- TABLE_LIST tables;
- bool not_used;
- Open_tables_state backup;
- bool ret;
-
- DBUG_ENTER("Event_queue::check_system_tables");
- DBUG_PRINT("enter", ("thd=0x%lx", thd));
-
- thd->reset_n_backup_open_tables_state(&backup);
-
- bzero((char*) &tables, sizeof(tables));
- tables.db= (char*) "mysql";
- tables.table_name= tables.alias= (char*) "db";
- tables.lock_type= TL_READ;
-
- if ((ret= simple_open_n_lock_tables(thd, &tables)))
- {
- sql_print_error("Cannot open mysql.db");
- goto end;
- }
- ret= table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT,
- mysql_db_table_fields, &mysql_db_table_last_check,
- ER_CANNOT_LOAD_FROM_TABLE);
- close_thread_tables(thd);
-
- bzero((char*) &tables, sizeof(tables));
- tables.db= (char*) "mysql";
- tables.table_name= tables.alias= (char*) "user";
- tables.lock_type= TL_READ;
-
- if (simple_open_n_lock_tables(thd, &tables))
- sql_print_error("Cannot open mysql.db");
- else
- {
- if (tables.table->s->fields < 29 ||
- strncmp(tables.table->field[29]->field_name,
- STRING_WITH_LEN("Event_priv")))
- sql_print_error("mysql.user has no `Event_priv` column at position 29");
- close_thread_tables(thd);
- }
-
-end:
- thd->restore_backup_open_tables_state(&backup);
-
- DBUG_VOID_RETURN;
-}
-
-
-/*
Recalculates activation times in the queue. There is one reason for
that. Because the values (execute_at) by which the queue is ordered are
changed by calls to compute_next_execution_time() on a request from the
@@ -782,7 +651,7 @@ Event_queue::recalculate_activation_time
Event_queue::empty_queue()
NOTE
- Should be called with LOCK_event_queue locked
+ Should be called with LOCK_event_queue locked
*/
void
@@ -812,7 +681,7 @@ Event_queue::empty_queue()
*/
void
-Event_queue::dbug_dump_queue(time_t now)
+Event_queue::dbug_dump_queue(time_t now) const
{
#ifndef DBUG_OFF
Event_queue_element *et;
@@ -1013,7 +882,7 @@ Event_queue::unlock_data(const char *fun
*/
bool
-Event_queue::dump_internal_status(THD *thd)
+Event_queue::dump_internal_status(THD *thd) const
{
DBUG_ENTER("Event_queue::dump_internal_status");
#ifndef DBUG_OFF
--- 1.9/sql/event_queue.h 2006-08-16 19:55:26 +02:00
+++ 1.10/sql/event_queue.h 2006-08-16 19:55:26 +02:00
@@ -31,33 +31,31 @@ public:
void
init_mutexes();
-
+
void
deinit_mutexes();
-
+
bool
- init_queue(Event_db_repository *db_repo, Event_scheduler *sched);
-
+ init_queue(THD *thd, Event_db_repository *db_repo, Event_scheduler *sched);
+
void
deinit_queue();
/* Methods for queue management follow */
int
- create_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
+ create_event(THD *thd, const LEX_STRING dbname, const LEX_STRING name);
int
- update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
- LEX_STRING *new_schema, LEX_STRING *new_name);
+ update_event(THD *thd, const LEX_STRING dbname, const LEX_STRING name,
+ const LEX_STRING * const new_schema,
+ const LEX_STRING * const new_name);
void
- drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
+ drop_event(THD *thd, const LEX_STRING dbname, const LEX_STRING name);
void
- drop_schema_events(THD *thd, LEX_STRING schema);
-
- void
- check_system_tables(THD *thd);
+ drop_schema_events(THD *thd, const LEX_STRING schema);
void
recalculate_activation_times(THD *thd);
@@ -66,19 +64,19 @@ public:
get_top_for_execution_if_time(THD *thd, time_t now, Event_job_data **job_data,
struct timespec *abstime);
bool
- dump_internal_status(THD *thd);
+ dump_internal_status(THD *thd) const;
int
load_events_from_db(THD *thd);
protected:
- Event_queue_element *
- find_n_remove_event(LEX_STRING db, LEX_STRING name);
+ void
+ find_n_remove_event(const LEX_STRING db, const LEX_STRING name);
void
- drop_matching_events(THD *thd, LEX_STRING pattern,
- bool (*)(LEX_STRING, Event_basic *));
+ drop_matching_events(THD *thd, const LEX_STRING pattern,
+ bool (*)(const LEX_STRING, const Event_basic * const));
void
empty_queue();
@@ -87,7 +85,7 @@ protected:
notify_observers();
void
- dbug_dump_queue(time_t now);
+ dbug_dump_queue(time_t now) const;
/* LOCK_event_queue is the mutex which protects the access to the queue. */
pthread_mutex_t LOCK_event_queue;
@@ -107,7 +105,7 @@ protected:
const char* mutex_last_attempted_lock_in_func;
bool mutex_queue_data_locked;
bool mutex_queue_data_attempting_lock;
-
+
/* helper functions for working with mutexes & conditionals */
void
lock_data(const char *func, uint line);
--- 1.20/sql/event_scheduler.cc 2006-08-16 19:55:26 +02:00
+++ 1.21/sql/event_scheduler.cc 2006-08-16 19:55:26 +02:00
@@ -61,7 +61,7 @@ struct scheduler_param {
*/
static void
-evex_print_warnings(THD *thd, Event_job_data *et)
+evex_print_warnings(THD *thd, const Event_job_data * const et)
{
MYSQL_ERROR *err;
DBUG_ENTER("evex_print_warnings");
@@ -253,7 +253,7 @@ event_worker_thread(void *arg)
{
/* needs to be first for thread_stack */
THD *thd;
- Event_job_data *event= (Event_job_data *)arg;
+ Event_job_data * const event= (Event_job_data *)arg;
int ret;
thd= event->thd;
@@ -384,7 +384,7 @@ Event_scheduler::start()
if (!(new_thd= new THD))
{
- sql_print_error("SCHEDULER: Cannot init manager event thread.");
+ sql_print_error("SCHEDULER: Cannot init manager event thread");
ret= TRUE;
goto end;
}
@@ -441,7 +441,7 @@ end:
bool
Event_scheduler::run(THD *thd)
{
- int res;
+ int res= FALSE;
struct timespec abstime;
Event_job_data *job_data;
DBUG_ENTER("Event_scheduler::run");
@@ -464,7 +464,7 @@ Event_scheduler::run(THD *thd)
&job_data, &abstime))
{
sql_print_information("SCHEDULER: Serious error during getting next"
- " event to execute. Stopping.");
+ " event to execute. Stopping");
break;
}
@@ -532,7 +532,7 @@ Event_scheduler::execute_top(THD *thd, E
pthread_t th;
int res= 0;
DBUG_ENTER("Event_scheduler::execute_top");
- if (!(new_thd= new THD))
+ if (!(new_thd= new THD()))
goto error;
pre_init_event_thread(new_thd);
--- 1.15/sql/event_scheduler.h 2006-08-16 19:55:26 +02:00
+++ 1.16/sql/event_scheduler.h 2006-08-16 19:55:26 +02:00
@@ -50,12 +50,12 @@ public:
stop();
/*
- Need to be public because has to be called from the function
+ Need to be public because has to be called from the function
passed to pthread_create.
*/
bool
run(THD *thd);
-
+
void
init_scheduler(Event_queue *queue);
@@ -64,7 +64,7 @@ public:
void
init_mutexes();
-
+
void
deinit_mutexes();
@@ -85,7 +85,7 @@ private:
/* helper functions */
bool
- execute_top(THD *thd, Event_job_data *job_data);
+ execute_top(THD *thd, Event_job_data * const job_data);
/* helper functions for working with mutexes & conditionals */
void
@@ -112,7 +112,7 @@ private:
ulong thread_id;
pthread_cond_t COND_state;
-
+
Event_queue *queue;
uint mutex_last_locked_at_line;
@@ -121,7 +121,7 @@ private:
const char* mutex_last_unlocked_in_func;
bool mutex_scheduler_data_locked;
bool waiting_on_cond;
-
+
ulonglong started_events;
private:
--- 1.74/sql/event_data_objects.cc 2006-08-16 19:55:26 +02:00
+++ 1.75/sql/event_data_objects.cc 2006-08-16 19:55:26 +02:00
@@ -59,19 +59,17 @@ Event_parse_data::new_instance(THD *thd)
*/
Event_parse_data::Event_parse_data()
+ :on_completion(ON_COMPLETION_DROP), status(ENABLED),
+ 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)
{
DBUG_ENTER("Event_parse_data::Event_parse_data");
- item_execute_at= item_expression= item_starts= item_ends= NULL;
- status= ENABLED;
- on_completion= ON_COMPLETION_DROP;
- expression= 0;
-
/* Actually in the parser STARTS is always set */
set_zero_time(&starts, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
- starts_null= ends_null= execute_at_null= TRUE;
body.str= comment.str= NULL;
body.length= comment.length= 0;
@@ -161,7 +159,7 @@ Event_parse_data::init_body(THD *thd)
*/
if ((*(body_end - 1) == '*') && (*body_end == '/'))
{
- DBUG_PRINT("info", ("consumend one '*" "/' comment in the query '%s'",
+ DBUG_PRINT("info", ("consumend one '*" "/' comment in the query '%s'",
body_begin));
body.length-= 2;
body_end-= 2;
@@ -217,7 +215,7 @@ Event_parse_data::init_execute_at(THD *t
DBUG_ASSERT(starts_null && ends_null);
/* let's check whether time is in the past */
- thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,
+ thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,
(my_time_t) thd->query_start());
if ((not_used= item_execute_at->get_date(<ime, TIME_NO_ZERO_DATE)))
@@ -512,7 +510,7 @@ error_bad_params:
*/
void
-Event_parse_data::report_bad_value(const char *item_name, Item *bad_item)
+Event_parse_data::report_bad_value(const char *item_name, Item * const bad_item)
{
char buff[120];
String str(buff,(uint32) sizeof(buff), system_charset_info);
@@ -736,8 +734,8 @@ Event_timed::~Event_timed()
Event_job_data::Event_job_data()
*/
-Event_job_data::Event_job_data():
- thd(NULL), sphead(NULL), sql_mode(0)
+Event_job_data::Event_job_data()
+ :thd(NULL), sphead(NULL), sql_mode(0)
{
}
@@ -1073,7 +1071,7 @@ bool get_next_time(TIME *next, TIME *sta
{
longlong seconds_diff;
long microsec_diff;
-
+
if (calc_time_diff(time_now, start, 1, &seconds_diff, µsec_diff))
{
DBUG_PRINT("error", ("negative difference"));
@@ -1115,14 +1113,16 @@ bool get_next_time(TIME *next, TIME *sta
interval.month= (diff_months / months)*months;
/*
Check if the same month as last_exec (always set - prerequisite)
- An event happens at most once per month so there is no way to schedule
- it two times for the current month. This saves us from two calls to
- date_add_interval() if the event was just executed. But if the scheduler
- is started and there was at least 1 scheduled date skipped this one does
- not help and two calls to date_add_interval() will be done, which is a
- bit more expensive but compared to the rareness of the case is neglectable.
+ An event happens at most once per month so there is no way to
+ schedule it two times for the current month. This saves us from two
+ calls to date_add_interval() if the event was just executed. But if
+ the scheduler is started and there was at least 1 scheduled date
+ skipped this one does not help and two calls to date_add_interval()
+ will be done, which is a bit more expensive but compared to the
+ rareness of the case is neglectable.
*/
- if (time_now->year==last_exec->year &&
time_now->month==last_exec->month)
+ if (time_now->year == last_exec->year &&
+ time_now->month == last_exec->month)
interval.month+= months;
tmp= *start;
@@ -1289,7 +1289,7 @@ Event_queue_element::compute_next_execut
}
goto ret;
}
- else if (starts_null && ends_null)
+ else if (starts_null && ends_null)
{
/* starts is always set, so this is a dead branch !! */
DBUG_PRINT("info", ("Neither STARTS nor ENDS are set"));
@@ -1333,7 +1333,7 @@ Event_queue_element::compute_next_execut
{
TIME next_exec;
- if (get_next_time(&next_exec, &starts, &time_now,
+ if (get_next_time(&next_exec, &starts, &time_now,
last_executed.year? &last_executed:&starts,
expression, interval))
goto err;
@@ -1454,7 +1454,8 @@ Event_queue_element::drop(THD *thd)
RETURN VALUE
FALSE OK
- TRUE Error while opening mysql.event for writing or during write on disk
+ TRUE Error while opening mysql.event for writing or during
+ write on disk
*/
bool
@@ -1530,7 +1531,7 @@ done:
*/
int
-Event_timed::get_create_event(THD *thd, String *buf)
+Event_timed::get_create_event(THD *thd, String *buf) const
{
int multipl= 0;
char tmp_buf[2 * STRING_BUFFER_USUAL_SIZE];
@@ -1605,7 +1606,7 @@ Event_timed::get_create_event(THD *thd,
*/
int
-Event_job_data::get_fake_create_event(THD *thd, String *buf)
+Event_job_data::get_fake_create_event(THD *thd, String *buf) const
{
DBUG_ENTER("Event_job_data::get_create_event");
buf->append(STRING_WITH_LEN("CREATE EVENT anonymous ON SCHEDULE "
@@ -1645,9 +1646,9 @@ Event_job_data::execute(THD *thd)
event_change_security_context(thd, definer_user, definer_host, dbname,
&save_ctx);
/*
- THD::~THD will clean this or if there is DROP DATABASE in the SP then
- it will be free there. It should not point to our buffer which is allocated
- on a mem_root.
+ THD::~THD will clean this or if there is DROP DATABASE in the
+ SP then it will be free there. It should not point to our buffer
+ which is allocated on a mem_root.
*/
thd->db= my_strdup(dbname.str, MYF(0));
thd->db_length= dbname.length;
@@ -1719,7 +1720,6 @@ Event_job_data::compile(THD *thd, MEM_RO
switch (get_fake_create_event(thd, &show_create)) {
case EVEX_MICROSECOND_UNSUP:
- sql_print_error("Scheduler");
DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
case 0:
break;
@@ -1769,7 +1769,8 @@ Event_job_data::compile(THD *thd, MEM_RO
Free lex associated resources
QQ: Do we really need all this stuff here?
*/
- sql_print_error("error during compile of %s.%s or thd->is_fatal_error=%d",
+ sql_print_error("SCHEDULER: Error during compilation of %s.%s or "
+ "thd->is_fatal_error=%d",
dbname.str, name.str, thd->is_fatal_error);
lex.unit.cleanup();
@@ -1825,17 +1826,20 @@ done:
*/
bool
-event_basic_db_equal(LEX_STRING db, Event_basic *et)
+event_basic_db_equal(const LEX_STRING db, const Event_basic * const et)
{
return !sortcmp_lex_string(et->dbname, db, system_charset_info);
}
/*
- Checks whether two events are equal by identifiers
+ Checks whether an event has equal `db` and `name`
SYNOPSIS
event_basic_identifier_equal()
+ db Schema
+ name Name
+ et The event object
RETURN VALUE
TRUE Equal
@@ -1843,15 +1847,17 @@ event_basic_db_equal(LEX_STRING db, Even
*/
bool
-event_basic_identifier_equal(LEX_STRING db, LEX_STRING name, Event_basic *b)
+event_basic_identifier_equal(const LEX_STRING db, const LEX_STRING name,
+ const Event_basic * const et)
{
- return !sortcmp_lex_string(name, b->name, system_charset_info) &&
- !sortcmp_lex_string(db, b->dbname, system_charset_info);
+ return !sortcmp_lex_string(name, et->name, system_charset_info) &&
+ !sortcmp_lex_string(db, et->dbname, system_charset_info);
}
/*
- Switches the security context
+ Switches the security context.
+
SYNOPSIS
event_change_security_context()
thd Thread
@@ -1859,7 +1865,7 @@ event_basic_identifier_equal(LEX_STRING
host The host of the user
db The schema for which the security_ctx will be loaded
backup Where to store the old context
-
+
RETURN VALUE
FALSE OK
TRUE Error (generates error too)
@@ -1887,7 +1893,8 @@ event_change_security_context(THD *thd,
/*
- Restores the security context
+ Restores the security context.
+
SYNOPSIS
event_restore_security_context()
thd Thread
--- 1.12/sql/event_data_objects.h 2006-08-16 19:55:26 +02:00
+++ 1.13/sql/event_data_objects.h 2006-08-16 19:55:26 +02:00
@@ -37,7 +37,7 @@ public:
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING definer;// combination of user and host
-
+
Event_basic();
virtual ~Event_basic();
@@ -90,7 +90,7 @@ public:
Event_queue_element();
virtual ~Event_queue_element();
-
+
virtual int
load_from_row(TABLE *table);
@@ -154,7 +154,7 @@ public:
load_from_row(TABLE *table);
int
- get_create_event(THD *thd, String *buf);
+ get_create_event(THD *thd, String *buf) const;
};
@@ -185,9 +185,9 @@ public:
compile(THD *thd, MEM_ROOT *mem_root);
private:
int
- get_fake_create_event(THD *thd, String *buf);
+ get_fake_create_event(THD *thd, String *buf) const;
- Event_job_data(const Event_job_data &); /* Prevent use of these */
+ Event_job_data(const Event_job_data &); /* Prevent use of these */
void operator=(Event_job_data &);
};
@@ -237,7 +237,7 @@ public:
new_instance(THD *thd);
bool
- check_parse_data(THD *);
+ check_parse_data(THD *thd);
void
init_body(THD *thd);
@@ -266,7 +266,7 @@ private:
~Event_parse_data();
void
- report_bad_value(const char *item_name, Item *bad_item);
+ report_bad_value(const char *item_name, Item * const bad_item);
Event_parse_data(const Event_parse_data &); /* Prevent use of these */
void operator=(Event_parse_data &);
@@ -275,11 +275,12 @@ private:
/* Compares only the schema part of the identifier */
bool
-event_basic_db_equal(LEX_STRING db, Event_basic *et);
+event_basic_db_equal(const LEX_STRING db, const Event_basic * const et);
/* Compares the whole identifier*/
bool
-event_basic_identifier_equal(LEX_STRING db, LEX_STRING name, Event_basic *b);
+event_basic_identifier_equal(const LEX_STRING db, const LEX_STRING name,
+ const Event_basic * const b);
#endif /* _EVENT_DATA_OBJECTS_H_ */
--- 1.118/sql/share/errmsg.txt 2006-08-16 19:55:26 +02:00
+++ 1.119/sql/share/errmsg.txt 2006-08-16 19:55:26 +02:00
@@ -5851,3 +5851,5 @@ ER_CANT_DROP_LOG_TABLE
eng "Cannot drop log table if log is enabled"
ER_EVENT_RECURSIVITY_FORBIDDEN
eng "Recursivity of EVENT DDL statements is forbidden when body is present"
+ER_EVENTS_DB_ERROR
+ eng "Cannot proceed because the tables used by events were found damaged at
server start"
--- 1.183/sql/set_var.cc 2006-08-16 19:55:26 +02:00
+++ 1.184/sql/set_var.cc 2006-08-16 19:55:26 +02:00
@@ -3978,7 +3978,7 @@ byte *sys_var_event_scheduler::value_ptr
{
if (Events::opt_event_scheduler == 0)
thd->sys_var_tmp.long_value= 0;
- else if (Events::get_instance()->is_started())
+ else if (Events::get_instance()->is_execution_of_events_started())
thd->sys_var_tmp.long_value= 1;
else
thd->sys_var_tmp.long_value= 2;
| Thread |
|---|
| • bk commit into 5.1 tree (andrey:1.2278) | ahristov | 16 Aug |