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

WL #1034 update

- fix one bug found by PeterG, namely bug #51

#there is a major problem currently after removing the specialised DYNAMIC_ARRAY as 
  storage for the events. I have to reintroduce similar storage, this time probably some
  linked list or maybe some API on top of DYNAMIC_ARRAY.


sql/event.cc:
  close the table
sql/event.h:
  change definition
sql/event_executor.cc:
  don't start the thread in advance
sql/event_timed.cc:
  - don't call evex_drop_event
  - quote the name during compilation to make create event `the rain in spain goes into the drain` not fail.
parent a820fa4f
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -877,7 +877,6 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
{
  TABLE *table;
  int ret= EVEX_OPEN_TABLE_FAILED;
  bool opened;
  DBUG_ENTER("evex_drop_event");

  if (evex_open_event_table(thd, TL_WRITE, &table))
@@ -914,9 +913,10 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)

done:
  /*
     No need to close the table, it will be closed in sql_parse::do_command()
     and evex_remove_from_cache does not try to open a table
    evex_drop_event() is used by event_timed::drop therefore
    we have to close our thread tables.
  */
  close_thread_tables(thd);

  DBUG_RETURN(ret);
}
+3 −3
Original line number Diff line number Diff line
@@ -102,13 +102,13 @@ class event_timed
                free_sphead_on_delete(true), flags(0)
                
  {
    pthread_mutex_init(&LOCK_running, MY_MUTEX_INIT_FAST);
    pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
    init();
  }
 
  ~event_timed()
  {
    pthread_mutex_destroy(&LOCK_running);
    pthread_mutex_destroy(&this->LOCK_running);
    if (free_sphead_on_delete)
	    free_sp();
  }
@@ -149,7 +149,7 @@ class event_timed
  void
  mark_last_executed();
  
  bool
  int
  drop(THD *thd);
  
  bool
+21 −10
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ init_events()
  evex_is_running= false;  
  VOID(pthread_mutex_unlock(&LOCK_evex_running));
  
  if (event_executor_running_global_var)
  {
#ifndef DBUG_FAULTY_THR
    //TODO Andrey: Change the error code returned!
    if (pthread_create(&th, NULL, event_executor_main, (void*)NULL))
@@ -98,6 +100,7 @@ init_events()
#else
    event_executor_main(NULL);
#endif
  }

  DBUG_RETURN(0);
}
@@ -249,6 +252,17 @@ event_executor_main(void *arg)
        continue;
      }
      et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*);
      if (et->status == MYSQL_EVENT_DISABLED)
      {
        DBUG_PRINT("evex_load_events_from_db",("Now it is disabled-exec no more"));
        if (et->dropped)
          et->drop(thd);
        delete et;
        evex_queue_delete_element(&EVEX_EQ_NAME, 1);// 1 is top
        VOID(pthread_mutex_unlock(&LOCK_event_arrays));
        sql_print_information("Event found disabled, dropping.");
        continue;    
      }
        
      time(&now);
      my_tz_UTC->gmt_sec_to_TIME(&time_now, now);
