Commit 1c5573a4 authored by unknown's avatar unknown

WL #1034 update

- handle better non-latin1 identifiers


sql/event.cc:
  - introduce a wrapper to compare easily and correctly
  LEX_STRINGs
  - remove few unneeded variables
  - remove need_second_pass by restructuring the code. this brings
    performance boost because the code bails out from the loop once
    it hits what it looks for
  - handle ALTER EVENT name RENAME TO name  (throw an error message).
sql/event_executor.cc:
  - comment about DBUG_FAULTY_THR
  - indent fix
sql/event_timed.cc:
  - fix a problem when event name is not latin1. a cyrillic event name
    was crashing the parser so the I emulate SET NAMES utf8. The data is
    already in utf8, being loaded from the disk.
sql/share/errmsg.txt:
  add new error message
parent c1cb8db8
...@@ -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,12 +481,21 @@ db_update_event(THD *thd, event_timed *et, sp_name *new_name) ...@@ -472,12 +481,21 @@ 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)) {
if (!sortcmp_lex_string(et->name, new_name->m_name, system_charset_info) &&
!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); my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str);
goto err; 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
because you will get error 120 from table handler because new_name will because you will get error 120 from table handler because new_name will
...@@ -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) && int idx= get_index_dynamic(&events_array, (gptr) et);
0 == strncmp(name->str, ett->name.str, name->length)
)
{
int idx;
//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, ett, &events_array, evex_executing_queue.elements, et, &events_array,
events_array.elements, events_array.buffer, p_et, ett)); events_array.elements, events_array.buffer, et));
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,19 +744,20 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock) ...@@ -733,19 +744,20 @@ 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 *ett= dynamic_element(&events_array, i, event_timed*); event_timed *et= dynamic_element(&events_array, i, event_timed*);
if (name->length == ett->name.length && if (!sortcmp_lex_string(*name, et->name, system_charset_info) &&
db->length == ett->dbname.length && !sortcmp_lex_string(*db, et->dbname, system_charset_info))
0 == strncmp(db->str, ett->dbname.str, db->length) && {
0 == strncmp(name->str, ett->name.str, name->length)
)
delete_dynamic_element(&events_array, i); delete_dynamic_element(&events_array, i);
break;
}
} }
done: done:
......
...@@ -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;
......
...@@ -904,6 +904,7 @@ done: ...@@ -904,6 +904,7 @@ done:
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