Commit 9fa9378b authored by unknown's avatar unknown
Browse files

WL#3337 (Events new architecture)

This cut No 7 should finish the part of fixing the parsing of the events :
- Event_timed is no more used during parsing. Less problems because it has
  a mutex. Event_parse_data class is used during parsing. It is suited only
  for this purpose. It's pretty lightweight
- Late checking of data from parsing is being performed. This should solve
  the problems of nested events in SP or other events (for the situation 
  of no nested bodies). Before if an ALTER EVENT was in a SP, then when the
  SP was compiled, and not executed, the actual init_xxx methods of Event_timed
  were called, which is wrong.
- It could be a side effect of using a specialized class, but test events_stress is
  now 25% quicker.

Cut No8 will start splitting Event_scheduler into 2 parts, the QUEUE will be moved
to Event_queue.


mysql-test/r/events.result:
  update result
mysql-test/t/events.test:
  disabled is actually wrong, should be disable, but because of the early
  checking it was never parsed.
sql/event_data_objects.cc:
  move add init_xxx methods from Event_timed to Event_parse_data
  Event_parse data does not need definer_user and definer_host
  in Event_timed::compile() do not use lex.et, well there is no more lex.et :)
sql/event_data_objects.h:
  move parsing responsibilities from Event_timed to Event_parse_data
sql/event_db_repository.cc:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/event_db_repository.h:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/event_scheduler.cc:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/event_scheduler.h:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/events.cc:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/events.h:
  No more Event_timed comes from parsing but Event_parse_data
  The initialization of Item*-s from parsing is done late, and not
  during the actual parsing. This is the right way to go because
  if an ALTER EVENT is inside a SP or CREATE EVENT it should not be
  executed (initialized) during parsing, as it was done.
sql/sql_lex.cc:
  lex->et_compile_phase and lex->et are no more.
  Use lex->event_parse_data
sql/sql_lex.h:
  lex->et_compile_phase and lex->et are no more.
  Use lex->event_parse_data
sql/sql_parse.cc:
  lex->et_compile_phase and lex->et are no more.
  Use lex->event_parse_data
  ACL checks were moved inside the Events subsystem.
  Also ending of the transaction is performed only just
  before doing disk operation. Therefore only when needed.
sql/sql_yacc.yy:
  lex->et and lex->et_parse_phase are no more
  Use the specialized for parsing Event_parse_data
parent 739ea377
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -297,9 +297,9 @@ select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_comp
db	name	body	definer	convert_tz(execute_at, 'UTC', 'SYSTEM')	on_completion
events_test	e_26	set @a = 5	root@localhost	2017-01-01 00:00:00	DROP
drop event e_26;
create event e_26 on schedule at NULL disabled do set @a = 5;
create event e_26 on schedule at NULL disable do set @a = 5;
ERROR HY000: Incorrect AT value: 'NULL'
create event e_26 on schedule at 'definitely not a datetime' disabled do set @a = 5;
create event e_26 on schedule at 'definitely not a datetime' disable do set @a = 5;
ERROR HY000: Incorrect AT value: 'definitely not a datetime'
set names utf8;
create event задачка on schedule every 123 minute starts now() ends now() + interval 1 month do select 1;
+2 −2
Original line number Diff line number Diff line
@@ -255,9 +255,9 @@ create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
drop event e_26;
--error ER_WRONG_VALUE
create event e_26 on schedule at NULL disabled do set @a = 5;
create event e_26 on schedule at NULL disable do set @a = 5;
--error ER_WRONG_VALUE
create event e_26 on schedule at 'definitely not a datetime' disabled do set @a = 5;
create event e_26 on schedule at 'definitely not a datetime' disable do set @a = 5;

set names utf8;
create event задаÑка on schedule every 123 minute starts now() ends now() + interval 1 month do select 1;
+166 −385
Original line number Diff line number Diff line
@@ -35,186 +35,18 @@ Event_parse_data::new_instance(THD *thd)
Event_parse_data::Event_parse_data()
{
  item_execute_at= item_expression= item_starts= item_ends= NULL;
}


/*
  Set body of the event - what should be executed.

  SYNOPSIS
    Event_timed::init_body()
      thd   THD

  NOTE
    The body is extracted by copying all data between the
    start of the body set by another method and the current pointer in Lex.
 
    Some questionable removal of characters is done in here, and that part
    should be refactored when the parser is smarter.
*/

