Loading mysql-test/r/events_bugs.result +14 −0 Original line number Diff line number Diff line create database if not exists events_test; use events_test; set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; call p_16(); "Here we used to crash!" call p_16(); ERROR HY000: Event 'e_16' already exists call p_16(); ERROR HY000: Event 'e_16' already exists DROP EVENT e_16; CALL p_16(); CALL p_16(); ERROR HY000: Event 'e_16' already exists DROP PROCEDURE p_16; DROP EVENT e_16; set global event_scheduler=0; "Wait a bit to settle down" delete from mysql.event; Loading mysql-test/t/events_bugs.test +21 −0 Original line number Diff line number Diff line create database if not exists events_test; use events_test; # # START - BUG#16408: Events: crash for an event in a procedure # set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; call p_16(); --echo "Here we used to crash!" --error 1516 call p_16(); --error 1516 call p_16(); DROP EVENT e_16; CALL p_16(); --error 1516 CALL p_16(); DROP PROCEDURE p_16; DROP EVENT e_16; # # END - BUG#16408: Events: crash for an event in a procedure # # # Start - 16407: Events: Changes in sql_mode won't be taken into account # Loading sql/event.h +43 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #define EVENT_EXEC_NO_MORE (1L << 0) #define EVENT_NOT_USED (1L << 1) extern ulong opt_event_executor; enum enum_event_on_completion Loading Loading @@ -122,6 +121,39 @@ class Event_timed bool free_sphead_on_delete; uint flags;//all kind of purposes static void *operator new(size_t size) { void *p; DBUG_ENTER("Event_timed::new(size)"); p= my_malloc(size, MYF(0)); DBUG_PRINT("info", ("alloc_ptr=0x%lx", p)); DBUG_RETURN(p); } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr, size_t size) { DBUG_ENTER("Event_timed::delete(ptr,size)"); DBUG_PRINT("enter", ("free_ptr=0x%lx", ptr)); TRASH(ptr, size); my_free((gptr) ptr, MYF(0)); DBUG_VOID_RETURN; } static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Don't free the memory it will be done by the mem_root but we need to call the destructor because we free other resources which are not allocated on the root but on the heap, or we deinit mutexes. */ DBUG_ASSERT(0); } Event_timed():in_spawned_thread(0),locked_by_thread_id(0), running(0), status_changed(false), last_executed_changed(false), expression(0), created(0), Loading @@ -137,15 +169,21 @@ class Event_timed ~Event_timed() { pthread_mutex_destroy(&this->LOCK_running); deinit_mutexes(); if (free_sphead_on_delete) free_sp(); } void init(); void deinit_mutexes() { pthread_mutex_destroy(&this->LOCK_running); } int init_definer(THD *thd); Loading sql/event_timed.cc +4 −3 Original line number Diff line number Diff line Loading @@ -1228,12 +1228,12 @@ Event_timed::change_security_context(THD *thd, Security_context *s_ctx, definer_host.str, dbname.str)) { my_error(ER_NO_SUCH_USER, MYF(0), definer_user.str, definer_host.str); DBUG_RETURN(TRUE); DBUG_RETURN(true); } *backup= thd->security_ctx; thd->security_ctx= s_ctx; #endif DBUG_RETURN(FALSE); DBUG_RETURN(false); } Loading Loading @@ -1368,7 +1368,8 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root) ret= 0; done: lex.et->free_sphead_on_delete= false; delete lex.et; lex.et->deinit_mutexes(); lex_end(&lex); DBUG_PRINT("note", ("return old data on its place. set back NAMES")); Loading sql/sql_parse.cc +13 −6 Original line number Diff line number Diff line Loading @@ -3804,9 +3804,13 @@ mysql_execute_command(THD *thd) /* lex->unit.cleanup() is called outside, no need to call it here */ } while (0); if (!thd->spcont) { lex->et->free_sphead_on_delete= true; delete lex->et; lex->et= 0; lex->et->free_sp(); lex->et->deinit_mutexes(); } break; } case SQLCOM_SHOW_CREATE_EVENT: Loading Loading @@ -5845,7 +5849,9 @@ void mysql_parse(THD *thd, char *inBuf, uint length) if (thd->lex->et) { thd->lex->et->free_sphead_on_delete= true; delete thd->lex->et; /* alloced on thd->mem_root so no real memory free but dtor call */ thd->lex->et->free_sp(); thd->lex->et->deinit_mutexes(); thd->lex->et= NULL; } } Loading Loading @@ -5886,7 +5892,8 @@ void mysql_parse(THD *thd, char *inBuf, uint length) if (thd->lex->et) { thd->lex->et->free_sphead_on_delete= true; delete thd->lex->et; lex->et->free_sp(); lex->et->deinit_mutexes(); thd->lex->et= NULL; } } Loading Loading
mysql-test/r/events_bugs.result +14 −0 Original line number Diff line number Diff line create database if not exists events_test; use events_test; set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; call p_16(); "Here we used to crash!" call p_16(); ERROR HY000: Event 'e_16' already exists call p_16(); ERROR HY000: Event 'e_16' already exists DROP EVENT e_16; CALL p_16(); CALL p_16(); ERROR HY000: Event 'e_16' already exists DROP PROCEDURE p_16; DROP EVENT e_16; set global event_scheduler=0; "Wait a bit to settle down" delete from mysql.event; Loading
mysql-test/t/events_bugs.test +21 −0 Original line number Diff line number Diff line create database if not exists events_test; use events_test; # # START - BUG#16408: Events: crash for an event in a procedure # set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; call p_16(); --echo "Here we used to crash!" --error 1516 call p_16(); --error 1516 call p_16(); DROP EVENT e_16; CALL p_16(); --error 1516 CALL p_16(); DROP PROCEDURE p_16; DROP EVENT e_16; # # END - BUG#16408: Events: crash for an event in a procedure # # # Start - 16407: Events: Changes in sql_mode won't be taken into account # Loading
sql/event.h +43 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ #define EVENT_EXEC_NO_MORE (1L << 0) #define EVENT_NOT_USED (1L << 1) extern ulong opt_event_executor; enum enum_event_on_completion Loading Loading @@ -122,6 +121,39 @@ class Event_timed bool free_sphead_on_delete; uint flags;//all kind of purposes static void *operator new(size_t size) { void *p; DBUG_ENTER("Event_timed::new(size)"); p= my_malloc(size, MYF(0)); DBUG_PRINT("info", ("alloc_ptr=0x%lx", p)); DBUG_RETURN(p); } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr, size_t size) { DBUG_ENTER("Event_timed::delete(ptr,size)"); DBUG_PRINT("enter", ("free_ptr=0x%lx", ptr)); TRASH(ptr, size); my_free((gptr) ptr, MYF(0)); DBUG_VOID_RETURN; } static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Don't free the memory it will be done by the mem_root but we need to call the destructor because we free other resources which are not allocated on the root but on the heap, or we deinit mutexes. */ DBUG_ASSERT(0); } Event_timed():in_spawned_thread(0),locked_by_thread_id(0), running(0), status_changed(false), last_executed_changed(false), expression(0), created(0), Loading @@ -137,15 +169,21 @@ class Event_timed ~Event_timed() { pthread_mutex_destroy(&this->LOCK_running); deinit_mutexes(); if (free_sphead_on_delete) free_sp(); } void init(); void deinit_mutexes() { pthread_mutex_destroy(&this->LOCK_running); } int init_definer(THD *thd); Loading
sql/event_timed.cc +4 −3 Original line number Diff line number Diff line Loading @@ -1228,12 +1228,12 @@ Event_timed::change_security_context(THD *thd, Security_context *s_ctx, definer_host.str, dbname.str)) { my_error(ER_NO_SUCH_USER, MYF(0), definer_user.str, definer_host.str); DBUG_RETURN(TRUE); DBUG_RETURN(true); } *backup= thd->security_ctx; thd->security_ctx= s_ctx; #endif DBUG_RETURN(FALSE); DBUG_RETURN(false); } Loading Loading @@ -1368,7 +1368,8 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root) ret= 0; done: lex.et->free_sphead_on_delete= false; delete lex.et; lex.et->deinit_mutexes(); lex_end(&lex); DBUG_PRINT("note", ("return old data on its place. set back NAMES")); Loading
sql/sql_parse.cc +13 −6 Original line number Diff line number Diff line Loading @@ -3804,9 +3804,13 @@ mysql_execute_command(THD *thd) /* lex->unit.cleanup() is called outside, no need to call it here */ } while (0); if (!thd->spcont) { lex->et->free_sphead_on_delete= true; delete lex->et; lex->et= 0; lex->et->free_sp(); lex->et->deinit_mutexes(); } break; } case SQLCOM_SHOW_CREATE_EVENT: Loading Loading @@ -5845,7 +5849,9 @@ void mysql_parse(THD *thd, char *inBuf, uint length) if (thd->lex->et) { thd->lex->et->free_sphead_on_delete= true; delete thd->lex->et; /* alloced on thd->mem_root so no real memory free but dtor call */ thd->lex->et->free_sp(); thd->lex->et->deinit_mutexes(); thd->lex->et= NULL; } } Loading Loading @@ -5886,7 +5892,8 @@ void mysql_parse(THD *thd, char *inBuf, uint length) if (thd->lex->et) { thd->lex->et->free_sphead_on_delete= true; delete thd->lex->et; lex->et->free_sp(); lex->et->deinit_mutexes(); thd->lex->et= NULL; } } Loading