Commit 56db09cf authored by andrey@lmy004's avatar andrey@lmy004

WL #1034 update

- handle better non-latin1 identifiers
parent 0797be8a
...@@ -89,6 +89,15 @@ MEM_ROOT evex_mem_root; ...@@ -89,6 +89,15 @@ MEM_ROOT evex_mem_root;
a < b -> -1 a < b -> -1
*/ */
static
int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
{
return cs->coll->strnncollsp(cs,
(unsigned char *) s.str,s.length,
(unsigned char *) t.str,t.length, 0);
}
inline int inline int
my_time_compare(TIME *a, TIME *b) my_time_compare(TIME *a, TIME *b)
{ {
...@@ -472,11 +481,20 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name) ...@@ -472,11 +481,20 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name)
} }
// first look whether we overwrite // first look whether we overwrite
if (new_name && !evex_db_find_event_aux(thd, new_name->m_db, new_name->m_name, if (new_name)
table))
{ {
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str); if (!sortcmp_lex_string(et->name, new_name->m_name, system_charset_info) &&
goto err; !sortcmp_lex_string(et->dbname, new_name->m_db, system_charset_info))
{
my_error(ER_EVENT_SAME_NAME, MYF(0), et->name.str);
goto err;
}
if (!evex_db_find_event_aux(thd, new_name->m_db, new_name->m_name, table))
{
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str);
goto err;
}
} }
/* /*
...and then whether there is such an event. don't exchange the blocks ...and then whether there is such an event. don't exchange the blocks
...@@ -676,7 +694,6 @@ static int ...@@ -676,7 +694,6 @@ static int
evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock) evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
{ {
uint i; uint i;
bool need_second_pass= true;
DBUG_ENTER("evex_remove_from_cache"); DBUG_ENTER("evex_remove_from_cache");
/* /*
...@@ -689,37 +706,31 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock) ...@@ -689,37 +706,31 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
for (i= 0; i < evex_executing_queue.elements; ++i) for (i= 0; i < evex_executing_queue.elements; ++i)
{ {
event_timed **p_et= dynamic_element(&evex_executing_queue, i, event_timed**); event_timed *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, et->dbname.str,
DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?",db->str,name->str, et->name.str));
ett->dbname.str, ett->name.str)); if (!sortcmp_lex_string(*name, et->name, system_charset_info) &&
if (name->length == ett->name.length && !sortcmp_lex_string(*db, et->dbname, system_charset_info))
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; int idx= get_index_dynamic(&events_array, (gptr) et);
//we are lucky the event is in the executing queue, no need of second pass //we are lucky the event is in the executing queue, no need of second pass
need_second_pass= false;
idx= get_index_dynamic(&events_array, (gptr) ett);
if (idx == -1) if (idx == -1)
{ {
//this should never happen //this should never happen
DBUG_PRINT("error", (" get_index_dynamic problem. %d." DBUG_PRINT("error", (" get_index_dynamic problem. %d."
"i=%d idx=%d evex_ex_queue.buf=%p evex_ex_queue.elements=%d ett=%p\n" "i=%d idx=%d evex_ex_queue.buf=%p evex_ex_queue.elements=%d et=%p\n"
"events_array=%p events_array.elements=%d events_array.buf=%p\n" "events_array=%p events_array.elements=%d events_array.buf=%p et=%p\n",
"p_et=%p ett=%p", __LINE__, i, idx, &evex_executing_queue.buffer,
__LINE__, i, idx, &evex_executing_queue.buffer, evex_executing_queue.elements, et, &events_array,
evex_executing_queue.elements, ett, &events_array, events_array.elements, events_array.buffer, et));
events_array.elements, events_array.buffer, p_et, ett));
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
//destruct first and then remove. the destructor will delete sp_head //destruct first and then remove. the destructor will delete sp_head
ett->free_sp(); et->free_sp();
delete_dynamic_element(&events_array, idx); delete_dynamic_element(&events_array, idx);
delete_dynamic_element(&evex_executing_queue, i); delete_dynamic_element(&evex_executing_queue, i);
// ok, we have cleaned // ok, we have cleaned
goto done;
} }
} }
...@@ -733,20 +744,21 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock) ...@@ -733,20 +744,21 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
For instance, second_pass is needed when an event For instance, second_pass is needed when an event
was created as DISABLED but then altered as ENABLED. was created as DISABLED but then altered as ENABLED.
*/ */
if (need_second_pass) /*
//we haven't found the event in the executing queue. This is nice! :) we haven't found the event in the executing queue. This is nice! :)
//Look for it in the events_array. Look for it in the events_array.
for (i= 0; i < events_array.elements; ++i) */
for (i= 0; i < events_array.elements; ++i)
{
event_timed *et= dynamic_element(&events_array, i, event_timed*);
if (!sortcmp_lex_string(*name, et->name, system_charset_info) &&
!sortcmp_lex_string(*db, et->dbname, system_charset_info))
{ {
event_timed *ett= dynamic_element(&events_array, i, event_timed*); delete_dynamic_element(&events_array, i);
break;
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);
}
done: done:
if (use_lock) if (use_lock)
......
...@@ -19,6 +19,15 @@ ...@@ -19,6 +19,15 @@
#include "event_priv.h" #include "event_priv.h"
#include "sp.h" #include "sp.h"
/*
Make this define DBUG_FAULTY_THR to be able to put breakpoints inside
code used by the scheduler's thread(s). In this case user connections
are not possible because the scheduler thread code is ran inside the
main thread (no spawning takes place. If you want to debug client
connection then start with --one-thread and make the define
DBUG_FAULTY_THR2 !
*/
#define DBUG_FAULTY_THR2 #define DBUG_FAULTY_THR2
extern ulong thread_created; extern ulong thread_created;
...@@ -204,7 +213,7 @@ event_executor_main(void *arg) ...@@ -204,7 +213,7 @@ event_executor_main(void *arg)
VOID(pthread_mutex_unlock(&LOCK_evex_running)); VOID(pthread_mutex_unlock(&LOCK_evex_running));
if (evex_load_events_from_db(thd)) if (evex_load_events_from_db(thd))
goto err; goto err;
THD_CHECK_SENTRY(thd); THD_CHECK_SENTRY(thd);
/* Read queries from the IO/THREAD until this thread is killed */ /* Read queries from the IO/THREAD until this thread is killed */
......
...@@ -904,6 +904,7 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root) ...@@ -904,6 +904,7 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
int int
event_timed::compile(THD *thd, MEM_ROOT *mem_root) event_timed::compile(THD *thd, MEM_ROOT *mem_root)
{ {
int ret= 0;
MEM_ROOT *tmp_mem_root= 0; MEM_ROOT *tmp_mem_root= 0;
LEX *old_lex= thd->lex, lex; LEX *old_lex= thd->lex, lex;
char *old_db; char *old_db;
...@@ -912,6 +913,19 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) ...@@ -912,6 +913,19 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
char *old_query; char *old_query;
uint old_query_len; uint old_query_len;
st_sp_chistics *p; st_sp_chistics *p;
CHARSET_INFO *old_character_set_client, *old_collation_connection,
*old_character_set_results;
old_character_set_client= thd->variables.character_set_client;
old_character_set_results= thd->variables.character_set_results;
old_collation_connection= thd->variables.collation_connection;
thd->variables.character_set_client=
thd->variables.character_set_results=
thd->variables.collation_connection=
get_charset_by_csname("utf8", MY_CS_PRIMARY, MYF(MY_WME));
thd->update_charset();
DBUG_ENTER("event_timed::compile"); DBUG_ENTER("event_timed::compile");
// change the memory root for the execution time // change the memory root for the execution time
...@@ -944,7 +958,9 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) ...@@ -944,7 +958,9 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
// QQ: anything else ? // QQ: anything else ?
lex_end(&lex); lex_end(&lex);
thd->lex= old_lex; thd->lex= old_lex;
DBUG_RETURN(EVEX_COMPILE_ERROR);
ret= EVEX_COMPILE_ERROR;
goto done;
} }
sphead= lex.sphead; sphead= lex.sphead;
...@@ -954,17 +970,25 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root) ...@@ -954,17 +970,25 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
sphead->set_definer(definer.str, definer.length); sphead->set_definer(definer.str, definer.length);
sphead->set_info(0, 0, &lex.sp_chistics, 0/*sql_mode*/); sphead->set_info(0, 0, &lex.sp_chistics, 0/*sql_mode*/);
sphead->optimize(); sphead->optimize();
ret= 0;
done:
lex_end(&lex); lex_end(&lex);
thd->lex= old_lex; thd->lex= old_lex;
thd->query= old_query; thd->query= old_query;
thd->query_length= old_query_len; thd->query_length= old_query_len;
thd->db= old_db; thd->db= old_db;
thd->variables.character_set_client= old_character_set_client;
thd->variables.character_set_results= old_character_set_results;
thd->variables.collation_connection= old_collation_connection;
thd->update_charset();
/* /*
Change the memory root for the execution time. Change the memory root for the execution time.
*/ */
if (mem_root) if (mem_root)
thd->mem_root= tmp_mem_root; thd->mem_root= tmp_mem_root;
DBUG_RETURN(0); DBUG_RETURN(ret);
} }
...@@ -5749,3 +5749,5 @@ ER_EVENT_CANNOT_DELETE ...@@ -5749,3 +5749,5 @@ ER_EVENT_CANNOT_DELETE
eng "Failed to delete the event from mysql.event" eng "Failed to delete the event from mysql.event"
ER_EVENT_COMPILE_ERROR ER_EVENT_COMPILE_ERROR
eng "Error during compilation of event's body" eng "Error during compilation of event's body"
ER_EVENT_SAME_NAME
eng "Same old and new event name"
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