void
Event_parse_data::init_body(THD *thd)
{
  DBUG_ENTER("Event_parse_data::init_body");
  DBUG_PRINT("info", ("body=[%s] body_begin=0x%ld end=0x%ld", body_begin,
             body_begin, thd->lex->ptr));

  body.length= thd->lex->ptr - body_begin;
  const uchar *body_end= body_begin + body.length - 1;

  /* Trim nuls or close-comments ('*'+'/') or spaces at the end */
  while (body_begin < body_end)
  {

    if ((*body_end == '\0') || 
        (my_isspace(thd->variables.character_set_client, *body_end)))
    { /* consume NULs and meaningless whitespace */
      --body.length;
      --body_end;
      continue;
    }

    /*  
       consume closing comments

       This is arguably wrong, but it's the best we have until the parser is
       changed to be smarter.   FIXME PARSER 

       See also the sp_head code, where something like this is done also.

       One idea is to keep in the lexer structure the count of the number of
       open-comments we've entered, and scan left-to-right looking for a
       closing comment IFF the count is greater than zero.

       Another idea is to remove the closing comment-characters wholly in the
       parser, since that's where it "removes" the opening characters.
    */
    if ((*(body_end - 1) == '*') && (*body_end == '/'))
    {
      DBUG_PRINT("info", ("consumend one '*" "/' comment in the query '%s'", 
          body_begin));
      body.length-= 2;
      body_end-= 2;
      continue;
    }

    break;  /* none were found, so we have excised all we can. */
  }

  /* the first is always whitespace which I cannot skip in the parser */
  while (my_isspace(thd->variables.character_set_client, *body_begin))
  {
    ++body_begin;
    --body.length;
  }
  body.str= thd->strmake((char *)body_begin, body.length);

  DBUG_VOID_RETURN;
}


/*
  Constructor

  SYNOPSIS
    Event_timed::Event_timed()
*/

Event_timed::Event_timed():in_spawned_thread(0),locked_by_thread_id(0),
                           running(0), thread_id(0), status_changed(false),
                           last_executed_changed(false), expression(0),
                           created(0), modified(0),
                           on_completion(Event_timed::ON_COMPLETION_DROP),
                           status(Event_timed::ENABLED), sphead(0),
                           sql_mode(0), body_begin(0), dropped(false),
                           free_sphead_on_delete(true), flags(0)
                
{
  pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
  pthread_cond_init(&this->COND_finished, NULL);
  init();
}


/*
  Destructor

  SYNOPSIS
    Event_timed::~Event_timed()
*/

Event_timed::~Event_timed()
{    
  deinit_mutexes();

  if (free_sphead_on_delete)
    free_sp();
}


/*
  Destructor

  SYNOPSIS
    Event_timed::~deinit_mutexes()
*/

void
Event_timed::deinit_mutexes()
{
  pthread_mutex_destroy(&this->LOCK_running);
  pthread_cond_destroy(&this->COND_finished);
}


/*
  Checks whether the event is running

  SYNOPSIS
    Event_timed::is_running()
*/

bool
Event_timed::is_running()
{
  bool ret;

  VOID(pthread_mutex_lock(&this->LOCK_running));
  ret= running;
  VOID(pthread_mutex_unlock(&this->LOCK_running));

  return ret;
}


/*
  Init all member variables

  SYNOPSIS
    Event_timed::init()
*/

void
Event_timed::init()
{
  DBUG_ENTER("Event_timed::init");

  dbname.str= name.str= body.str= comment.str= 0;
  dbname.length= name.length= body.length= comment.length= 0;
  status= ENABLED;
  on_completion= ON_COMPLETION_DROP;
  expression= 0;

  /* Actually in the parser STARTS is always set */
  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);
  starts_null= ends_null= execute_at_null= TRUE;

  definer_user.str= definer_host.str= 0;
  definer_user.length= definer_host.length= 0;

  sql_mode= 0;

  DBUG_VOID_RETURN;
  body.str= comment.str= 0;
  body.length= comment.length= 0;
}


@@ -222,37 +54,25 @@ Event_timed::init()
  Set a name of the event

  SYNOPSIS
    Event_timed::init_name()
    Event_parse_data::init_name()
      thd   THD
      spn   the name extracted in the parser
*/

