Commit 3d854641 authored by andrey@lmy004's avatar andrey@lmy004

WL #1034 updates after review

(strip m_ as prefix from member variables' names)
parent b7578df0
/* Copyright (C) 2000-2003 MySQL AB
/* Copyright (C) 2004-2005 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
......@@ -143,7 +143,7 @@ my_time_compare(TIME *a, TIME *b)
inline int
event_timed_compare(event_timed **a, event_timed **b)
{
return my_time_compare(&(*a)->m_execute_at, &(*b)->m_execute_at);
return my_time_compare(&(*a)->execute_at, &(*b)->execute_at);
}
......@@ -258,55 +258,55 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
DBUG_RETURN(EVEX_GET_FIELD_FAILED);
}
DBUG_PRINT("info", ("m_db.len=%d",et->m_db.length));
DBUG_PRINT("info", ("m_name.len=%d",et->m_name.length));
DBUG_PRINT("info", ("dbname.len=%d",et->dbname.length));
DBUG_PRINT("info", ("name.len=%d",et->name.length));
table->field[EVEX_FIELD_DB]->
store(et->m_db.str, et->m_db.length, system_charset_info);
store(et->dbname.str, et->dbname.length, system_charset_info);
table->field[EVEX_FIELD_NAME]->
store(et->m_name.str, et->m_name.length, system_charset_info);
store(et->name.str, et->name.length, system_charset_info);
table->field[EVEX_FIELD_ON_COMPLETION]->set_notnull();
table->field[EVEX_FIELD_ON_COMPLETION]->store((longlong)et->m_on_completion);
table->field[EVEX_FIELD_ON_COMPLETION]->store((longlong)et->on_completion);
table->field[EVEX_FIELD_STATUS]->set_notnull();
table->field[EVEX_FIELD_STATUS]->store((longlong)et->m_status);
et->m_status_changed= false;
table->field[EVEX_FIELD_STATUS]->store((longlong)et->status);
// et->status_changed= false;
// ToDo: Andrey. How to use users current charset?
if (et->m_body.str)
if (et->body.str)
table->field[EVEX_FIELD_BODY]->
store(et->m_body.str, et->m_body.length, system_charset_info);
store(et->body.str, et->body.length, system_charset_info);
if (et->m_starts.year)
if (et->starts.year)
{
table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF
table->field[EVEX_FIELD_STARTS]->store_time(&et->m_starts,MYSQL_TIMESTAMP_DATETIME);
table->field[EVEX_FIELD_STARTS]->store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME);
}
if (et->m_ends.year)
if (et->ends.year)
{
table->field[EVEX_FIELD_ENDS]->set_notnull();
table->field[EVEX_FIELD_ENDS]->store_time(&et->m_ends, MYSQL_TIMESTAMP_DATETIME);
table->field[EVEX_FIELD_ENDS]->store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
}
if (et->m_expr)
if (et->expression)
{
table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull();
table->field[EVEX_FIELD_INTERVAL_EXPR]->store((longlong)et->m_expr);
table->field[EVEX_FIELD_INTERVAL_EXPR]->store((longlong)et->expression);
table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_notnull();
/*
In the enum (C) intervals start from 0 but in mysql enum valid values start
from 1. Thus +1 offset is needed!
*/
table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->m_interval + 1);
table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval + 1);
}
else if (et->m_execute_at.year)
else if (et->execute_at.year)
{
// fix_fields already called in init_execute_at
table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull();
table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->m_execute_at,
table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at,
MYSQL_TIMESTAMP_DATETIME);
//this will make it NULL because we don't call set_notnull
......@@ -321,9 +321,9 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time();
if ((et->m_comment).length)
if (et->comment.length)
table->field[EVEX_FIELD_COMMENT]->
store((et->m_comment).str, (et->m_comment).length, system_charset_info);
store(et->comment.str, et->comment.length, system_charset_info);
DBUG_RETURN(0);
}
......@@ -351,7 +351,7 @@ db_create_event(THD *thd, event_timed *et)
char olddb[128];
bool dbchanged= false;
DBUG_ENTER("db_create_event");
DBUG_PRINT("enter", ("name: %.*s", et->m_name.length, et->m_name.str));
DBUG_PRINT("enter", ("name: %.*s", et->name.length, et->name.str));
DBUG_PRINT("info", ("open mysql.event for update"));
......@@ -362,14 +362,14 @@ db_create_event(THD *thd, event_timed *et)
}
DBUG_PRINT("info", ("check existance of an event with the same name"));
if (!evex_db_find_routine_aux(thd, et->m_db, et->m_name, table))
if (!evex_db_find_routine_aux(thd, et->dbname, et->name, table))
{
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->m_name.str);
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
goto err;
}
DBUG_PRINT("info", ("non-existant, go forward"));
if ((ret= sp_use_new_db(thd, et->m_db.str,olddb, sizeof(olddb),0, &dbchanged)))
if ((ret= sp_use_new_db(thd, et->dbname.str,olddb, sizeof(olddb),0, &dbchanged)))
{
my_error(ER_BAD_DB_ERROR, MYF(0));
goto err;
......@@ -378,31 +378,31 @@ db_create_event(THD *thd, event_timed *et)
restore_record(table, s->default_values); // Get default values for fields
if (et->m_name.length > table->field[EVEX_FIELD_NAME]->field_length)
if (et->name.length > table->field[EVEX_FIELD_NAME]->field_length)
{
my_error(ER_TOO_LONG_IDENT, MYF(0), et->m_name.str);
my_error(ER_TOO_LONG_IDENT, MYF(0), et->name.str);
goto err;
}
if (et->m_body.length > table->field[EVEX_FIELD_BODY]->field_length)
if (et->body.length > table->field[EVEX_FIELD_BODY]->field_length)
{
my_error(ER_TOO_LONG_BODY, MYF(0), et->m_name.str);
my_error(ER_TOO_LONG_BODY, MYF(0), et->name.str);
goto err;
}
if (!(et->m_expr) && !(et->m_execute_at.year))
if (!(et->expression) && !(et->execute_at.year))
{
DBUG_PRINT("error", ("neither m_expr nor m_execute_as are set!"));
DBUG_PRINT("error", ("neither expression nor execute_at are set!"));
my_error(ER_EVENT_NEITHER_M_EXPR_NOR_M_AT, MYF(0));
goto err;
}
strxmov(definer, et->m_definer_user.str, "@", et->m_definer_host.str, NullS);
strxmov(definer, et->definer_user.str, "@", et->definer_host.str, NullS);
if (table->field[EVEX_FIELD_DEFINER]->
store(definer, et->m_definer_user.length + 1 + et->m_definer_host.length,
store(definer, et->definer_user.length + 1 + et->definer_host.length,
system_charset_info))
{
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str);
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
goto err;
}
......@@ -413,7 +413,7 @@ db_create_event(THD *thd, event_timed *et)
ret= EVEX_OK;
if (table->file->write_row(table->record[0]))
{
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str);
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
goto err;
}
......@@ -452,14 +452,15 @@ err:
*/
static int
db_update_event(THD *thd, sp_name *name, event_timed *et)
db_update_event(THD *thd, sp_name *new_name, event_timed *et)
{
TABLE *table;
int ret= EVEX_OPEN_TABLE_FAILED;
DBUG_ENTER("db_update_event");
DBUG_PRINT("enter", ("name: %.*s", et->m_name.length, et->m_name.str));
if (name)
DBUG_PRINT("enter", ("rename to: %.*s", name->m_name.length, name->m_name.str));
DBUG_PRINT("enter", ("name: %.*s", et->name.length, et->name.str));
if (new_name)
DBUG_PRINT("enter", ("rename to: %.*s", new_name->m_name.length,
new_name->m_name.str));
if (!(table= evex_open_event_table(thd, TL_WRITE)))
{
......@@ -467,10 +468,10 @@ db_update_event(THD *thd, sp_name *name, event_timed *et)
goto err;
}
if (EVEX_KEY_NOT_FOUND == evex_db_find_routine_aux(thd, et->m_db, et->m_name,
if (EVEX_KEY_NOT_FOUND == evex_db_find_routine_aux(thd, et->dbname, et->name,
table))
{
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->m_name.str);
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
goto err;
}
......@@ -483,17 +484,17 @@ db_update_event(THD *thd, sp_name *name, event_timed *et)
if ((ret= evex_fill_row(thd, table, et, true)))
goto err;
if (name)
if (new_name)
{
table->field[EVEX_FIELD_DB]->
store(name->m_db.str, name->m_db.length, system_charset_info);
store(new_name->m_db.str, new_name->m_db.length, system_charset_info);
table->field[EVEX_FIELD_NAME]->
store(name->m_name.str, name->m_name.length, system_charset_info);
store(new_name->m_name.str, new_name->m_name.length, system_charset_info);
}
if ((ret= table->file->update_row(table->record[1], table->record[0])))
{
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str);
my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
goto err;
}
......@@ -546,7 +547,7 @@ db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl)
if ((ret= evex_db_find_routine_aux(thd, name->m_db, name->m_name, table)))
{
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->m_name.str);
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name->m_name.str);
goto done;
}
et= new event_timed;
......@@ -612,7 +613,7 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
/*
allocate on evex_mem_root. if you call without evex_mem_root
then m_sphead will not be cleared!
then sphead will not be cleared!
*/
if ((ret= ett->compile(thd, &evex_mem_root)))
goto done;
......@@ -627,10 +628,10 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
VOID(push_dynamic(&evex_executing_queue, (gptr) &ett_copy));
/*
There is a copy in the array which we don't need. m_sphead won't be
There is a copy in the array which we don't need. sphead won't be
destroyed.
*/
ett->m_free_sphead_on_delete= false;
ett->free_sphead_on_delete= false;
delete ett;
/*
......@@ -674,11 +675,11 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
event_timed **p_et= dynamic_element(&evex_executing_queue, i, event_timed**);
event_timed *ett= *p_et;
DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?",db->str,name->str,
ett->m_db.str, ett->m_name.str));
if (name->length == ett->m_name.length &&
db->length == ett->m_db.length &&
0 == strncmp(db->str, ett->m_db.str, db->length) &&
0 == strncmp(name->str, ett->m_name.str, name->length)
ett->dbname.str, ett->name.str));
if (name->length == ett->name.length &&
db->length == ett->dbname.length &&
0 == strncmp(db->str, ett->dbname.str, db->length) &&
0 == strncmp(name->str, ett->name.str, name->length)
)
{
int idx;
......@@ -722,10 +723,10 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
{
event_timed *ett= dynamic_element(&events_array, i, event_timed*);
if (name->length == ett->m_name.length &&
db->length == ett->m_db.length &&
0 == strncmp(db->str, ett->m_db.str, db->length) &&
0 == strncmp(name->str, ett->m_name.str, name->length)
if (name->length == ett->name.length &&
db->length == ett->dbname.length &&
0 == strncmp(db->str, ett->dbname.str, db->length) &&
0 == strncmp(name->str, ett->name.str, name->length)
)
delete_dynamic_element(&events_array, i);
}
......@@ -763,15 +764,15 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
int ret = 0;
DBUG_ENTER("evex_create_event");
DBUG_PRINT("enter", ("name: %*s options:%d", et->m_name.length,
et->m_name.str, create_options));
DBUG_PRINT("enter", ("name: %*s options:%d", et->name.length,
et->name.str, create_options));
if ((ret = db_create_event(thd, et)) == EVEX_WRITE_ROW_FAILED &&
(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
"EVENT", thd->lex->et->m_name.str);
"EVENT", et->name.str);
ret= 0;
goto done;
}
......@@ -785,9 +786,9 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
goto done;
VOID(pthread_mutex_lock(&LOCK_evex_running));
if (evex_is_running && et->m_status == MYSQL_EVENT_ENABLED)
if (evex_is_running && et->status == MYSQL_EVENT_ENABLED)
{
sp_name spn(et->m_db, et->m_name);
sp_name spn(et->dbname, et->name);
ret= evex_load_and_compile_event(thd, &spn, true);
}
VOID(pthread_mutex_unlock(&LOCK_evex_running));
......@@ -804,9 +805,9 @@ done:
SYNOPSIS
evex_update_event()
thd THD
name the real name of the event.
et event's data
thd THD
et event's data
new_name set in case of RENAME TO.
NOTES
et contains data about dbname and event name.
......@@ -815,14 +816,14 @@ done:
*/
int
evex_update_event(THD *thd, sp_name *name, event_timed *et)
evex_update_event(THD *thd, event_timed *et, sp_name *name)
{
int ret, i;
bool need_second_pass= true;
sp_name *spn= 0;
DBUG_ENTER("evex_update_event");
DBUG_PRINT("enter", ("name: %*s", et->m_name.length, et->m_name.str));
DBUG_PRINT("enter", ("name: %*s", et->name.length, et->name.str));
/*
db_update_event() opens & closes the table to prevent
......@@ -836,13 +837,13 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et)
UNLOCK_MUTEX_AND_BAIL_OUT(LOCK_evex_running, done);
VOID(pthread_mutex_lock(&LOCK_event_arrays));
evex_remove_from_cache(&et->m_db, &et->m_name, false);
if (et->m_status == MYSQL_EVENT_ENABLED)
evex_remove_from_cache(&et->dbname, &et->name, false);
if (et->status == MYSQL_EVENT_ENABLED)
if (name)
ret= evex_load_and_compile_event(thd, name, false);
else
{
spn= new sp_name(et->m_db, et->m_name);
spn= new sp_name(et->dbname, et->name);
ret= evex_load_and_compile_event(thd, spn, false);
delete spn;
}
......@@ -884,9 +885,9 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
goto done;
}
if (!(ret= evex_db_find_routine_aux(thd, et->m_db, et->m_name, table)))
if (!(ret= evex_db_find_routine_aux(thd, et->dbname, et->name, table)))
{
if (ret= table->file->delete_row(table->record[0]))
if ((ret= table->file->delete_row(table->record[0])))
{
my_error(ER_EVENT_CANNOT_DELETE, MYF(0));
goto done;
......@@ -896,7 +897,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
"EVENT", thd->lex->et->m_name.str);
"EVENT", et->name.str);
ret= 0;
goto done;
} else
......@@ -904,7 +905,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
VOID(pthread_mutex_lock(&LOCK_evex_running));
if (evex_is_running)
ret= evex_remove_from_cache(&et->m_db, &et->m_name, true);
ret= evex_remove_from_cache(&et->dbname, &et->name, true);
VOID(pthread_mutex_unlock(&LOCK_evex_running));
done:
......
/* Copyright (C) 2000-2003 MySQL AB
/* Copyright (C) 2004-2005 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
......@@ -63,41 +63,45 @@ class event_timed
my_bool running;
pthread_mutex_t LOCK_running;
bool status_changed;
bool last_executed_changed;
TIME last_executed;
public:
LEX_STRING m_db;
LEX_STRING m_name;
LEX_STRING m_body;
LEX_STRING m_definer_user;
LEX_STRING m_definer_host;
LEX_STRING m_definer;// combination of user and host
LEX_STRING m_comment;
TIME m_starts;
TIME m_ends;
TIME m_execute_at;
longlong m_expr;
interval_type m_interval;
longlong m_created;
longlong m_modified;
TIME m_last_executed;
enum enum_event_on_completion m_on_completion;
enum enum_event_status m_status;
sp_head *m_sphead;
const uchar *m_body_begin;
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING body;
LEX_STRING definer_user;
LEX_STRING definer_host;
LEX_STRING definer;// combination of user and host
LEX_STRING comment;
TIME starts;
TIME ends;
TIME execute_at;
longlong expression;
interval_type interval;
longlong created;
longlong modified;
enum enum_event_on_completion on_completion;
enum enum_event_status status;
sp_head *sphead;
const uchar *body_begin;
bool m_dropped;
bool m_free_sphead_on_delete;
uint m_flags;//all kind of purposes
bool m_last_executed_changed;
bool m_status_changed;
event_timed():running(0), m_expr(0), m_created(0), m_modified(0),
m_on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
m_status(MYSQL_EVENT_ENABLED), m_sphead(0), m_dropped(false),
m_free_sphead_on_delete(true), m_flags(0),
m_last_executed_changed(false), m_status_changed(false)
bool dropped;
bool free_sphead_on_delete;
uint flags;//all kind of purposes
event_timed():running(0), status_changed(false), last_executed_changed(false),
expression(0), created(0), modified(0),
on_completion(MYSQL_EVENT_ON_COMPLETION_DROP),
status(MYSQL_EVENT_ENABLED), sphead(0), dropped(false),
free_sphead_on_delete(true), flags(0)
{
pthread_mutex_init(&LOCK_running, MY_MUTEX_INIT_FAST);
init();
......@@ -106,7 +110,7 @@ public:
~event_timed()
{
pthread_mutex_destroy(&LOCK_running);
if (m_free_sphead_on_delete)
if (free_sphead_on_delete)
free_sp();
}
......@@ -120,10 +124,10 @@ public:
init_execute_at(THD *thd, Item *expr);
int
init_interval(THD *thd, Item *expr, interval_type interval);
init_interval(THD *thd, Item *expr, interval_type new_interval);
void
init_name(THD *thd, sp_name *name);
init_name(THD *thd, sp_name *spn);
int
init_starts(THD *thd, Item *starts);
......@@ -135,7 +139,7 @@ public:
event_timed::init_body(THD *thd);
void
init_comment(THD *thd, LEX_STRING *comment);
init_comment(THD *thd, LEX_STRING *set_comment);
int
load_from_row(MEM_ROOT *mem_root, TABLE *table);
......@@ -163,11 +167,8 @@ public:
void free_sp()
{
if (m_sphead)
{
delete m_sphead;
m_sphead= 0;
}
delete sphead;
sphead= 0;
}
};
......@@ -176,7 +177,7 @@ int
evex_create_event(THD *thd, event_timed *et, uint create_options);
int
evex_update_event(THD *thd, sp_name *name, event_timed *et);
evex_update_event(THD *thd, event_timed *et, sp_name *new_name);
int
evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists);
......
/* Copyright (C) 2000-2003 MySQL AB
/* Copyright (C) 2004-2005 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
......@@ -226,7 +226,7 @@ event_executor_main(void *arg)
for (i= 0; (i < evex_executing_queue.elements) && !thd->killed; ++i)
{
event_timed *et= *dynamic_element(&evex_executing_queue,i,event_timed**);
// printf("%llu\n", TIME_to_ulonglong_datetime(&et->m_execute_at));
// printf("%llu\n", TIME_to_ulonglong_datetime(&et->execute_at));
if (!event_executor_running_global_var)
break;
......@@ -236,13 +236,13 @@ event_executor_main(void *arg)
if this is the first event which is after time_now then no
more need to iterate over more elements since the array is sorted.
*/
if (et->m_execute_at.year > 1969 &&
my_time_compare(&time_now, &et->m_execute_at) == -1)
if (et->execute_at.year > 1969 &&
my_time_compare(&time_now, &et->execute_at) == -1)
break;
if (et->m_status == MYSQL_EVENT_ENABLED &&
!check_access(thd, EVENT_ACL, et->m_db.str, 0, 0, 0,
is_schema_db(et->m_db.str)))
if (et->status == MYSQL_EVENT_ENABLED &&
!check_access(thd, EVENT_ACL, et->dbname.str, 0, 0, 0,
is_schema_db(et->dbname.str)))
{
pthread_t th;
......@@ -262,9 +262,9 @@ event_executor_main(void *arg)
thd->proc_info = "Computing next time";
et->compute_next_execution_time();
et->update_fields(thd);
if ((et->m_execute_at.year && !et->m_expr)
|| TIME_to_ulonglong_datetime(&et->m_execute_at) == 0L)
et->m_flags |= EVENT_EXEC_NO_MORE;
if ((et->execute_at.year && !et->expression)
|| TIME_to_ulonglong_datetime(&et->execute_at) == 0L)
et->flags |= EVENT_EXEC_NO_MORE;
}
}
/*
......@@ -275,13 +275,13 @@ event_executor_main(void *arg)
while (j < i && j < evex_executing_queue.elements)
{
event_timed *et= *dynamic_element(&evex_executing_queue, j, event_timed**);
if (et->m_flags & EVENT_EXEC_NO_MORE || et->m_status == MYSQL_EVENT_DISABLED)
if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED)
{
delete_dynamic_element(&evex_executing_queue, j);
DBUG_PRINT("EVEX main thread", ("DELETING FROM EXECUTION QUEUE [%s.%s]",
et->m_db.str, et->m_name.str));
et->dbname.str, et->name.str));
// nulling the position, will delete later
if (et->m_dropped)
if (et->dropped)
{
// we have to drop the event
int idx;
......@@ -311,7 +311,7 @@ err:
evex_is_running= false;
VOID(pthread_mutex_unlock(&LOCK_evex_running));
sql_print_information("Event executor stopping");
sql_print_information("Event scheduler stopping");
/*
TODO: A better will be with a conditional variable
......@@ -334,7 +334,7 @@ err:
// No need to use lock here if EVEX is not running but anyway
delete_dynamic(&evex_executing_queue);
delete_dynamic(&events_array);
VOID(pthread_mutex_unlock(&LOCK_evex_running));
VOID(pthread_mutex_unlock(&LOCK_event_arrays));
thd->proc_info = "Clearing";
DBUG_ASSERT(thd->net.buff != 0);
......@@ -355,7 +355,7 @@ err_no_thd:
VOID(pthread_mutex_unlock(&LOCK_evex_running));
free_root(&evex_mem_root, MYF(0));
sql_print_information("Event executor stopped");
sql_print_information("Event scheduler stopped");
my_thread_end();
pthread_exit(0);
......@@ -381,7 +381,7 @@ event_executor_worker(void *event_void)
if (!(thd = new THD)) // note that contructor of THD uses DBUG_ !
{
sql_print_error("Cannot create a THD structure in worker thread");
sql_print_error("Cannot create a THD structure in a scheduler worker thread");
goto err_no_thd;
}
thd->thread_stack = (char*)&thd; // remember where our stack is
......@@ -406,20 +406,20 @@ event_executor_worker(void *event_void)
// thd->security_ctx->priv_host is char[MAX_HOSTNAME]
strxnmov(thd->security_ctx->priv_host, sizeof(thd->security_ctx->priv_host),
event->m_definer_host.str, NullS);
event->definer_host.str, NullS);
thd->security_ctx->priv_user= event->m_definer_user.str;
thd->security_ctx->priv_user= event->definer_user.str;
thd->db= event->m_db.str;
thd->db= event->dbname.str;
{
char exec_time[200];
int ret;
my_TIME_to_str(&event->m_execute_at, exec_time);
DBUG_PRINT("info", (" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time));
sql_print_information(" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time);
my_TIME_to_str(&event->execute_at, exec_time);
DBUG_PRINT("info", (" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->dbname.str, event->name.str,(int) event->expression, exec_time));
sql_print_information(" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->dbname.str, event->name.str,(int) event->expression, exec_time);
ret= event->execute(thd, &worker_mem_root);
sql_print_information(" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]. RetCode=%d", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time, ret);
DBUG_PRINT("info", (" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->m_db.str, event->m_name.str,(int) event->m_expr, exec_time));
sql_print_information(" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]. RetCode=%d", event->dbname.str, event->name.str,(int) event->expression, exec_time, ret);
DBUG_PRINT("info", (" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]", event->dbname.str, event->name.str,(int) event->expression, exec_time));
}
thd->db= 0;
......@@ -495,19 +495,19 @@ evex_load_events_from_db(THD *thd)
}
DBUG_PRINT("evex_load_events_from_db",
("Event %s loaded from row. Time to compile", et->m_name.str));
("Event %s loaded from row. Time to compile", et->name.str));
if ((ret= et->compile(thd, &evex_mem_root)))
{
sql_print_error("Error while compiling %s.%s. Aborting load.",
et->m_db.str, et->m_name.str);
et->dbname.str, et->name.str);
goto end;
}
// let's find when to be executed
et->compute_next_execution_time();
DBUG_PRINT("evex_load_events_from_db",
("Adding %s to the executor list.", et->m_name.str));
("Adding %s to the executor list.", et->name.str));
VOID(push_dynamic(&events_array,(gptr) et));
/*
We always add at the end so the number of elements - 1 is the place
......@@ -518,7 +518,7 @@ evex_load_events_from_db(THD *thd)
et_copy= dynamic_element(&events_array, events_array.elements - 1,
event_timed*);
VOID(push_dynamic(&evex_executing_queue,(gptr) &et_copy));
et->m_free_sphead_on_delete= false;
et->free_sphead_on_delete= false;
delete et;
}
end_read_record(&read_record_info);
......
/* Copyright (C) 2000-2003 MySQL AB
/* Copyright (C) 2004-2005 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
......
/* Copyright (C) 2000-2003 MySQL AB
/* Copyright (C) 2004-2005 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
......@@ -35,16 +35,16 @@ event_timed::init()
{
DBUG_ENTER("event_timed::init");
m_db.str= m_name.str= m_body.str= m_comment.str= 0;
m_db.length= m_name.length= m_body.length= m_comment.length= 0;
dbname.str= name.str= body.str= comment.str= 0;
dbname.length= name.length= body.length= comment.length= 0;
set_zero_time(&m_starts, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&m_ends, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&m_execute_at, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&m_last_executed, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&starts, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME);
m_definer_user.str= m_definer_host.str= 0;
m_definer_user.length= m_definer_host.length= 0;
definer_user.str= definer_host.str= 0;
definer_user.length= definer_host.length= 0;
DBUG_VOID_RETURN;
}
......@@ -56,11 +56,11 @@ event_timed::init()
SYNOPSIS
event_timed::init_name()
thd THD
name the name extracted in the parser
spn the name extracted in the parser
*/
void
event_timed::init_name(THD *thd, sp_name *name)
event_timed::init_name(THD *thd, sp_name *spn)
{
DBUG_ENTER("event_timed::init_name");
uint n; /* Counter for nul trimming */
......@@ -68,27 +68,27 @@ event_timed::init_name(THD *thd, sp_name *name)
MEM_ROOT *root= thd->mem_root;
/* We have to copy strings to get them into the right memroot */
if (name)
if (spn)
{
m_db.length= name->m_db.length;
if (name->m_db.length == 0)
m_db.str= NULL;
dbname.length= spn->m_db.length;
if (spn->m_db.length == 0)
dbname.str= NULL;
else
m_db.str= strmake_root(root, name->m_db.str, name->m_db.length);
m_name.length= name->m_name.length;
m_name.str= strmake_root(root, name->m_name.str, name->m_name.length);
dbname.str= strmake_root(root, spn->m_db.str, spn->m_db.length);
name.length= spn->m_name.length;
name.str= strmake_root(root, spn->m_name.str, spn->m_name.length);
if (name->m_qname.length == 0)
name->init_qname(thd);
if (spn->m_qname.length == 0)
spn->init_qname(thd);
}
else if (thd->db)
{
m_db.length= thd->db_length;
m_db.str= strmake_root(root, thd->db, m_db.length);
dbname.length= thd->db_length;
dbname.str= strmake_root(root, thd->db, dbname.length);
}
DBUG_PRINT("m_db", ("len=%d db=%s",m_db.length, m_db.str));
DBUG_PRINT("m_name", ("len=%d name=%s",m_name.length, m_name.str));
DBUG_PRINT("dbname", ("len=%d db=%s",dbname.length, dbname.str));
DBUG_PRINT("name", ("len=%d name=%s",name.length, name.str));
DBUG_VOID_RETURN;
}
......@@ -112,12 +112,12 @@ event_timed::init_body(THD *thd)
DBUG_ENTER("event_timed::init_body");
MEM_ROOT *root= thd->mem_root;
m_body.length= thd->lex->ptr - m_body_begin;
body.length= thd->lex->ptr - body_begin;
// Trim nuls at the end
while (m_body.length && m_body_begin[m_body.length-1] == '\0')
m_body.length--;
while (body.length && body_begin[body.length-1] == '\0')
body.length--;
m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
body.str= strmake_root(root, (char *)body_begin, body.length);
DBUG_VOID_RETURN;
}
......@@ -169,7 +169,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd,&ltime, &not_used));
m_execute_at= ltime;
execute_at= ltime;
DBUG_RETURN(0);
}
......@@ -180,7 +180,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
SYNOPSIS
event_timed::init_interval()
expr how much?
interval what is the interval
new_interval what is the interval
RETURNS
0 - OK
......@@ -189,7 +189,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
*/
int
event_timed::init_interval(THD *thd, Item *expr, interval_type interval)
event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
{
longlong tmp;
DBUG_ENTER("event_timed::init_interval");
......@@ -200,8 +200,8 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type interval)
if ((tmp= expr->val_int()) <= 0)
DBUG_RETURN(EVEX_BAD_PARAMS);
m_expr= tmp;
m_interval= interval;
expression= tmp;
interval= new_interval;
DBUG_RETURN(0);
}
......@@ -228,7 +228,7 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type interval)
*/
int
event_timed::init_starts(THD *thd, Item *starts)
event_timed::init_starts(THD *thd, Item *new_starts)
{
my_bool not_used;
TIME ltime;
......@@ -236,22 +236,22 @@ event_timed::init_starts(THD *thd, Item *starts)
DBUG_ENTER("event_timed::init_starts");
if (starts->fix_fields(thd, &starts))
if (new_starts->fix_fields(thd, &new_starts))
DBUG_RETURN(EVEX_PARSE_ERROR);
if (starts->val_int() == MYSQL_TIMESTAMP_ERROR)
if (new_starts->val_int() == MYSQL_TIMESTAMP_ERROR)
DBUG_RETURN(EVEX_BAD_PARAMS);
if ((not_used= starts->get_date(&ltime, TIME_NO_ZERO_DATE)))
if ((not_used= new_starts->get_date(&ltime, TIME_NO_ZERO_DATE)))
DBUG_RETURN(EVEX_BAD_PARAMS);
/*
This may result in a 1970-01-01 date if ltime is > 2037-xx-xx
CONVERT_TZ has similar problem
*/
my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd,&ltime, &not_used));
my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
m_starts= ltime;
starts= ltime;
DBUG_RETURN(0);
}
......@@ -262,7 +262,7 @@ event_timed::init_starts(THD *thd, Item *starts)
SYNOPSIS
event_timed::init_ends()
thd THD
ends when?
new_ends when?
NOTES
Note that activation time is not execution time.
......@@ -279,7 +279,7 @@ event_timed::init_starts(THD *thd, Item *starts)
*/
int
event_timed::init_ends(THD *thd, Item *ends)
event_timed::init_ends(THD *thd, Item *new_ends)
{
TIME ltime;
my_time_t my_time_tmp;
......@@ -287,11 +287,11 @@ event_timed::init_ends(THD *thd, Item *ends)
DBUG_ENTER("event_timed::init_ends");
if (ends->fix_fields(thd, &ends))
if (new_ends->fix_fields(thd, &new_ends))
DBUG_RETURN(EVEX_PARSE_ERROR);
// the field was already fixed in init_ends
if ((not_used= ends->get_date(&ltime, TIME_NO_ZERO_DATE)))
if ((not_used= new_ends->get_date(&ltime, TIME_NO_ZERO_DATE)))
DBUG_RETURN(EVEX_BAD_PARAMS);
/*
......@@ -300,10 +300,10 @@ event_timed::init_ends(THD *thd, Item *ends)
*/
my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
if (m_starts.year && my_time_compare(&m_starts, &ltime) != -1)
if (starts.year && my_time_compare(&starts, &ltime) != -1)
DBUG_RETURN(EVEX_BAD_PARAMS);
m_ends= ltime;
ends= ltime;
DBUG_RETURN(0);
}
......@@ -318,19 +318,19 @@ event_timed::init_ends(THD *thd, Item *ends)
*/
void
event_timed::init_comment(THD *thd, LEX_STRING *comment)
event_timed::init_comment(THD *thd, LEX_STRING *set_comment)
{
DBUG_ENTER("event_timed::init_comment");
m_comment.str= strmake_root(thd->mem_root, comment->str,
m_comment.length= comment->length);
comment.str= strmake_root(thd->mem_root, set_comment->str,
comment.length= set_comment->length);
DBUG_VOID_RETURN;
}
/*
Inits definer (m_definer_user and m_definer_host) during
Inits definer (definer_user and definer_host) during
parsing.
SYNOPSIS
......@@ -342,11 +342,11 @@ event_timed::init_definer(THD *thd)
{
DBUG_ENTER("event_timed::init_definer");
m_definer_user.str= strdup_root(thd->mem_root, thd->security_ctx->priv_user);
m_definer_user.length= strlen(thd->security_ctx->priv_user);
definer_user.str= strdup_root(thd->mem_root, thd->security_ctx->priv_user);
definer_user.length= strlen(thd->security_ctx->priv_user);
m_definer_host.str= strdup_root(thd->mem_root, thd->security_ctx->priv_host);
m_definer_host.length= strlen(thd->security_ctx->priv_host);
definer_host.str= strdup_root(thd->mem_root, thd->security_ctx->priv_host);
definer_host.length= strlen(thd->security_ctx->priv_host);
DBUG_RETURN(0);
}
......@@ -384,68 +384,68 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
if (table->s->fields != EVEX_FIELD_COUNT)
goto error;
if ((et->m_db.str= get_field(mem_root,
if ((et->dbname.str= get_field(mem_root,
table->field[EVEX_FIELD_DB])) == NULL)
goto error;
et->m_db.length= strlen(et->m_db.str);
et->dbname.length= strlen(et->dbname.str);
if ((et->m_name.str= get_field(mem_root,
if ((et->name.str= get_field(mem_root,
table->field[EVEX_FIELD_NAME])) == NULL)
goto error;
et->m_name.length= strlen(et->m_name.str);
et->name.length= strlen(et->name.str);
if ((et->m_body.str= get_field(mem_root,
if ((et->body.str= get_field(mem_root,
table->field[EVEX_FIELD_BODY])) == NULL)
goto error;
et->m_body.length= strlen(et->m_body.str);
et->body.length= strlen(et->body.str);
if ((et->m_definer.str= get_field(mem_root,
if ((et->definer.str= get_field(mem_root,
table->field[EVEX_FIELD_DEFINER])) == NullS)
goto error;
et->m_definer.length= strlen(et->m_definer.str);
et->definer.length= strlen(et->definer.str);
ptr= strchr(et->m_definer.str, '@');
ptr= strchr(et->definer.str, '@');
if (! ptr)
ptr= et->m_definer.str; // Weird, isn't it?
ptr= et->definer.str;
len= ptr - et->m_definer.str;
len= ptr - et->definer.str;
et->m_definer_user.str= strmake_root(mem_root, et->m_definer.str, len);
et->m_definer_user.length= len;
len= et->m_definer.length - len - 1; //1 is because of @
et->m_definer_host.str= strmake_root(mem_root, ptr + 1, len);//1: because of @
et->m_definer_host.length= len;
et->definer_user.str= strmake_root(mem_root, et->definer.str, len);
et->definer_user.length= len;
len= et->definer.length - len - 1; //1 is because of @
et->definer_host.str= strmake_root(mem_root, ptr + 1, len);//1: because of @
et->definer_host.length= len;
res1= table->field[EVEX_FIELD_STARTS]->
get_date(&et->m_starts, TIME_NO_ZERO_DATE);
get_date(&et->starts, TIME_NO_ZERO_DATE);
res2= table->field[EVEX_FIELD_ENDS]->
get_date(&et->m_ends, TIME_NO_ZERO_DATE);
get_date(&et->ends, TIME_NO_ZERO_DATE);
et->m_expr= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int();
et->expression= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int();
/*
If res1 and res2 are true then both fields are empty.
Hence if EVEX_FIELD_EXECUTE_AT is empty there is an error.
*/
if (res1 && res2 && !et->m_expr && table->field[EVEX_FIELD_EXECUTE_AT]->
get_date(&et->m_execute_at, TIME_NO_ZERO_DATE))
if (res1 && res2 && !et->expression && table->field[EVEX_FIELD_EXECUTE_AT]->
get_date(&et->execute_at, TIME_NO_ZERO_DATE))
goto error;
/*
In DB the values start from 1 but enum interval_type starts
from 0
*/
et->m_interval= (interval_type)
et->interval= (interval_type)
((ulonglong) table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->val_int() - 1);
et->m_modified= table->field[EVEX_FIELD_CREATED]->val_int();
et->m_created= table->field[EVEX_FIELD_MODIFIED]->val_int();
et->modified= table->field[EVEX_FIELD_CREATED]->val_int();
et->created= table->field[EVEX_FIELD_MODIFIED]->val_int();
/*
ToDo Andrey : Ask PeterG & Serg what to do in this case.
......@@ -458,25 +458,25 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
is loaded from DB, execution at L_E_AT+15min
will be scheduled. However this time is in the past.
Hence immediate execution. Due to patch of
::mark_last_executed() m_last_executed gets time_now
and not m_execute_at. If not like this a big
::mark_last_executed() last_executed gets time_now
and not execute_at. If not like this a big
queue can be scheduled for times which are still in
the past (2, 3 and more executions which will be
consequent).
*/
set_zero_time(&m_last_executed, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME);
#ifdef ANDREY_0
table->field[EVEX_FIELD_LAST_EXECUTED]->
get_date(&et->m_last_executed, TIME_NO_ZERO_DATE);
get_date(&et->last_executed, TIME_NO_ZERO_DATE);
#endif
m_last_executed_changed= false;
last_executed_changed= false;
// ToDo : Andrey . Find a way not to allocate ptr on event_mem_root
if ((ptr= get_field(mem_root, table->field[EVEX_FIELD_STATUS])) == NullS)
goto error;
DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", et->m_name.str, ptr));
et->m_status= (ptr[0]=='E'? MYSQL_EVENT_ENABLED:
DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", et->name.str, ptr));
et->status= (ptr[0]=='E'? MYSQL_EVENT_ENABLED:
MYSQL_EVENT_DISABLED);
// ToDo : Andrey . Find a way not to allocate ptr on event_mem_root
......@@ -484,14 +484,14 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
table->field[EVEX_FIELD_ON_COMPLETION])) == NullS)
goto error;
et->m_on_completion= (ptr[0]=='D'? MYSQL_EVENT_ON_COMPLETION_DROP:
et->on_completion= (ptr[0]=='D'? MYSQL_EVENT_ON_COMPLETION_DROP:
MYSQL_EVENT_ON_COMPLETION_PRESERVE);
et->m_comment.str= get_field(mem_root, table->field[EVEX_FIELD_COMMENT]);
if (et->m_comment.str != NullS)
et->m_comment.length= strlen(et->m_comment.str);
et->comment.str= get_field(mem_root, table->field[EVEX_FIELD_COMMENT]);
if (et->comment.str != NullS)
et->comment.length= strlen(et->comment.str);
else
et->m_comment.length= 0;
et->comment.length= 0;
DBUG_RETURN(0);
error:
......@@ -499,6 +499,11 @@ error:
}
/*
Note: In the comments this->ends is referenced as m_ends
*/
bool
event_timed::compute_next_execution_time()
{
......@@ -508,179 +513,181 @@ event_timed::compute_next_execution_time()
DBUG_ENTER("event_timed::compute_next_execution_time");
if (m_status == MYSQL_EVENT_DISABLED)
if (status == MYSQL_EVENT_DISABLED)
{
DBUG_PRINT("compute_next_execution_time",
("Event %s is DISABLED", m_name.str));
("Event %s is DISABLED", name.str));
goto ret;
}
//if one-time no need to do computation
if (!m_expr)
if (!expression)
{
//let's check whether it was executed
if (m_last_executed.year)
if (last_executed.year)
{
DBUG_PRINT("compute_next_execution_time",
("One-time event %s was already executed", m_name.str));
if (m_on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
("One-time event %s was already executed", name.str));
if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
{
DBUG_PRINT("compute_next_execution_time",
("One-time event will be dropped."));
m_dropped= true;
dropped= true;
}
m_status= MYSQL_EVENT_DISABLED;
m_status_changed= true;
status= MYSQL_EVENT_DISABLED;
status_changed= true;
}
goto ret;
}
time(&now);
my_tz_UTC->gmt_sec_to_TIME(&time_now, now);
/*
sql_print_information("[%s.%s]", m_db.str, m_name.str);
sql_print_information("[%s.%s]", dbname.str, name.str);
sql_print_information("time_now : [%d-%d-%d %d:%d:%d ]",
time_now.year, time_now.month, time_now.day,
time_now.hour, time_now.minute, time_now.second);
sql_print_information("m_starts : [%d-%d-%d %d:%d:%d ]", m_starts.year,
m_starts.month, m_starts.day, m_starts.hour,
m_starts.minute, m_starts.second);
sql_print_information("m_ends : [%d-%d-%d %d:%d:%d ]", m_ends.year,
m_ends.month, m_ends.day, m_ends.hour,
m_ends.minute, m_ends.second);
sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]", m_last_executed.year,
m_last_executed.month, m_last_executed.day,
m_last_executed.hour, m_last_executed.minute,
m_last_executed.second);
sql_print_information("starts : [%d-%d-%d %d:%d:%d ]", starts.year,
starts.month, starts.day, starts.hour,
starts.minute, starts.second);
sql_print_information("ends : [%d-%d-%d %d:%d:%d ]", ends.year,
ends.month, ends.day, ends.hour,
ends.minute, ends.second);
sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]", last_executed.year,
last_executed.month, last_executed.day,
last_executed.hour, last_executed.minute,
last_executed.second);
*/
//if time_now is after m_ends don't execute anymore
if (m_ends.year && (tmp= my_time_compare(&m_ends, &time_now)) == -1)
//if time_now is after ends don't execute anymore
if (ends.year && (tmp= my_time_compare(&ends, &time_now)) == -1)
{
// time_now is after m_ends. don't execute anymore
set_zero_time(&m_execute_at, MYSQL_TIMESTAMP_DATETIME);
if (m_on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
m_dropped= true;
m_status= MYSQL_EVENT_DISABLED;
m_status_changed= true;
// time_now is after ends. don't execute anymore
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
dropped= true;
status= MYSQL_EVENT_DISABLED;
status_changed= true;
goto ret;
}
/*
Here time_now is before or equals m_ends if the latter is set.
Let's check whether time_now is before m_starts.
If so schedule for m_starts
Here time_now is before or equals ends if the latter is set.
Let's check whether time_now is before starts.
If so schedule for starts
*/
if (m_starts.year && (tmp= my_time_compare(&time_now, &m_starts)) < 1)
if (starts.year && (tmp= my_time_compare(&time_now, &starts)) < 1)
{
if (tmp == 0 && my_time_compare(&m_starts, &m_last_executed) == 0)
if (tmp == 0 && my_time_compare(&starts, &last_executed) == 0)
{
/*
time_now = m_starts = m_last_executed
do nothing or we will schedule for second time execution at m_starts.
time_now = starts = last_executed
do nothing or we will schedule for second time execution at starts.
*/
}
else
{
//m_starts is in the future
//time_now before m_starts. Scheduling for m_starts
m_execute_at= m_starts;
/*
starts is in the future
time_now before starts. Scheduling for starts
*/
execute_at= starts;
goto ret;
}
}
if (m_starts.year && m_ends.year)
if (starts.year && ends.year)
{
/*
Both m_starts and m_ends are set and time_now is between them (incl.)
If m_last_executed is set then increase with m_expr. The new TIME is
after m_ends set m_execute_at to 0. And check for m_on_completion
Both starts and m_ends are set and time_now is between them (incl.)
If last_executed is set then increase with m_expression. The new TIME is
after m_ends set execute_at to 0. And check for on_completion
If not set then schedule for now.
*/
if (!m_last_executed.year)
m_execute_at= time_now;
if (!last_executed.year)
execute_at= time_now;
else
{
my_time_t last, ll_ends;
// There was previous execution
last= sec_since_epoch_TIME(&m_last_executed) + m_expr;
ll_ends= sec_since_epoch_TIME(&m_ends);
last= sec_since_epoch_TIME(&last_executed) + expression;
ll_ends= sec_since_epoch_TIME(&ends);
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
if (ll_ends < last)
{
// Next execution after ends. No more executions
set_zero_time(&m_execute_at, MYSQL_TIMESTAMP_DATETIME);
if (m_on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
m_dropped= true;
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
dropped= true;
}
else
my_tz_UTC->gmt_sec_to_TIME(&m_execute_at, last);
my_tz_UTC->gmt_sec_to_TIME(&execute_at, last);
}
goto ret;
}
else if (!m_starts.year && !m_ends.year)
else if (!starts.year && !ends.year)
{
// both m_starts and m_ends are not set, se we schedule for the next
// based on m_last_executed
if (!m_last_executed.year)
//m_last_executed not set. Schedule the event for now
m_execute_at= time_now;
// both starts and m_ends are not set, se we schedule for the next
// based on last_executed
if (!last_executed.year)
//last_executed not set. Schedule the event for now
execute_at= time_now;
else
//ToDo Andrey: maybe check for error here?
my_tz_UTC->gmt_sec_to_TIME(&m_execute_at,
sec_since_epoch_TIME(&m_last_executed) + m_expr);
my_tz_UTC->gmt_sec_to_TIME(&execute_at,
sec_since_epoch_TIME(&last_executed) + expression);
goto ret;
}
else
{
//either m_starts or m_ends is set
if (m_starts.year)
//either starts or m_ends is set
if (starts.year)
{
/*
- m_starts is set.
- m_starts is not in the future according to check made before
Hence schedule for m_starts + m_expr in case m_last_executed
is not set, otherwise to m_last_executed + m_expr
- starts is set.
- starts is not in the future according to check made before
Hence schedule for starts + m_expression in case last_executed
is not set, otherwise to last_executed + m_expression
*/
my_time_t last;
//convert either m_last_executed or m_starts to seconds
if (m_last_executed.year)
last= sec_since_epoch_TIME(&m_last_executed) + m_expr;
//convert either last_executed or starts to seconds
if (last_executed.year)
last= sec_since_epoch_TIME(&last_executed) + expression;
else
last= sec_since_epoch_TIME(&m_starts);
last= sec_since_epoch_TIME(&starts);
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
my_tz_UTC->gmt_sec_to_TIME(&m_execute_at, last);
my_tz_UTC->gmt_sec_to_TIME(&execute_at, last);
}
else
{
/*
- m_ends is set
- m_ends is after time_now or is equal
Hence check for m_last_execute and increment with m_expr.
If m_last_executed is not set then schedule for now
Hence check for m_last_execute and increment with m_expression.
If last_executed is not set then schedule for now
*/
my_time_t last, ll_ends;
if (!m_last_executed.year)
m_execute_at= time_now;
if (!last_executed.year)
execute_at= time_now;
else
{
last= sec_since_epoch_TIME(&m_last_executed);
ll_ends= sec_since_epoch_TIME(&m_ends);
last+= m_expr;
last= sec_since_epoch_TIME(&last_executed);
ll_ends= sec_since_epoch_TIME(&ends);
last+= expression;
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
if (ll_ends < last)
{
set_zero_time(&m_execute_at, MYSQL_TIMESTAMP_DATETIME);
if (m_on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
m_dropped= true;
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
dropped= true;
}
else
my_tz_UTC->gmt_sec_to_TIME(&m_execute_at, last);
my_tz_UTC->gmt_sec_to_TIME(&execute_at, last);
}
}
goto ret;
......@@ -700,11 +707,11 @@ event_timed::mark_last_executed()
time(&now);
my_tz_UTC->gmt_sec_to_TIME(&time_now, now);
m_last_executed= time_now; // was m_execute_at
last_executed= time_now; // was execute_at
#ifdef ANDREY_0
m_last_executed= m_execute_at;
last_executed= execute_at;
#endif
m_last_executed_changed= true;
last_executed_changed= true;
}
......@@ -724,33 +731,33 @@ event_timed::update_fields(THD *thd)
DBUG_ENTER("event_timed::update_time_fields");
DBUG_PRINT("enter", ("name: %*s", m_name.length, m_name.str));
DBUG_PRINT("enter", ("name: %*s", name.length, name.str));
//no need to update if nothing has changed
if (!(m_status_changed || m_last_executed_changed))
if (!(status_changed || last_executed_changed))
goto done;
if (!(table= evex_open_event_table(thd, TL_WRITE)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
if ((ret= evex_db_find_routine_aux(thd, m_db, m_name, table)))
if ((ret= evex_db_find_routine_aux(thd, dbname, name, table)))
goto done;
store_record(table,record[1]);
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; // Don't update create on row update.
if (m_last_executed_changed)
if (last_executed_changed)
{
table->field[EVEX_FIELD_LAST_EXECUTED]->set_notnull();
table->field[EVEX_FIELD_LAST_EXECUTED]->store_time(&m_last_executed,
table->field[EVEX_FIELD_LAST_EXECUTED]->store_time(&last_executed,
MYSQL_TIMESTAMP_DATETIME);
m_last_executed_changed= false;
last_executed_changed= false;
}
if (m_status_changed)
if (status_changed)
{
table->field[EVEX_FIELD_STATUS]->set_notnull();
table->field[EVEX_FIELD_STATUS]->store((longlong)m_status);
m_status_changed= false;
table->field[EVEX_FIELD_STATUS]->store((longlong)status);
status_changed= false;
}
if ((table->file->update_row(table->record[1],table->record[0])))
......@@ -769,27 +776,27 @@ event_timed::get_show_create_event(THD *thd, uint *length)
char *dst, *ret;
uint len, tmp_len;
len = strlen("CREATE EVENT ") + m_db.length + strlen(".") + m_name.length +
len = strlen("CREATE EVENT ") + dbname.length + strlen(".") + name.length +
strlen(" ON SCHEDULE ") + strlen("EVERY 5 MINUTE ")
/*
+ strlen("ON COMPLETION ")
+ (m_on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
+ (on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
strlen("NOT PRESERVE "):strlen("PRESERVE "))
+ (m_status==MYSQL_EVENT_ENABLED?
+ (status==MYSQL_EVENT_ENABLED?
strlen("ENABLE "):strlen("DISABLE "))
+ strlen("COMMENT \"") + m_comment.length + strlen("\" ")
+ strlen("COMMENT \"") + comment.length + strlen("\" ")
*/
+ strlen("DO ") +
+ m_body.length + strlen(";");
+ body.length + strlen(";");
ret= dst= (char*) alloc_root(thd->mem_root, len);
memcpy(dst, "CREATE EVENT ", tmp_len= strlen("CREATE EVENT "));
dst+= tmp_len;
memcpy(dst, m_db.str, tmp_len=m_db.length);
memcpy(dst, dbname.str, tmp_len=dbname.length);
dst+= tmp_len;
memcpy(dst, ".", tmp_len= strlen("."));
dst+= tmp_len;
memcpy(dst, m_name.str, tmp_len= m_name.length);
memcpy(dst, name.str, tmp_len= name.length);
dst+= tmp_len;
memcpy(dst, " ON SCHEDULE ", tmp_len= strlen(" ON SCHEDULE "));
dst+= tmp_len;
......@@ -798,19 +805,19 @@ event_timed::get_show_create_event(THD *thd, uint *length)
/*
memcpy(dst, "ON COMPLETION ", tmp_len =strlen("ON COMPLETION "));
dst+= tmp_len;
memcpy(dst, (m_on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
memcpy(dst, (on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
"NOT PRESERVE ":"PRESERVE "),
tmp_len =(m_on_completion==MYSQL_EVENT_ON_COMPLETION_DROP? 13:9));
tmp_len =(on_completion==MYSQL_EVENT_ON_COMPLETION_DROP? 13:9));
dst+= tmp_len;
memcpy(dst, (m_status==MYSQL_EVENT_ENABLED?
memcpy(dst, (status==MYSQL_EVENT_ENABLED?
"ENABLE ":"DISABLE "),
tmp_len= (m_status==MYSQL_EVENT_ENABLED? 8:9));
tmp_len= (status==MYSQL_EVENT_ENABLED? 8:9));
dst+=tmp_len;
memcpy(dst, "COMMENT \"", tmp_len= strlen("COMMENT \""));
dst+= tmp_len;
memcpy(dst, m_comment.str, tmp_len= m_comment.length);
memcpy(dst, comment.str, tmp_len= comment.length);
dst+= tmp_len;
memcpy(dst, "\" ", tmp_len=2);
dst+= tmp_len;
......@@ -818,7 +825,7 @@ event_timed::get_show_create_event(THD *thd, uint *length)
memcpy(dst, "DO ", tmp_len=3);
dst+= tmp_len;
memcpy(dst, m_body.str, tmp_len= m_body.length);
memcpy(dst, body.str, tmp_len= body.length);
dst+= tmp_len;
memcpy(dst, ";", 1);
++dst;
......@@ -865,21 +872,21 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
// TODO Andrey : make this as member variable and delete in destructor
empty_item_list.empty();
if (!m_sphead && (ret= compile(thd, mem_root)))
if (!sphead && (ret= compile(thd, mem_root)))
goto done;
ret= m_sphead->execute_procedure(thd, &empty_item_list);
ret= sphead->execute_procedure(thd, &empty_item_list);
VOID(pthread_mutex_lock(&LOCK_running));
running= false;
VOID(pthread_mutex_unlock(&LOCK_running));
done:
// Don't cache m_sphead if allocated on another mem_root
if (mem_root && m_sphead)
// Don't cache sphead if allocated on another mem_root
if (mem_root && sphead)
{
delete m_sphead;
m_sphead= 0;
delete sphead;
sphead= 0;
}
DBUG_RETURN(ret);
......@@ -908,7 +915,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
old_query_len= thd->query_length;
old_query= thd->query;
old_db= thd->db;
thd->db= m_db.str;
thd->db= dbname.str;
thd->query= get_show_create_event(thd, &thd->query_length);
DBUG_PRINT("event_timed::compile", ("query:%s",thd->query));
......@@ -932,13 +939,13 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
DBUG_RETURN(-1);
}
m_sphead= lex.sphead;
m_sphead->m_db= m_db;
sphead= lex.sphead;
sphead->m_db= dbname;
//copy also chistics since they will vanish otherwise we get 0x0 pointer
// Todo : Handle sql_mode !!
m_sphead->set_definer(m_definer.str, m_definer.length);
m_sphead->set_info(0, 0, &lex.sp_chistics, 0/*sql_mode*/);
m_sphead->optimize();
sphead->set_definer(definer.str, definer.length);
sphead->set_info(0, 0, &lex.sp_chistics, 0/*sql_mode*/);
sphead->optimize();
lex_end(&lex);
thd->lex= old_lex;
thd->query= old_query;
......
......@@ -3676,26 +3676,25 @@ end_with_restore_list:
case SQLCOM_CREATE_EVENT:
{
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
if (! lex->et->dbname.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
is_schema_db(lex->et->dbname.str)))
break;
int result;
uint create_options= lex->create_info.options;
res= (result= evex_create_event(thd, lex->et, create_options));
if (result == EVEX_OK)
if (!(res= evex_create_event(thd, lex->et, (uint) lex->create_info.options)))
send_ok(thd, 1);
/* lex->unit.cleanup() is called outside, no need to call it here */
delete lex->et;
lex->et= 0;
delete lex->sphead;
lex->et= 0;
lex->sphead= 0;
break;
......@@ -3703,53 +3702,50 @@ end_with_restore_list:
case SQLCOM_ALTER_EVENT:
{
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
if (! lex->et->dbname.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
is_schema_db(lex->et->dbname.str)))
break;
int result;
res= (result= evex_update_event(thd, lex->spname, lex->et));
res= (result= evex_update_event(thd, lex->et, lex->spname));
switch (result) {
case EVEX_OK:
send_ok(thd, 1);
break;
case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_name.str);
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->name.str);
break;
default:
my_error(ER_EVENT_CANT_ALTER, MYF(0), lex->et->m_name.str);
my_error(ER_EVENT_CANT_ALTER, MYF(0), lex->et->name.str);
break;
}
/* lex->unit.cleanup() is called outside, no need to call it here */
delete lex->et;
delete lex->sphead;
lex->et= 0;
if (lex->sphead)
{
delete lex->sphead;
lex->sphead= 0;
}
lex->sphead= 0;
break;
}
case SQLCOM_DROP_EVENT:
{
DBUG_ASSERT(lex->et);
if (! lex->et->m_db.str)
if (! lex->et->dbname.str)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->et;
lex->et= 0;
goto error;
}
if (check_access(thd, EVENT_ACL, lex->et->m_db.str, 0, 0, 0,
is_schema_db(lex->et->m_db.str)))
if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
is_schema_db(lex->et->dbname.str)))
break;
int result;
......@@ -3759,10 +3755,10 @@ end_with_restore_list:
send_ok(thd, 1);
break;
case EVEX_KEY_NOT_FOUND:
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->m_name.str);
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), lex->et->name.str);
break;
default:
my_error(ER_EVENT_DROP_FAILED, MYF(0), lex->et->m_name.str);
my_error(ER_EVENT_DROP_FAILED, MYF(0), lex->et->name.str);
break;
}
delete lex->et;
......
......@@ -1415,14 +1415,14 @@ ev_status: /* empty */
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->m_status= MYSQL_EVENT_ENABLED;
lex->et->status= MYSQL_EVENT_ENABLED;
}
| DISABLE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->m_status= MYSQL_EVENT_DISABLED;
lex->et->status= MYSQL_EVENT_DISABLED;
}
;
ev_starts: /* empty */
......@@ -1457,13 +1457,13 @@ ev_on_completion: /* empty */
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->m_on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
}
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->m_on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
}
;
ev_comment: /* empty */
......@@ -1497,7 +1497,7 @@ ev_sql_stmt:
lex->sphead->m_body_begin= lex->ptr;
if (!lex->et_compile_phase)
lex->et->m_body_begin= lex->ptr;
lex->et->body_begin= lex->ptr;
}
ev_sql_stmt_inner
{
......
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