Commit 06dd9764 authored by unknown's avatar unknown
Browse files

fix for bug 16408 (Events: crash for an event in a procedure)

(one patch)


mysql-test/r/events_bugs.result:
  fix for bug 16408
mysql-test/t/events_bugs.test:
  fix for bug 16408
sql/event.h:
  fix for bug 16408
sql/event_timed.cc:
  fix for bug 16408
sql/sql_parse.cc:
  fix for bug 16408
sql/sql_yacc.yy:
  fix for bug 16408
parent 28109fed
Loading
Loading
Loading
Loading
+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;
+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
#
+43 −5
Original line number Diff line number Diff line
@@ -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
@@ -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),
@@ -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);

+4 −3
Original line number Diff line number Diff line
@@ -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);
}


@@ -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"));

+13 −6
Original line number Diff line number Diff line
@@ -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:
@@ -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;
          }
	}
@@ -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