void
Event_timed::init_name(THD *thd, sp_name *spn)
Event_parse_data::init_name(THD *thd, sp_name *spn)
{
  DBUG_ENTER("Event_timed::init_name");
  /* During parsing, we must use thd->mem_root */
  MEM_ROOT *root= thd->mem_root;
  DBUG_ENTER("Event_parse_data::init_name");

  /* We have to copy strings to get them into the right memroot */
  if (spn)
  {
  DBUG_ASSERT(spn);
  dbname.length= spn->m_db.length;
  if (spn->m_db.length == 0)
    dbname.str= NULL;
  else
      dbname.str= strmake_root(root, spn->m_db.str, spn->m_db.length);
    dbname.str= thd->strmake(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 (spn->m_qname.length == 0)
      spn->init_qname(thd);
  }
  else if (thd->db)
  {
    dbname.length= thd->db_length;
    dbname.str= strmake_root(root, thd->db, dbname.length);
  }
  name.str= thd->strmake(spn->m_name.str, spn->m_name.length);

  DBUG_PRINT("dbname", ("len=%d db=%s",dbname.length, dbname.str));
  DBUG_PRINT("name", ("len=%d name=%s",name.length, name.str));
@@ -265,7 +85,7 @@ Event_timed::init_name(THD *thd, sp_name *spn)
  Set body of the event - what should be executed.

  SYNOPSIS
    Event_timed::init_body()
    Event_parse_data::init_body()
      thd   THD

  NOTE
@@ -277,9 +97,9 @@ Event_timed::init_name(THD *thd, sp_name *spn)
*/

void
Event_timed::init_body(THD *thd)
Event_parse_data::init_body(THD *thd)
{
  DBUG_ENTER("Event_timed::init_body");
  DBUG_ENTER("Event_parse_data::init_body");
  DBUG_PRINT("info", ("body=[%s] body_begin=0x%ld end=0x%ld", body_begin,
             body_begin, thd->lex->ptr));

@@ -331,17 +151,60 @@ Event_timed::init_body(THD *thd)
    ++body_begin;
    --body.length;
  }
  body.str= strmake_root(thd->mem_root, (char *)body_begin, body.length);
  body.str= thd->strmake((char *)body_begin, body.length);

  DBUG_VOID_RETURN;
}


/*
  Inits definer (definer_user and definer_host) during parsing.

  SYNOPSIS
    Event_parse_data::init_definer()
  
  RETURN VALUE
    0  OK
*/

int
Event_parse_data::init_definer(THD *thd)
{
  int definer_user_len;
  int definer_host_len;
  DBUG_ENTER("Event_parse_data::init_definer");

  DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
                     "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
                     thd->security_ctx->priv_user));

  definer_user_len= strlen(thd->security_ctx->priv_user);
  definer_host_len= strlen(thd->security_ctx->priv_host);

  /* + 1 for @ */
  DBUG_PRINT("info",("init definer as whole"));
  definer.length= definer_user_len + definer_host_len + 1;
  definer.str= thd->alloc(definer.length + 1);

  DBUG_PRINT("info",("copy the user"));
  memcpy(definer.str, thd->security_ctx->priv_user, definer_user_len);
  definer.str[definer_user_len]= '@';

  DBUG_PRINT("info",("copy the host"));
  memcpy(definer.str + definer_user_len + 1, thd->security_ctx->priv_host,
         definer_host_len);
  definer.str[definer.length]= '\0';
  DBUG_PRINT("info",("definer [%s] initted", definer.str));

  DBUG_RETURN(0);
}


/*
  Set time for execution for one time events.

  SYNOPSIS
    Event_timed::init_execute_at()
    Event_parse_data::init_execute_at()
      expr   when (datetime)

  RETURN VALUE
@@ -352,14 +215,14 @@ Event_timed::init_body(THD *thd)
*/