@@ -256,8 +270,6 @@ event_executor_main(void *arg)
      VOID(pthread_mutex_unlock(&LOCK_event_arrays));
      if (t2sleep > 0)
      {
//        sql_print_information("Sleeping for %d seconds.", t2sleep);
//        printf("\nWHEN=%llu   NOW=%llu\n", TIME_to_ulonglong_datetime(&et->execute_at), TIME_to_ulonglong_datetime(&time_now));
        /*
          We sleep t2sleep seconds but we check every second whether this thread
          has been killed, or there is new candidate
@@ -266,11 +278,9 @@ event_executor_main(void *arg)
               evex_queue_num_elements(EVEX_EQ_NAME) &&
               (evex_queue_first_element(&EVEX_EQ_NAME, event_timed*) == et))
          my_sleep(1000000);
//        sql_print_information("Finished sleeping");
      }
      if (!event_executor_running_global_var)
        continue;

    }


@@ -316,7 +326,7 @@ event_executor_main(void *arg)
      printf("[%10s] next at [%llu]\n\n\n", et->name.str,TIME_to_ulonglong_datetime(&et->execute_at));
      et->update_fields(thd);
      if ((et->execute_at.year && !et->expression) ||
           TIME_to_ulonglong_datetime(&et->execute_at) == 0L)
           TIME_to_ulonglong_datetime(&et->execute_at) == 0)
         et->flags |= EVENT_EXEC_NO_MORE;
    }
    if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED)
@@ -551,6 +561,7 @@ evex_load_events_from_db(THD *thd)
                      et->dbname.str, et->name.str);
      goto end;
    }
    
    // let's find when to be executed  
    et->compute_next_execution_time();
    
+36 −12
Original line number Diff line number Diff line
@@ -714,10 +714,34 @@ event_timed::mark_last_executed()
}


bool
/*
  Returns :
    0 - OK
   -1 - Cannot open mysql.event
   -2 - Cannot find the event in mysql.event (already deleted?)
   
   others - return code from SE in case deletion of the event row
            failed.
*/

int
event_timed::drop(THD *thd)
{
  return (bool) evex_drop_event(thd, this, false);
  TABLE *table;
  int ret= 0;
  DBUG_ENTER("event_timed::drop");

  if (evex_open_event_table(thd, TL_WRITE, &table))
    DBUG_RETURN(-1);

  if (evex_db_find_event_aux(thd, dbname, name, table))
    DBUG_RETURN(-2);

  if ((ret= table->file->delete_row(table->record[0])))
    DBUG_RETURN(ret);
    
  close_thread_tables(thd);
  DBUG_RETURN(0);
}


@@ -783,11 +807,11 @@ event_timed::get_show_create_event(THD *thd, uint *length)
  char *dst, *ret;
  uint len, tmp_len;

  len = strlen("CREATE EVENT ") + dbname.length + strlen(".") + name.length +
        strlen(" ON SCHEDULE EVERY 5 MINUTE DO ") + body.length + strlen(";");
  len = strlen("CREATE EVENT `") + dbname.length + strlen(".") + name.length +
        strlen("` ON SCHEDULE EVERY 5 MINUTE DO ") + body.length + strlen(";");
  
  ret= dst= (char*) alloc_root(thd->mem_root, len + 1);
  memcpy(dst, "CREATE EVENT ", tmp_len= strlen("CREATE EVENT "));
  memcpy(dst, "CREATE EVENT `", tmp_len= strlen("CREATE EVENT `"));
  dst+= tmp_len;
  memcpy(dst, dbname.str, tmp_len=dbname.length);
  dst+= tmp_len;
@@ -795,8 +819,8 @@ event_timed::get_show_create_event(THD *thd, uint *length)
  dst+= tmp_len;
  memcpy(dst, name.str, tmp_len= name.length);
  dst+= tmp_len;
  memcpy(dst, " ON SCHEDULE EVERY 5 MINUTE DO ",
         tmp_len= strlen(" ON SCHEDULE EVERY 5 MINUTE DO "));
  memcpy(dst, "` ON SCHEDULE EVERY 5 MINUTE DO ",
         tmp_len= strlen("` ON SCHEDULE EVERY 5 MINUTE DO "));
  dst+= tmp_len;

  memcpy(dst, body.str, tmp_len= body.length);
@@ -834,14 +858,14 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
   
  DBUG_ENTER("event_timed::execute");

  VOID(pthread_mutex_lock(&LOCK_running));
  VOID(pthread_mutex_lock(&this->LOCK_running));
  if (running) 
  {
    VOID(pthread_mutex_unlock(&LOCK_running));
    VOID(pthread_mutex_unlock(&this->LOCK_running));
    DBUG_RETURN(-100);
  }
  running= true;
  VOID(pthread_mutex_unlock(&LOCK_running));
  VOID(pthread_mutex_unlock(&this->LOCK_running));

  // TODO Andrey : make this as member variable and delete in destructor
  empty_item_list.empty();
@@ -851,9 +875,9 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
  
  ret= sphead->execute_procedure(thd, &empty_item_list);

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

done:
  // Don't cache sphead if allocated on another mem_root