int
Event_timed::init_execute_at(THD *thd, Item *expr)
Event_parse_data::init_execute_at(THD *thd, Item *expr)
{
  my_bool not_used;
  TIME ltime;
  my_time_t t;

  TIME time_tmp;
  DBUG_ENTER("Event_timed::init_execute_at");
  DBUG_ENTER("Event_parse_data::init_execute_at");

  if (expr->fix_fields(thd, &expr))
    DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -403,7 +266,7 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
  Set time for execution for transient events.

  SYNOPSIS
    Event_timed::init_interval()
    Event_parse_data::init_interval()
      expr      how much?
      new_interval  what is the interval

@@ -415,12 +278,12 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
*/

int
Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
Event_parse_data::init_interval(THD *thd, Item *expr, interval_type new_interval)
{
  String value;
  INTERVAL interval_tmp;

  DBUG_ENTER("Event_timed::init_interval");
  DBUG_ENTER("Event_parse_data::init_interval");

  if (expr->fix_fields(thd, &expr))
    DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -504,7 +367,7 @@ Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
  Set activation time.

  SYNOPSIS
    Event_timed::init_starts()
    Event_parse_data::init_starts()
      expr      how much?
      interval  what is the interval

@@ -523,13 +386,13 @@ Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
*/

int
Event_timed::init_starts(THD *thd, Item *new_starts)
Event_parse_data::init_starts(THD *thd, Item *new_starts)
{
  my_bool not_used;
  TIME ltime, time_tmp;
  my_time_t t;

  DBUG_ENTER("Event_timed::init_starts");
  DBUG_ENTER("Event_parse_data::init_starts");

  if (new_starts->fix_fields(thd, &new_starts))
    DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -570,7 +433,7 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
  Set deactivation time.

  SYNOPSIS
    Event_timed::init_ends()
    Event_parse_data::init_ends()
      thd       THD
      new_ends  when?

@@ -590,13 +453,13 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
*/

int
Event_timed::init_ends(THD *thd, Item *new_ends)
Event_parse_data::init_ends(THD *thd, Item *new_ends)
{
  TIME ltime, ltime_now;
  my_bool not_used;
  my_time_t t;

  DBUG_ENTER("Event_timed::init_ends");
  DBUG_ENTER("Event_parse_data::init_ends");

  if (new_ends->fix_fields(thd, &new_ends))
    DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -641,67 +504,106 @@ Event_timed::init_ends(THD *thd, Item *new_ends)


/*
  Sets comment.
  Constructor

  SYNOPSIS
    Event_timed::init_comment()
      thd      THD - used for memory allocation
      comment  the string.
    Event_timed::Event_timed()
*/

void
Event_timed::init_comment(THD *thd, LEX_STRING *set_comment)
Event_timed::Event_timed():in_spawned_thread(0),locked_by_thread_id(0),
                           running(0), thread_id(0), status_changed(false),
                           last_executed_changed(false), expression(0),
                           created(0), modified(0),
                           on_completion(Event_timed::ON_COMPLETION_DROP),
                           status(Event_timed::ENABLED), sphead(0),
                           sql_mode(0), dropped(false),
                           free_sphead_on_delete(true), flags(0)
                
{
  DBUG_ENTER("Event_timed::init_comment");
  pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
  pthread_cond_init(&this->COND_finished, NULL);
  init();
}

  comment.str= strmake_root(thd->mem_root, set_comment->str,
                            comment.length= set_comment->length);

  DBUG_VOID_RETURN;
/*
  Destructor

  SYNOPSIS
    Event_timed::~Event_timed()
*/

Event_timed::~Event_timed()
{    
  deinit_mutexes();

  if (free_sphead_on_delete)
    free_sp();
}


/*
  Inits definer (definer_user and definer_host) during parsing.
  Destructor

  SYNOPSIS
    Event_timed::init_definer()
    Event_timed::deinit_mutexes()
*/

  RETURN VALUE
    0  OK
void
Event_timed::deinit_mutexes()
{
  pthread_mutex_destroy(&this->LOCK_running);
  pthread_cond_destroy(&this->COND_finished);
}


/*
  Checks whether the event is running

  SYNOPSIS
    Event_timed::is_running()
*/

int
Event_timed::init_definer(THD *thd)
bool
Event_timed::is_running()
{
  DBUG_ENTER("Event_timed::init_definer");
  bool ret;

  DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
                     "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
                     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);
  VOID(pthread_mutex_lock(&this->LOCK_running));
  ret= running;
  VOID(pthread_mutex_unlock(&this->LOCK_running));

  DBUG_PRINT("info",("init definer_host thd->s_c->priv_host=0x%lx",
                     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);
  return ret;
}

  DBUG_PRINT("info",("init definer as whole"));
  definer.length= definer_user.length + definer_host.length + 1;
  definer.str= alloc_root(thd->mem_root, definer.length + 1);

  DBUG_PRINT("info",("copy the user"));
  memcpy(definer.str, definer_user.str, definer_user.length);
  definer.str[definer_user.length]= '@';
/*
  Init all member variables

  DBUG_PRINT("info",("copy the host"));
  memcpy(definer.str + definer_user.length + 1, definer_host.str,
         definer_host.length);
  definer.str[definer.length]= '\0';
  DBUG_PRINT("info",("definer initted"));
  SYNOPSIS
    Event_timed::init()
*/

  DBUG_RETURN(0);
void
Event_timed::init()
{
  DBUG_ENTER("Event_timed::init");

  dbname.str= name.str= body.str= comment.str= 0;
  dbname.length= name.length= body.length= comment.length= 0;

  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);
  starts_null= ends_null= execute_at_null= TRUE;

  definer_user.str= definer_host.str= 0;
  definer_user.length= definer_host.length= 0;

  sql_mode= 0;

  DBUG_VOID_RETURN;
}


@@ -739,20 +641,17 @@ Event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
  if (table->s->fields != ET_FIELD_COUNT)
    goto error;

  if ((et->dbname.str= get_field(mem_root,
                                 table->field[ET_FIELD_DB])) == NULL)
  if ((et->dbname.str= get_field(mem_root, table->field[ET_FIELD_DB])) == NULL)
    goto error;

  et->dbname.length= strlen(et->dbname.str);

  if ((et->name.str= get_field(mem_root,
                               table->field[ET_FIELD_NAME])) == NULL)
  if ((et->name.str= get_field(mem_root, table->field[ET_FIELD_NAME])) == NULL)
    goto error;

  et->name.length= strlen(et->name.str);

  if ((et->body.str= get_field(mem_root,
                               table->field[ET_FIELD_BODY])) == NULL)
  if ((et->body.str= get_field(mem_root, table->field[ET_FIELD_BODY])) == NULL)
    goto error;

  et->body.length= strlen(et->body.str);
@@ -838,7 +737,6 @@ Event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
  else
    et->comment.length= 0;


  et->sql_mode= (ulong) table->field[ET_FIELD_SQL_MODE]->val_int();

  DBUG_RETURN(0);
@@ -1639,7 +1537,6 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
                               &security_ctx, &save_ctx);
  thd->lex= &lex;
  lex_start(thd, (uchar*)thd->query, thd->query_length);
  lex.et_compile_phase= TRUE;
  if (MYSQLparse((void *)thd) || thd->is_fatal_error)
  {
    DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d",
@@ -1662,7 +1559,7 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
  }
  DBUG_PRINT("note", ("success compiling %s.%s", dbname.str, name.str));

  sphead= lex.et->sphead;
  sphead= lex.sphead;
  sphead->m_db= dbname;

  sphead->set_definer(definer.str, definer.length);
@@ -1670,8 +1567,6 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
  sphead->optimize();
  ret= 0;
done:
  lex.et->free_sphead_on_delete= false;
  lex.et->deinit_mutexes();

  lex_end(&lex);
  thd->restore_security_context(save_ctx);
@@ -1875,7 +1770,6 @@ event_timed_db_equal(Event_timed *et, LEX_STRING *db)
}



/*
  Checks whether two events are equal by identifiers

@@ -1888,121 +1782,8 @@ event_timed_db_equal(Event_timed *et, LEX_STRING *db)
*/

bool
event_timed_identifier_equal(Event_timed *a, Event_timed *b)
event_timed_identifier_equal(LEX_STRING db, LEX_STRING name, Event_timed *b)
{
  return event_timed_name_equal(a, &b->name) &&
         event_timed_db_equal(a, &b->dbname);
}


/*
  Checks whether two events have the same name

  SYNOPSIS
    event_timed_name_equal()

  RETURN VALUE
    TRUE  names are equal
    FALSE names are not equal
*/

bool
event_timed_name_equal(sp_name *name, LEX_STRING *event_name)
{
  return !sortcmp_lex_string(name->m_name, *event_name, system_charset_info);
}


/*
  Checks whether two events are in the same schema

  SYNOPSIS
    event_timed_db_equal()

  RETURN VALUE
    TRUE  schemas are equal
    FALSE schemas are not equal
*/

bool
event_timed_db_equal(sp_name *name, LEX_STRING *db)
{
  return !sortcmp_lex_string(name->m_db, *db, system_charset_info);
}


/*
  Checks whether two events are equal by identifiers

  SYNOPSIS
    event_timed_identifier_equal()

  RETURN VALUE
    TRUE   equal
    FALSE  not equal
*/

bool
event_timed_identifier_equal(sp_name *a, Event_timed *b)
{
  return event_timed_name_equal(a, &b->name) &&
         event_timed_db_equal(a, &b->dbname);
}


/*
  Switches the security context
  SYNOPSIS
    change_security_context()
      thd     Thread
      user    The user
      host    The host of the user
      db      The schema for which the security_ctx will be loaded
      s_ctx   Security context to load state into
      backup  Where to store the old context
  
  RETURN VALUE
    0  - OK
    1  - Error (generates error too)
*/

bool
change_security_context(THD *thd, LEX_STRING user, LEX_STRING host,
                        LEX_STRING db, Security_context *s_ctx,
                        Security_context **backup)
{
  DBUG_ENTER("change_security_context");
  DBUG_PRINT("info",("%s@%s@%s", user.str, host.str, db.str));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
  s_ctx->init();
  *backup= 0;
  if (acl_getroot_no_password(s_ctx, user.str, host.str, host.str, db.str))
  {
    my_error(ER_NO_SUCH_USER, MYF(0), user.str, host.str);
    DBUG_RETURN(TRUE);
  }
  *backup= thd->security_ctx;
  thd->security_ctx= s_ctx;
#endif
  DBUG_RETURN(FALSE);
}


/*
  Restores the security context
  SYNOPSIS
    restore_security_context()
      thd    - thread
      backup - switch to this context
*/

void
restore_security_context(THD *thd, Security_context *backup)
{
  DBUG_ENTER("restore_security_context");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
  if (backup)
    thd->security_ctx= backup;
#endif
  DBUG_VOID_RETURN;
  return !sortcmp_lex_string(name, b->name, system_charset_info) &&
         !sortcmp_lex_string(db, b->dbname, system_charset_info);
}
+2 −61
Original line number Diff line number Diff line
@@ -54,19 +54,9 @@ class Event_timed;
bool
event_timed_db_equal(Event_timed *et, LEX_STRING *db);


/* Compares the whole identifier*/
bool
event_timed_identifier_equal(Event_timed *a, Event_timed *b);

/* Compares only the schema part of the identifier */
bool
event_timed_db_equal(sp_name *name, LEX_STRING *db);


/* Compares the whole identifier*/
bool
event_timed_identifier_equal(sp_name *a, Event_timed *b);
event_timed_identifier_equal(LEX_STRING db, LEX_STRING name, Event_timed *b);


class Event_timed
@@ -123,7 +113,6 @@ class Event_timed
  enum enum_status status;
  sp_head *sphead;
  ulong sql_mode;
  const uchar *body_begin;

  bool dropped;
  bool free_sphead_on_delete;
@@ -138,9 +127,6 @@ class Event_timed
    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)");
@@ -150,17 +136,6 @@ class Event_timed
    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();

  ~Event_timed();
@@ -171,30 +146,6 @@ class Event_timed
  void
  deinit_mutexes();

  int
  init_definer(THD *thd);

  int
  init_execute_at(THD *thd, Item *expr);

  int
  init_interval(THD *thd, Item *expr, interval_type new_interval);

  void
  init_name(THD *thd, sp_name *spn);

  int
  init_starts(THD *thd, Item *starts);

  int
  init_ends(THD *thd, Item *ends);

  void
  init_body(THD *thd);

  void
  init_comment(THD *thd, LEX_STRING *set_comment);

  int
  load_from_row(MEM_ROOT *mem_root, TABLE *table);

@@ -231,9 +182,6 @@ class Event_timed
  void
  free_sp();

  bool
  has_equal_db(Event_timed *etn);

  int
  kill_thread(THD *thd);

@@ -268,12 +216,9 @@ class Event_parse_data : public Sql_alloc
  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;

  Item* item_starts;
  Item* item_ends;
  Item* item_execute_at;
@@ -316,10 +261,6 @@ class Event_parse_data : public Sql_alloc

  void
  init_body(THD *thd);

  void
  init_comment(THD *thd, LEX_STRING *set_comment);

};


+321 −60

File changed.

Preview size limit exceeded, changes collapsed.

Loading