List:Commits« Previous MessageNext Message »
From:ahristov Date:February 20 2006 5:39pm
Subject:bk commit into 5.1 tree (andrey:1.2122) BUG#16992
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2122 06/02/20 17:39:45 andrey@lmy004. +15 -0
  fix for bug#16992 Events: information_schema troubles
  WL#1034
  (the previous CSet was missing one file :( )
  EVENT is no more needed, as SHOW PRIVILEGES, to see own events.
  To see all events one needs SELECT on mysql.event.
  SHOW EVENTS always shows events from one database. FULL has no effect
  SELECT I_S gets from all schemas. If user is missing EVENT on a schema
  but still has events there he will be able to see them but they won't
  be executed because he misses EVENT on this schema. They will start
  executing again if she gets again granted EVENT on this schema.

  mysql-test/t/events_tamper.test
    1.1 06/02/20 17:39:37 andrey@lmy004. +100 -0

  mysql-test/t/events_tamper.test
    1.0 06/02/20 17:39:37 andrey@lmy004. +0 -0
    BitKeeper file /work/mysql-5.1-bug16992/mysql-test/t/events_tamper.test

  mysql-test/r/events_tamper.result
    1.1 06/02/20 17:39:34 andrey@lmy004. +126 -0

  mysql-test/r/events_tamper.result
    1.0 06/02/20 17:39:34 andrey@lmy004. +0 -0
    BitKeeper file /work/mysql-5.1-bug16992/mysql-test/r/events_tamper.result

  mysql-test/r/events_i_s.result
    1.1 06/02/20 17:39:33 andrey@lmy004. +125 -0

  sql/table.h
    1.132 06/02/20 17:39:33 andrey@lmy004. +19 -2
    - add index checking typedef

  sql/table.cc
    1.210 06/02/20 17:39:33 andrey@lmy004. +64 -16
    - add functionality to table_check_intact() to check also indices, if needed
      indices on tables with up to 255 fields. The index length is practically unlimited
      but anyway - 255 fields.
    - prefix the table->alias with mysql. The code will be used anyway for now only for
      mysql internal tables.

  sql/sql_show.cc
    1.308 06/02/20 17:39:33 andrey@lmy004. +63 -21
    - field 16 of I_S.EVENTS, last_execute_at is declared as maybe_null so only in case
it's not
      null call set_notnull() and set a value
    - handle in better way SHOW EVENTS / SELECT I_S
     -- SHOW EVENTS can be executed without having EVENT on the specific schema. All
user's events
        will be presented. If the user has no EVENT but SELECT_ACL on mysql.event the he
will see
        all events in the specific schema (nobody can prevent him from selecting
mysql.event anyway)
     -- SELECT I_S is the same as SHOW EVENTS but on global level. Without SELECT_ACL on
mysql.event
        one does see all events (s)he has. With SELECT_ACL on mysql.event one sees all
existing events. 

  sql/sql_parse.cc
    1.523 06/02/20 17:39:33 andrey@lmy004. +5 -6
    - handle show events in another way. show events does not require EVENT priv to
      see your own events. SELECT on  mysql.event is required to see all events per 
      db (with SHOW EVENTS) or globally (with SELECT I_S.EVENTS)

  sql/event_executor.cc
    1.31 06/02/20 17:39:33 andrey@lmy004. +6 -6
    - additional NULL parameter durin checking of mysql.db, we don't check the
      indices of mysql.db because we don't care about them.
    - make "event_scheduler" var OFF when the scheduler finishes.

  sql/event.cc
    1.31 06/02/20 17:39:33 andrey@lmy004. +104 -86
    - add information about the indices we expect mysql.event to have
    - because the new UNIQUE index is introduced on mysql.event it is used
      in evex_drop_db_events() to speedup the table scan to an index scan.
    - everything else changed in this file is whitespace change

  scripts/mysql_fix_privilege_tables.sql
    1.41 06/02/20 17:39:33 andrey@lmy004. +3 -2
    add additional unique index;

  scripts/mysql_create_system_tables.sh
    1.38 06/02/20 17:39:33 andrey@lmy004. +2 -1
    add additional unique index

  mysql-test/r/events_i_s.result
    1.0 06/02/20 17:39:33 andrey@lmy004. +0 -0
    BitKeeper file /work/mysql-5.1-bug16992/mysql-test/r/events_i_s.result

  mysql-test/t/events.test
    1.21 06/02/20 17:39:32 andrey@lmy004. +0 -132
    - move information_schema test of EVENTS to a separate test
    - move tampering test to separate file which has more tests for index
      checking.

  mysql-test/r/system_mysql_db.result
    1.39 06/02/20 17:39:32 andrey@lmy004. +2 -1
    - fix output

  mysql-test/r/events.result
    1.22 06/02/20 17:39:32 andrey@lmy004. +1 -143
    -update results file
    -information_schema test of EVENTS has been moved to a separate file
    -tampering of mysql.event test has been moved to a separate file

  mysql-test/lib/init_db.sql
    1.25 06/02/20 17:39:32 andrey@lmy004. +2 -1
    add a second key, unique to the table mysql.event

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	andrey
# Host:	lmy004.
# Root:	/work/mysql-5.1-bug16992

--- 1.522/sql/sql_parse.cc	2006-02-15 17:12:20 +01:00
+++ 1.523/sql/sql_parse.cc	2006-02-20 17:39:33 +01:00
@@ -2458,15 +2458,11 @@ mysql_execute_command(THD *thd)
     if (all_tables)
     {
       if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
-          lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC &&
-          lex->orig_sql_command != SQLCOM_SHOW_EVENTS)
+          lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC)
         res= check_table_access(thd,
                                 lex->exchange ? SELECT_ACL | FILE_ACL :
                                 SELECT_ACL,
                                 all_tables, 0);
-      else if (lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
-        res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
-                       is_schema_db(thd->lex->select_lex.db));
     }
     else
       res= check_access(thd,
@@ -3769,9 +3765,12 @@ end_with_restore_list:
         break;
       }
 
-      if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
+      if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 1,
                        is_schema_db(lex->et->dbname.str)))
+      {
+        my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "EVENT"); 
         break;
+      }
 
       if (end_active_trans(thd))
       {

--- 1.307/sql/sql_show.cc	2006-02-16 13:12:37 +01:00
+++ 1.308/sql/sql_show.cc	2006-02-20 17:39:33 +01:00
@@ -4013,9 +4013,10 @@ fill_events_copy_to_schema_table(THD *th
   sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
 
   if (et.last_executed.year)
+  {
+    sch_table->field[16]->set_notnull();
    
sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME);
-  else
-    sch_table->field[16]->set_null();
+  }
 
   sch_table->field[17]->store(et.comment.str, et.comment.length, scs);
 
@@ -4035,17 +4036,18 @@ int fill_schema_events(THD *thd, TABLE_L
   int ret=0;
   bool verbose= false;
   char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
-  bool use_prefix_scanning= true;
   uint key_len= 0;
   byte *key_buf= NULL;
   LINT_INIT(key_buf);
+  bool use_prefix_scanning= TRUE;
 
   DBUG_ENTER("fill_schema_events");
 
   strxmov(definer,
thd->security_ctx->priv_user,"@",thd->security_ctx->priv_host,
           NullS);
 
-  DBUG_PRINT("info",("db=%s current_user=%s", thd->lex->select_lex.db, definer));
+  DBUG_PRINT("info",("db=%s current_user=%s",
+             thd->lex->select_lex.db?thd->lex->select_lex.db:"(null)",
definer));
 
   thd->reset_n_backup_open_tables_state(&backup);
 
@@ -4055,33 +4057,68 @@ int fill_schema_events(THD *thd, TABLE_L
     ret= 1;
     goto err;
   }
-  
-  event_table->file->ha_index_init(0, 1);
 
-  /* 
-    see others' events only if you have PROCESS_ACL !!
-    thd->lex->verbose is set either if SHOW FULL EVENTS or
-    in case of SELECT FROM I_S.EVENTS
-  */
-  verbose= (thd->lex->verbose
-            && (thd->security_ctx->master_access & PROCESS_ACL));
-
-  if (verbose && thd->security_ctx->user)
-  {    
-    ret= event_table->file->index_first(event_table->record[0]);
-    use_prefix_scanning= false;
+  {
+    TABLE_LIST tmp_table;
+    bzero((char*) &tmp_table,sizeof(tmp_table));
+    tmp_table.db=(char*) "mysql";
+    tmp_table.table_name=(char*) "event";
+    verbose= !(check_grant(thd, SELECT_ACL, &tmp_table, 0, 1, 1));
+  }
+
+  if (verbose)
+  {
+    /*
+      1. SELECT I_S => use PK(0) 
+      2. SHOW EVENTS => second index(1) (db, name, definer)
+    
+    */
+    if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+    {
+      DBUG_PRINT("info",("Using prefix scanning on UNIQUE"));
+      event_table->file->ha_index_init(1, 1);
+      DBUG_ASSERT(thd->lex->select_lex.db);
+      DBUG_PRINT("info",("Using  `%s` in the prefix", thd->lex->select_lex.db));
+      event_table->field[EVEX_FIELD_DB]->
+          store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db),
scs);
+      key_len= event_table->key_info[1].key_part[0].store_length;
+  
+      if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+      {
+        ret= 1;
+        goto err;
+      }
+    
+      key_copy(key_buf, event_table->record[0], event_table->key_info + 1,
+               key_len);
+      ret= event_table->file->index_read(event_table->record[0], key_buf,
+                                         key_len, HA_READ_PREFIX);
+    }
+    else
+    {
+      DBUG_PRINT("info",("Not using prefix scanning but using PK."));
+      event_table->file->ha_index_init(0, 1);
+      ret= event_table->file->index_first(event_table->record[0]);
+      use_prefix_scanning= FALSE;
+    }
   }
   else
   {
-    event_table->field[EVEX_FIELD_DEFINER]->store(definer, strlen(definer), scs);  
 
+    DBUG_PRINT("info",("Using prefix scanning on PK"));
+
+    event_table->file->ha_index_init(0, 1);
+    event_table->field[EVEX_FIELD_DEFINER]->store(definer, strlen(definer), scs);
     key_len= event_table->key_info->key_part[0].store_length;
 
-    if (thd->lex->select_lex.db)
+    if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
     {
+      DBUG_PRINT("info",("Using also `%s` in the prefix scanning",
+                  thd->lex->select_lex.db));
       event_table->field[EVEX_FIELD_DB]->
             store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db),
scs);
       key_len+= event_table->key_info->key_part[1].store_length;
     }
+
     if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
     {
       ret= 1;
@@ -4098,6 +4135,7 @@ int fill_schema_events(THD *thd, TABLE_L
     ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
     goto err;
   }
+  DBUG_PRINT("info",("Found some rows, let's retrieve them."));
 
   while (!ret)
   {
@@ -4106,20 +4144,24 @@ int fill_schema_events(THD *thd, TABLE_L
 
     if (use_prefix_scanning)
       ret= event_table->file->
-                       index_next_same(event_table->record[0], key_buf, key_len);     
                            
+                       index_next_same(event_table->record[0], key_buf, key_len);
     else
       ret= event_table->file->index_next(event_table->record[0]);
   }
+  DBUG_PRINT("info",("Scan finished"));
   // ret is guaranteed to be != 0
   ret= (ret != HA_ERR_END_OF_FILE);
 err:
   if (event_table)
   {
+    DBUG_PRINT("info",("Closing index"));
     event_table->file->ha_index_end();
     close_thread_tables(thd);
   }
 
   thd->restore_backup_open_tables_state(&backup);
+  
+  DBUG_PRINT("info",("Return code=%d", ret));
   DBUG_RETURN(ret);
 }
 

--- 1.209/sql/table.cc	2006-02-14 20:10:43 +01:00
+++ 1.210/sql/table.cc	2006-02-20 17:39:33 +01:00
@@ -2299,6 +2299,9 @@ bool check_column_name(const char *name)
       table         - the table to check
       table_f_count - expected number of columns in the table
       table_def     - expected structure of the table (column name and type)
+      table_keys    - NULL if no index checking, otherwise a pointer to an
+                      array of the type. The last element in the array should
+                      be {NULL, 0} (terminated in this way).
     last_create_time- the table->file->create_time of the table in memory
                       we have checked last time
       error_num     - ER_XXXX from the error messages file. When 0 no error
@@ -2314,8 +2317,9 @@ bool check_column_name(const char *name)
 
 my_bool
 table_check_intact(TABLE *table, uint table_f_count,
-                   TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
-                   int error_num)
+                   TABLE_FIELD_W_TYPE *table_def,
+                   TABLE_KEY_FOR_CHECK *table_keys,
+                   time_t *last_create_time, int error_num)
 {
   uint i;
   my_bool error= FALSE;
@@ -2323,7 +2327,7 @@ table_check_intact(TABLE *table, uint ta
   DBUG_ENTER("table_check_intact");
   DBUG_PRINT("info",("table=%s expected_count=%d",table->alias, table_f_count));
   DBUG_PRINT("info",("last_create_time=%d", *last_create_time));
-  
+
   if ((fields_diff_count= (table->s->fields != table_f_count)) ||
       (*last_create_time != table->file->create_time))
   {
@@ -2363,11 +2367,11 @@ table_check_intact(TABLE *table, uint ta
         if (strncmp(field->field_name, table_def->name.str,
                                        table_def->name.length))
         {
-          sql_print_error("(%s) Expected field %s at position %d, found %s",
-                          table->alias, table_def->name.str, i,
+          sql_print_error("(mysql.%s) Expected field %s at position %d, "
+                          " found %s", table->alias, table_def->name.str, i,
                           field->field_name);
         }
-                        
+
         /*
           IF the type does not match than something is really wrong
           Check up to length - 1. Why?
@@ -2382,22 +2386,23 @@ table_check_intact(TABLE *table, uint ta
         if (strncmp(sql_type.c_ptr(), table_def->type.str,
                     table_def->type.length - 1))
         {
-          sql_print_error("(%s) Expected field %s at position %d to have type "
-                          "%s, found %s", table->alias, table_def->name.str,
-                          i, table_def->type.str, sql_type.c_ptr()); 
+          sql_print_error("(mysql.%s) Expected field %s at position %d to "
+                          " have type %s, found %s", table->alias,
+                          table_def->name.str, i, table_def->type.str,
+                          sql_type.c_ptr()); 
           error= TRUE;
         }
         else if (table_def->cset.str && !field->has_charset())
         {
-          sql_print_error("(%s) Expected field %s at position %d to have "
+          sql_print_error("(mysql.%s) Expected field %s at position %d to have "
                           "character set '%s' but found no such", table->alias,
-                          table_def->name.str, i, table_def->cset.str);        
+                          table_def->name.str, i, table_def->cset.str);
           error= TRUE;
         }
         else if (table_def->cset.str && 
                  strcmp(field->charset()->csname, table_def->cset.str))
         {
-          sql_print_error("(%s) Expected field %s at position %d to have "
+          sql_print_error("(mysql.%s) Expected field %s at position %d to have "
                           "character set '%s' but found '%s'", table->alias,
                           table_def->name.str, i, table_def->cset.str,
                           field->charset()->csname);
@@ -2406,12 +2411,54 @@ table_check_intact(TABLE *table, uint ta
       }
       else
       {
-        sql_print_error("(%s) Expected field %s at position %d to have type %s "
-                        " but no field found.", table_def->name.str,
+        sql_print_error("(mysql.%s) Expected field %s at position %d to "
+                        " have type %s but no field found.", table_def->name.str,
                         table_def->name.str, i, table_def->type.str);
         error= TRUE;        
       }
     }
+    if (table_keys)
+    {
+      KEY *key_info= table->key_info;
+      uint key_num= 0;
+      uint missing_keys= 0;
+      for (; table_keys->key.length; ++key_num, ++table_keys, ++key_info)
+      {
+        if (table->s->keys < key_num + 1)
+        {
+          ++missing_keys;
+          continue;
+        }
+        KEY_PART_INFO *key_part= key_info->key_part;
+        if (table_keys->key.length > key_info->key_parts)
+        {
+          error= TRUE;
+          sql_print_error("(mysql.%s) Key %d is shorter than expected. "
+                          "Expected %d key parts, found %d", table->alias,
+                          key_num, table_keys->key.length, key_info->key_parts);
+          continue;
+        }
+        for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
+        {
+          if (j == table_keys->key.length)
+            break;
+
+          if (key_part->fieldnr != table_keys->key.str[j])
+          {
+            error= TRUE;
+            sql_print_error("(mysql.%s) Key %d, key part %d expected field %d,"
+                            " found %d.", table->alias, key_num, j,
+                            table_keys->key.str[j], key_part->fieldnr);
+          }
+        }
+      }
+      if (missing_keys)
+      {
+        error= TRUE;
+        sql_print_error("(mysql.%s) Expected %d keys, found %d", table->alias,
+                        table->s->keys + missing_keys, table->s->keys);
+      }
+    }
     if (!error)
       *last_create_time= table->file->create_time;
     else if (!fields_diff_count && error_num)
@@ -2422,8 +2469,9 @@ table_check_intact(TABLE *table, uint ta
     DBUG_PRINT("info", ("Table seems ok without thorough checking."));
     *last_create_time= table->file->create_time;
   }
-   
-  DBUG_RETURN(error);  
+
+  DBUG_PRINT("info", ("return code=%d", error));
+  DBUG_RETURN(error);
 }
 
 

--- 1.131/sql/table.h	2006-02-16 14:53:27 +01:00
+++ 1.132/sql/table.h	2006-02-20 17:39:33 +01:00
@@ -867,6 +867,7 @@ typedef struct st_open_table_list{
   uint32 in_use,locked;
 } OPEN_TABLE_LIST;
 
+
 typedef struct st_table_field_w_type
 {
   LEX_STRING name;
@@ -874,8 +875,24 @@ typedef struct st_table_field_w_type
   LEX_STRING cset;
 } TABLE_FIELD_W_TYPE;
 
+/*
+  Every byte in the string regards a fieldnr
+  Should work without probles with tables with up to 126 fields.
+  If char is unsigned by default with up to 255 fields.
+  Usage:
+  
+  STRING_WITH_LEN("\x01\x04\07") 
+  This instructs that the index has 3 parts and includes fields
+  1, 4 and 7. For the keys the indexing is 1-based and not 0-based. 
+*/
+typedef struct st_table_key_for_check
+{
+  LEX_STRING key;
+} TABLE_KEY_FOR_CHECK;
+
 
 my_bool
 table_check_intact(TABLE *table, uint table_f_count,
-                   TABLE_FIELD_W_TYPE *table_def, time_t *last_create_time,
-                   int error_num);
+                   TABLE_FIELD_W_TYPE *table_def,
+                   TABLE_KEY_FOR_CHECK *table_keys,
+                   time_t *last_create_time, int error_num);

--- 1.21/mysql-test/r/events.result	2006-02-16 13:11:06 +01:00
+++ 1.22/mysql-test/r/events.result	2006-02-20 17:39:32 +01:00
@@ -168,149 +168,6 @@ drop event root19;
 drop event root20;
 drop event ðóóò21;
 set names latin1;
-CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
-ALTER TABLE mysql.event ADD dummy INT FIRST;
-SHOW EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
-ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
-SHOW EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
-ALTER TABLE mysql.event DROP dummy2;
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
-CREATE TABLE event_like LIKE mysql.event;
-INSERT INTO event_like SELECT * FROM mysql.event;
-ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default
'';
-SHOW CREATE TABLE mysql.event;
-Table	Create Table
-event	CREATE TABLE `event` (
-  `db` char(20) character set utf8 collate utf8_bin NOT NULL default '',
-  `name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
-  `body` longblob NOT NULL,
-  `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
-  `execute_at` datetime default NULL,
-  `interval_value` int(11) default NULL,
-  `interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
-  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
-  `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
-  `last_executed` datetime default NULL,
-  `starts` datetime default NULL,
-  `ends` datetime default NULL,
-  `status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
-  `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP',
-  `sql_mode`
set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE')
NOT NULL default '',
-  `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
-  PRIMARY KEY  (`definer`,`db`,`name`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
-ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default
'';
-"This should work"
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
-ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
-ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
-ALTER TABLE mysql.event DROP comment, DROP starts;
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 14. Table probably
corrupted
-DROP TABLE mysql.event;
-CREATE TABLE mysql.event like event_like;
-INSERT INTO  mysql.event SELECT * FROM event_like;
-DROP TABLE event_like;
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
-DROP EVENT intact_check;
-create event one_event on schedule every 10 second do select 123;
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	one_event	root@localhost	RECURRING	NULL	10	SECOND	#	#	ENABLED
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
-NULL	events_test	one_event	root@localhost	select 123	RECURRING	NULL	10	SECOND	ENABLED	NOT
PRESERVE	
-CREATE DATABASE events_test2;
-CREATE USER ev_test@localhost;
-GRANT ALL ON events_test.* to ev_test@localhost;
-GRANT ALL on events_test2.* to ev_test@localhost;
-REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
-REVOKE PROCESS on *.* from ev_test@localhost;
-select "NEW CONNECTION";
-NEW CONNECTION
-NEW CONNECTION
-SELECT USER(), DATABASE();
-USER()	DATABASE()
-ev_test@localhost	events_test2
-SHOW GRANTS;
-Grants for ev_test@localhost
-GRANT USAGE ON *.* TO 'ev_test'@'localhost'
-GRANT ALL PRIVILEGES ON `events_test`.* TO 'ev_test'@'localhost'
-GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE
TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER
ROUTINE, TRIGGER ON `events_test2`.* TO 'ev_test'@'localhost'
-"Here comes an error:";
-SHOW EVENTS;
-ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_test2'
-USE events_test;
-"Now the list should be empty:";
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-select concat("Let's create some new events from the name of ",user());
-concat("Let's create some new events from the name of ",user())
-Let's create some new events from the name of ev_test@localhost
-create event one_event on schedule every 20 second do select 123;
-create event two_event on schedule every 20 second on completion not preserve comment
"two event" do select 123;
-create event three_event on schedule every 20 second on completion preserve comment
"three event" do select 123;
-"Now we should see 3 events:";
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-"This should show us only 3 events:";
-SHOW FULL EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-"This should show us only 2 events:";
-SHOW FULL EVENTS LIKE 't%event';
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-"This should show us no events:";
-SHOW FULL EVENTS FROM test LIKE '%';
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-DROP DATABASE events_test2;
-"should see 1 event:";
-SHOW EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	one_event	root@localhost	RECURRING	NULL	10	SECOND	#	#	ENABLED
-"we should see 4 events now:";
-SHOW FULL EVENTS;
-Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
-events_test	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
-events_test	one_event	root@localhost	RECURRING	NULL	10	SECOND	#	#	ENABLED
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
-NULL	events_test	one_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	NOT PRESERVE	
-NULL	events_test	three_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	PRESERVE	three event
-NULL	events_test	two_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	NOT PRESERVE	two event
-NULL	events_test	one_event	root@localhost	select 123	RECURRING	NULL	10	SECOND	ENABLED	NOT
PRESERVE	
-drop event one_event;
-drop event two_event;
-drop event three_event;
-drop user ev_test@localhost;
-drop event one_event;
-"Sleep a bit so the server closes the second connection"
 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;
 db	name	body	definer	convert_tz(execute_at, 'UTC', 'SYSTEM')	on_completion
@@ -343,6 +200,7 @@ root@localhost	закачка	events_tes
 show processlist;
 Id	User	Host	db	Command	Time	State	Info
 #	root	localhost	events_test	Query	#	NULL	show processlist
+#	event_scheduler	connecting host	NULL	Connect	#	Sleeping	NULL
 select release_lock("test_lock1");
 release_lock("test_lock1")
 1
--- New file ---
+++ mysql-test/r/events_i_s.result	06/02/20 17:39:33
create database if not exists events_test;
use events_test;
select user(), database();
user()	database()
root@localhost	events_test
create event one_event on schedule every 10 second do select 123;
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test	one_event	root@localhost	RECURRING	NULL	10	SECOND	#	#	ENABLED
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
NULL	events_test	one_event	root@localhost	select 123	RECURRING	NULL	10	SECOND	ENABLED	NOT
PRESERVE	
CREATE DATABASE events_test2;
CREATE USER ev_test@localhost;
GRANT EVENT ON events_test.* to ev_test@localhost;
GRANT SELECT on events_test2.* to ev_test@localhost;
"Connect as ev_con1, user ev_test, db events_test2"
"NEW CONNECTION";
SELECT USER(), DATABASE();
USER()	DATABASE()
ev_test@localhost	events_test2
SHOW GRANTS;
Grants for ev_test@localhost
GRANT USAGE ON *.* TO 'ev_test'@'localhost'
GRANT EVENT ON `events_test`.* TO 'ev_test'@'localhost'
GRANT SELECT ON `events_test2`.* TO 'ev_test'@'localhost'
"Now the list should be empty:";
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
"Now create few events as ev_test@localhost in schema events_test"
select concat("Let's create some new events from the name of ",user());
concat("Let's create some new events from the name of ",user())
Let's create some new events from the name of ev_test@localhost
"ev_test@localhost has no EVENT so error"
create event one_event on schedule every 20 second disable do select 123;
ERROR 42000: Access denied; you need the EVENT privilege for this operation
"Now we will give him EVENT"
GRANT EVENT ON events_test2.* to ev_test@localhost;
"Change the current schema so the server will read our new privs"
use events_test;
use events_test2;
"Now he has EVENT and will create 3 events"
create event one_event on schedule every 20 second disable do select 123;
create event two_event on schedule every 20 second on completion not preserve comment "two
event" do select 123;
create event three_event on schedule every 20 second on completion preserve comment "three
event" do select 123;
"Now we should see 3 events because ev_test has no SELECT on mysql.event:";
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	DISABLED
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
"Let's REVOKE his EVENT on events_test2, but he will still see his events"
REVOKE EVENT on events_test2.* FROM ev_test@localhost;
"Now he has no EVENT on events_test2 but that's not a problem"
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	DISABLED
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
"This should show us only 2 events:";
SHOW EVENTS LIKE 't%event';
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
"This should show us no events:";
SHOW EVENTS FROM test LIKE '%';
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
"This also :";
SHOW EVENTS IN test LIKE '%';
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
"ok, we are back to root@localhost"
USE events_test2;
create event root_event_1 on schedule every 10 hour do select 12345;
create event root_event_2 on schedule every 20 minute do select 4567;
"As root@localhost we should see 5 event:";
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	DISABLED
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	root_event_1	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
events_test2	root_event_2	root@localhost	RECURRING	NULL	20	MINUTE	#	#	ENABLED
"Switching back to ev_con1, should see only his 3 events. Keep in mind he has no EVENT
ATM"
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	DISABLED
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
"Back to root@localhost to GRANT SELECT on mysql.event"
GRANT SELECT ON mysql.event TO ev_test@localhost;
"Back to ev_test@localhost"
"Now we should see 5 events, because of SELECT on mysql.event,"
"even without EVENT on event_test2. 3 of ev_test@localhost and 2 of root@localhost"
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test2	one_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	DISABLED
events_test2	three_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	two_event	ev_test@localhost	RECURRING	NULL	20	SECOND	#	#	ENABLED
events_test2	root_event_1	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
events_test2	root_event_2	root@localhost	RECURRING	NULL	20	MINUTE	#	#	ENABLED
"we should see 6 events now (additional one from events_test schema:";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
NULL	events_test2	one_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	DISABLED	NOT PRESERVE	
NULL	events_test2	three_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	PRESERVE	three event
NULL	events_test2	two_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	NOT PRESERVE	two event
NULL	events_test	one_event	root@localhost	select 123	RECURRING	NULL	10	SECOND	ENABLED	NOT
PRESERVE	
NULL	events_test2	root_event_1	root@localhost	select
12345	RECURRING	NULL	10	HOUR	ENABLED	NOT PRESERVE	
NULL	events_test2	root_event_2	root@localhost	select
4567	RECURRING	NULL	20	MINUTE	ENABLED	NOT PRESERVE	
REVOKE SELECT ON mysql.event FROM ev_test@localhost;
"we should see only 3 events now, we don't have SELECT on mysql.event anymore:";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
NULL	events_test2	one_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	DISABLED	NOT PRESERVE	
NULL	events_test2	three_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	PRESERVE	three event
NULL	events_test2	two_event	ev_test@localhost	select
123	RECURRING	NULL	20	SECOND	ENABLED	NOT PRESERVE	two event
DROP DATABASE events_test2;
use events_test;
"we should see only 2 events now, 3 of ev_test@localhost were dropped with DROP DATABASE";
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
EVENT_CATALOG	EVENT_SCHEMA	EVENT_NAME	DEFINER	EVENT_BODY	EVENT_TYPE	EXECUTE_AT	INTERVAL_VALUE	INTERVAL_FIELD	STATUS	ON_COMPLETION	EVENT_COMMENT
NULL	events_test	one_event	root@localhost	select 123	RECURRING	NULL	10	SECOND	ENABLED	NOT
PRESERVE	
drop user ev_test@localhost;
drop event one_event;
drop database events_test;

--- New file ---
+++ mysql-test/r/events_tamper.result	06/02/20 17:39:34
create database if not exists events_test;
use events_test;
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
ALTER TABLE mysql.event ADD dummy INT FIRST;
SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
SHOW EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 17. Table probably
corrupted
ALTER TABLE mysql.event DROP dummy2;
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event;
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
SHOW CREATE TABLE mysql.event;
Table	Create Table
event	CREATE TABLE `event` (
  `db` char(20) character set utf8 collate utf8_bin NOT NULL default '',
  `name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
  `body` longblob NOT NULL,
  `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
  `execute_at` datetime default NULL,
  `interval_value` int(11) default NULL,
  `interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
  `last_executed` datetime default NULL,
  `starts` datetime default NULL,
  `ends` datetime default NULL,
  `status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
  `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP',
  `sql_mode`
set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE')
NOT NULL default '',
  `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
  PRIMARY KEY  (`definer`,`db`,`name`),
  UNIQUE KEY `db_definer_name` (`db`,`definer`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
"This should work"
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP comment, DROP starts;
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Column count of mysql.event is wrong. Expected 16, found 14. Table probably
corrupted
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
"Now dropping one index to see whether index tampering check works"
ALTER TABLE mysql.event DROP PRIMARY KEY;
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
"Recreating, should work now:"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
"Test whether everything is fine"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
ALTER TABLE mysql.event DROP INDEX db_definer_name;
SHOW CREATE TABLE mysql.event;
Table	Create Table
event	CREATE TABLE `event` (
  `db` char(64) character set utf8 collate utf8_bin NOT NULL default '',
  `name` char(64) character set utf8 collate utf8_bin NOT NULL default '',
  `body` longblob NOT NULL,
  `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
  `execute_at` datetime default NULL,
  `interval_value` int(11) default NULL,
  `interval_field`
enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND')
default NULL,
  `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
  `last_executed` datetime default NULL,
  `starts` datetime default NULL,
  `ends` datetime default NULL,
  `status` enum('ENABLED','DISABLED') NOT NULL default 'ENABLED',
  `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP',
  `sql_mode`
set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE')
NOT NULL default '',
  `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
  PRIMARY KEY  (`definer`,`db`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
"Now let's bork the index and see whether we catch it"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name, definer);
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP KEY db_definer_name;
"Make the key shorter"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name);
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP KEY db_definer_name;
"Try with longer index, this should work"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, definer, name, execute_at);
"No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
"Add 1 more index, that should not be a problem - downgrading is ok"
ALTER TABLE mysql.event ADD KEY dummy_index(execute_at);
"No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
event_name
intact_check
"Recreating"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
DROP TABLE event_like;
SHOW EVENTS;
Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
events_test	intact_check	root@localhost	RECURRING	NULL	10	HOUR	#	#	ENABLED
DROP EVENT intact_check;
drop database events_test;


--- 1.20/mysql-test/t/events.test	2006-02-16 05:20:54 +01:00
+++ 1.21/mysql-test/t/events.test	2006-02-20 17:39:32 +01:00
@@ -149,139 +149,7 @@ set names latin1;
 # SHOW CREATE EVENT test end
 #
 
-#
-# mysql.event intact checking start
-#
-# There should be at least 1 second between the ALTERs or we can't catch the change of
create_time!!
-#
-CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
---replace_column 8 # 9 #
-SHOW EVENTS;
-ALTER TABLE mysql.event ADD dummy INT FIRST;
---error 1525
-SHOW EVENTS;
-ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
---error 1525
-SHOW EVENTS;
-ALTER TABLE mysql.event DROP dummy2;
---replace_column 8 # 9 #
-SHOW EVENTS;
-CREATE TABLE event_like LIKE mysql.event;
-INSERT INTO event_like SELECT * FROM mysql.event;
-#sleep a bit or we won't catch the change of time
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default
'';
-#wait a bit or we won't see the difference because of seconds resolution
---sleep 1
-SHOW CREATE TABLE mysql.event;
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default
'';
---sleep 1
---echo "This should work"
---replace_column 8 # 9 #
-SHOW EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
---error 1526
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
---sleep 1
-ALTER TABLE mysql.event DROP comment, DROP starts;
---sleep 1
---error 1525
-SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
-DROP TABLE mysql.event;
-CREATE TABLE mysql.event like event_like;
-INSERT INTO  mysql.event SELECT * FROM event_like;
-DROP TABLE event_like;
---replace_column 8 # 9 #
-SHOW EVENTS;
-DROP EVENT intact_check;
-#
-# mysql.event intact checking end
-#
 
-#
-#INFORMATION_SCHEMA.EVENTS test begin
-#
-create event one_event on schedule every 10 second do select 123;
---replace_column 8 # 9 #
-SHOW EVENTS;
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-CREATE DATABASE events_test2;
-CREATE USER ev_test@localhost;
-GRANT ALL ON events_test.* to ev_test@localhost;
-GRANT ALL on events_test2.* to ev_test@localhost;
-REVOKE EVENT ON events_test2.* FROM ev_test@localhost;
-REVOKE PROCESS on *.* from ev_test@localhost;
-#now we are on con1
-connect (ev_con1,localhost,ev_test,,events_test2);
-select "NEW CONNECTION";
-SELECT USER(), DATABASE();
-SHOW GRANTS;
-
---echo "Here comes an error:";
-#NO EVENT_ACL on events_test2
---error 1044
-SHOW EVENTS;
-USE events_test;
-
---echo "Now the list should be empty:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-#now create an event with the same name but we are different user
-select concat("Let's create some new events from the name of ",user());
-create event one_event on schedule every 20 second do select 123;
-create event two_event on schedule every 20 second on completion not preserve comment
"two event" do select 123;
-create event three_event on schedule every 20 second on completion preserve comment
"three event" do select 123;
-
---echo "Now we should see 3 events:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-
---echo "This should show us only 3 events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS;
-
---echo "This should show us only 2 events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS LIKE 't%event';
-
---echo "This should show us no events:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS FROM test LIKE '%';
-#ok, we are back
-connection default;
-DROP DATABASE events_test2;
-
---echo "should see 1 event:";
---replace_column 8 # 9 #
-SHOW EVENTS;
-
---echo "we should see 4 events now:";
---replace_column 8 # 9 #
-SHOW FULL EVENTS;
-SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_TYPE,
EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT from
information_schema.events;
-
-connection ev_con1;
-drop event one_event;
-drop event two_event;
-drop event three_event;
-disconnect ev_con1;
-connection default;
-drop user ev_test@localhost;
-drop event one_event;
-#
-##INFORMATION_SCHEMA.EVENTS test end
-#
-
---echo "Sleep a bit so the server closes the second connection"
---sleep 2
 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;
--- New file ---
+++ mysql-test/t/events_tamper.test	06/02/20 17:39:37
create database if not exists events_test;
use events_test;
#
# mysql.event intact checking start
#
# There should be at least 1 second between the ALTERs or we can't catch the change of
create_time!!
#
CREATE EVENT intact_check ON SCHEDULE EVERY 10 HOUR DO SELECT "nothing";
--replace_column 8 # 9 #
SHOW EVENTS;
ALTER TABLE mysql.event ADD dummy INT FIRST;
--error 1525
SHOW EVENTS;
ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST;
--error 1525
SHOW EVENTS;
ALTER TABLE mysql.event DROP dummy2;
--replace_column 8 # 9 #
SHOW EVENTS;
CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event;
#sleep a bit or we won't catch the change of time
--sleep 1
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
#wait a bit or we won't see the difference because of seconds resolution
--sleep 1
SHOW CREATE TABLE mysql.event;
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1
ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default '';
--sleep 1
--echo "This should work"
--replace_column 8 # 9 #
SHOW EVENTS;
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default
'';
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP comment, DROP starts;
--sleep 2
--error 1525
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
--echo "Now dropping one index to see whether index tampering check works"
ALTER TABLE mysql.event DROP PRIMARY KEY;
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Recreating, should work now:"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
--echo "Test whether everything is fine"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP INDEX db_definer_name;
SHOW CREATE TABLE mysql.event;
#--sleep 2
#--error 1526
#SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Now let's bork the index and see whether we catch it"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name, definer);
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP KEY db_definer_name;
--echo "Make the key shorter"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, name);
--sleep 2
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event DROP KEY db_definer_name;
--echo "Try with longer index, this should work"
ALTER TABLE mysql.event ADD UNIQUE db_definer_name(db, definer, name, execute_at);
--sleep 2
--echo "No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Add 1 more index, that should not be a problem - downgrading is ok"
ALTER TABLE mysql.event ADD KEY dummy_index(execute_at);
--sleep 2
--echo "No error:"
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--echo "Recreating"
DROP TABLE mysql.event;
CREATE TABLE mysql.event like event_like;
INSERT INTO  mysql.event SELECT * FROM event_like;
DROP TABLE event_like;
--replace_column 8 # 9 #
SHOW EVENTS;
DROP EVENT intact_check;
#
# mysql.event intact checking end
#
drop database events_test;


--- 1.30/sql/event.cc	2006-02-16 13:11:06 +01:00
+++ 1.31/sql/event.cc	2006-02-20 17:39:33 +01:00
@@ -66,10 +66,15 @@ QUEUE EVEX_EQ_NAME;
 MEM_ROOT evex_mem_root;
 time_t mysql_event_last_create_time= 0L;
 
+TABLE_KEY_FOR_CHECK event_table_keys[4]= {
+  { (char *) STRING_WITH_LEN("\x04\x01\x02")    },
+  { (char *) STRING_WITH_LEN("\x01\x04\x02")    },
+  { NULL, 0}
+};
 
-static TABLE_FIELD_W_TYPE event_table_fields[EVEX_FIELD_COUNT] = {
+TABLE_FIELD_W_TYPE event_table_fields[EVEX_FIELD_COUNT] = {
   {
-    {(char *) STRING_WITH_LEN("db")},            
+    {(char *) STRING_WITH_LEN("db")},
     {(char *) STRING_WITH_LEN("char(64)")},
     {(char *) STRING_WITH_LEN("utf8")}
   }, 
@@ -162,25 +167,25 @@ static TABLE_FIELD_W_TYPE event_table_fi
 
 
 LEX_STRING interval_type_to_name[] = {
-  {(char *) STRING_WITH_LEN("YEAR")}, 
-  {(char *) STRING_WITH_LEN("QUARTER")}, 
-  {(char *) STRING_WITH_LEN("MONTH")}, 
-  {(char *) STRING_WITH_LEN("DAY")}, 
-  {(char *) STRING_WITH_LEN("HOUR")}, 
-  {(char *) STRING_WITH_LEN("MINUTE")}, 
-  {(char *) STRING_WITH_LEN("WEEK")}, 
-  {(char *) STRING_WITH_LEN("SECOND")}, 
-  {(char *) STRING_WITH_LEN("MICROSECOND")}, 
-  {(char *) STRING_WITH_LEN("YEAR_MONTH")}, 
-  {(char *) STRING_WITH_LEN("DAY_HOUR")}, 
-  {(char *) STRING_WITH_LEN("DAY_MINUTE")}, 
-  {(char *) STRING_WITH_LEN("DAY_SECOND")}, 
-  {(char *) STRING_WITH_LEN("HOUR_MINUTE")}, 
-  {(char *) STRING_WITH_LEN("HOUR_SECOND")}, 
-  {(char *) STRING_WITH_LEN("MINUTE_SECOND")}, 
-  {(char *) STRING_WITH_LEN("DAY_MICROSECOND")}, 
-  {(char *) STRING_WITH_LEN("HOUR_MICROSECOND")}, 
-  {(char *) STRING_WITH_LEN("MINUTE_MICROSECOND")}, 
+  {(char *) STRING_WITH_LEN("YEAR")},
+  {(char *) STRING_WITH_LEN("QUARTER")},
+  {(char *) STRING_WITH_LEN("MONTH")},
+  {(char *) STRING_WITH_LEN("DAY")},
+  {(char *) STRING_WITH_LEN("HOUR")},
+  {(char *) STRING_WITH_LEN("MINUTE")},
+  {(char *) STRING_WITH_LEN("WEEK")},
+  {(char *) STRING_WITH_LEN("SECOND")},
+  {(char *) STRING_WITH_LEN("MICROSECOND")},
+  {(char *) STRING_WITH_LEN("YEAR_MONTH")},
+  {(char *) STRING_WITH_LEN("DAY_HOUR")},
+  {(char *) STRING_WITH_LEN("DAY_MINUTE")},
+  {(char *) STRING_WITH_LEN("DAY_SECOND")},
+  {(char *) STRING_WITH_LEN("HOUR_MINUTE")},
+  {(char *) STRING_WITH_LEN("HOUR_SECOND")},
+  {(char *) STRING_WITH_LEN("MINUTE_SECOND")},
+  {(char *) STRING_WITH_LEN("DAY_MICROSECOND")},
+  {(char *) STRING_WITH_LEN("HOUR_MICROSECOND")},
+  {(char *) STRING_WITH_LEN("MINUTE_MICROSECOND")},
   {(char *) STRING_WITH_LEN("SECOND_MICROSECOND")}
 }; 
 
@@ -369,7 +374,7 @@ event_reconstruct_interval_expression(St
     goto common_1_lev_code;
   case INTERVAL_HOUR_MINUTE:
   case INTERVAL_MINUTE_SECOND:
-    multipl= 60;      
+    multipl= 60;
 common_1_lev_code:
     buf->append('\'');
     end= longlong10_to_str(expression/multipl, tmp_buff, 10);
@@ -410,7 +415,7 @@ common_1_lev_code:
     expr= tmp_expr - (tmp_expr/60)*60;
     /* the code after the switch will finish */
   }
-    break;      
+    break;
   case INTERVAL_DAY_SECOND:
   {
     int tmp_expr= expr;
@@ -493,7 +498,7 @@ evex_open_event_table(THD *thd, enum thr
     DBUG_RETURN(1);
   
   if (table_check_intact(tables.table, EVEX_FIELD_COUNT, event_table_fields,
-                         &mysql_event_last_create_time,
+                         event_table_keys, &mysql_event_last_create_time,
                          ER_EVENT_CANNOT_LOAD_FROM_TABLE))
   {
     close_thread_tables(thd);
@@ -593,7 +598,7 @@ evex_db_find_event_by_name(THD *thd, con
    Returns
      0 - ok
      EVEX_GENERAL_ERROR    - bad data
-     EVEX_GET_FIELD_FAILED - field count does not match. table corrupted? 
+     EVEX_GET_FIELD_FAILED - field count does not match. table corrupted?
 
    DESCRIPTION 
      Used both when an event is created and when it is altered.
@@ -641,7 +646,7 @@ evex_fill_row(THD *thd, TABLE *table, ev
     table->field[EVEX_FIELD_ENDS]->
                           store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
   }
-   
+
   if (et->expression)
   {
     table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull();
@@ -664,8 +669,8 @@ evex_fill_row(THD *thd, TABLE *table, ev
 
     table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull();
     table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at,
-                                                    MYSQL_TIMESTAMP_DATETIME);    
-    
+                                                    MYSQL_TIMESTAMP_DATETIME);
+
     table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null();  
   }
   else
@@ -674,7 +679,7 @@ evex_fill_row(THD *thd, TABLE *table, ev
     // it is normal to be here when the action is update
     // this is an error if the action is create. something is borked
   }
-    
+
   ((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time();
 
   if (et->comment.length)
@@ -698,7 +703,7 @@ trunc_err:
        et              event_timed object containing information for the event
        create_if_not - if an warning should be generated in case event exists
        rows_affected - how many rows were affected
-   
+
      Return value
                         0 - OK
        EVEX_GENERAL_ERROR - Failure
@@ -726,7 +731,7 @@ db_create_event(THD *thd, event_timed *e
     my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
     goto err;
   }
-  
+
   DBUG_PRINT("info", ("check existance of an event with the same name"));
   if (!evex_db_find_event_aux(thd, et, table))
   {
@@ -735,7 +740,7 @@ db_create_event(THD *thd, event_timed *e
       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 		          ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
 		          et->name.str);
-      goto ok;    
+      goto ok;
     }
     my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
     goto err;
@@ -747,7 +752,7 @@ db_create_event(THD *thd, event_timed *e
     my_error(ER_BAD_DB_ERROR, MYF(0));
     goto err;
   }
-  
+
   restore_record(table, s->default_values); // Get default values for fields
 
   if (system_charset_info->cset->numchars(system_charset_info, et->dbname.str,
@@ -831,7 +836,7 @@ err:
        thd      THD
        sp_name  the name of the event to alter
        et       event's data
-   
+
    NOTES
      sp_name is passed since this is the name of the event to
      alter in case of RENAME TO.
@@ -931,7 +936,7 @@ err:
        definer  who owns the event
        ett      event's data if event is found
        tbl      TABLE object to use when not NULL
-   
+
    NOTES
      1) Use sp_name for look up, return in **ett if found
      2) tbl is not closed at exit
@@ -967,7 +972,7 @@ db_find_event(THD *thd, sp_name *name, L
     goto done;    
   }
   et= new event_timed;
-  
+
   /*
     1)The table should not be closed beforehand.  ::load_from_row() only loads
       and does not compile
@@ -1146,7 +1151,7 @@ done:
        create_options Options specified when in the query. We are
                       interested whether there is IF NOT EXISTS
        rows_affected  How many rows were affected
-          
+ 
    NOTES
      - in case there is an event with the same name (db) and 
        IF NOT EXISTS is specified, an warning is put into the W stack.
@@ -1190,7 +1195,7 @@ done:
        thd        THD
        et         event's data
        new_name   set in case of RENAME TO.    
-          
+
    NOTES
      et contains data about dbname and event name. 
      new_name is the new name of the event, if not null (this means
@@ -1312,7 +1317,7 @@ done:
      et              event's name
      drop_if_exists  if set and the event not existing => warning onto the stack
      rows_affected   affected number of rows is returned heres
-          
+
 */
 
 int
@@ -1349,11 +1354,11 @@ evex_drop_event(THD *thd, event_timed *e
        thd        THD
        spn        the name of the event (db, name)
        definer    the definer of the event
-   
+
    RETURNS
      0  -  OK
      1  - Error during writing to the wire
-          
+
 */
 
 int
@@ -1378,7 +1383,7 @@ evex_show_create_event(THD *thd, sp_name
     List<Item> field_list;
     const char *sql_mode_str;
     ulong sql_mode_len=0;
-    
+
     show_str.length(0);
     show_str.set_charset(system_charset_info);
 
@@ -1404,19 +1409,19 @@ evex_show_create_event(THD *thd, sp_name
 
     protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
 
-    
+
     protocol->store(show_str.c_ptr(), show_str.length(), system_charset_info);
     ret= protocol->write();
     send_eof(thd);
   }
-  
+
   DBUG_RETURN(ret);
 }
 
 
 /*
   evex_drop_db_events - Drops all events in the selected database
-  
+
   thd  - Thread
   db   - ASCIIZ the name of the database
   
@@ -1447,12 +1452,11 @@ int
 evex_drop_db_events(THD *thd, char *db)
 {
   TABLE *table;
-  READ_RECORD read_record_info;
-  MYSQL_LOCK *lock;
   int ret= 0;
   uint i;
+  uint key_len= 0;
+  byte *key_buf= NULL;
   LEX_STRING db_lex= {db, strlen(db)};
-  
   DBUG_ENTER("evex_drop_db_events");  
   DBUG_PRINT("info",("dropping events from %s", db));
 
@@ -1537,58 +1541,72 @@ skip_memory:
   */
   DBUG_PRINT("info",("Mem-cache checked, now going to db for disabled events"));
   /* only enabled events are in memory, so we go now and delete the rest */
-  init_read_record(&read_record_info, thd, table ,NULL,1,0);
-  while (!(read_record_info.read_record(&read_record_info)) && !ret)
+
+
+  table->file->ha_index_init(1, 1);
+
+  DBUG_ASSERT(db);
+  DBUG_PRINT("info",("Using  `%s` in the prefix", db));
+  table->field[EVEX_FIELD_DB]->store(db, strlen(db), system_charset_info);
+  key_len= table->key_info[1].key_part[0].store_length;
+  
+  if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+  {
+    ret= 1;
+    goto end;
+  }
+    
+  key_copy(key_buf, table->record[0], table->key_info + 1, key_len);
+  ret= table->file->index_read(table->record[0], key_buf, key_len,
+                               HA_READ_PREFIX);
+  if (ret)
   {
-    char *et_db;
+    ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
+    goto end;
+  }
 
-    if ((et_db= get_field(thd->mem_root, table->field[EVEX_FIELD_DB])) == NULL)
+  while (!ret)
+  {
+    char *ptr;
+      
+    if ((ptr= get_field(thd->mem_root, table->field[EVEX_FIELD_STATUS]))
+         == NullS)
     {
-      ret= 2;
-      break;
+      sql_print_error("Error while loading from mysql.event. "
+                      "Table probably corrupted");
+      goto end;
     }
-    
-    LEX_STRING et_db_lex= {et_db, strlen(et_db)};
-    if (!sortcmp_lex_string(et_db_lex, db_lex, system_charset_info))
+    /*
+      When not running nothing is in memory so we have to clean
+      everything.
+      We don't delete EVENT_ENABLED events when the scheduler is running
+      because maybe this is an event which we asked to drop itself when
+      it is finished and it hasn't finished yet, so we don't touch it.
+      It will drop itself. The not running ENABLED events has been already
+      deleted from ha_delete_row() above in the loop over the QUEUE
+      (in case the executor is running).
+      'D' stands for DISABLED, 'E' for ENABLED - it's an enum
+    */
+    if ((evex_is_running && ptr[0] == 'D') || !evex_is_running)
     {
-      event_timed ett;
-      char *ptr;
-      
-      if ((ptr= get_field(thd->mem_root, table->field[EVEX_FIELD_STATUS]))
-           == NullS)
+      char *name= get_field(thd->mem_root, table->field[EVEX_FIELD_NAME]);
+
+      if ((ret= table->file->ha_delete_row(table->record[0])))
       {
-        sql_print_error("Error while loading from mysql.event. "
-                        "Table probably corrupted");
+        my_error(ER_EVENT_DROP_FAILED, MYF(0), name);
         goto end;
       }
-      /*
-        When not running nothing is in memory so we have to clean
-        everything.
-        We don't delete EVENT_ENABLED events when the scheduler is running
-        because maybe this is an event which we asked to drop itself when
-        it is finished and it hasn't finished yet, so we don't touch it.
-        It will drop itself. The not running ENABLED events has been already
-        deleted from ha_delete_row() above in the loop over the QUEUE
-        (in case the executor is running).
-        'D' stands for DISABLED, 'E' for ENABLED - it's an enum
-      */
-      if ((evex_is_running && ptr[0] == 'D') || !evex_is_running)
-      {
-        DBUG_PRINT("info", ("Dropping %s.%s", et_db, ett.name.str));
-        if ((ret= table->file->ha_delete_row(table->record[0])))
-        {
-          my_error(ER_EVENT_DROP_FAILED, MYF(0), ett.name.str);
-          goto end;
-        }
-      }
     }
+    table->file->index_next_same(table->record[0], key_buf, key_len);    
   }
-  DBUG_PRINT("info",("Disk checked for disabled events. Finishing."));
+  // ret is guaranteed to be != 0
+  ret= (ret != HA_ERR_END_OF_FILE);
 
+  DBUG_PRINT("info",("Disk checked for disabled events. Finishing."));
 end:
   VOID(pthread_mutex_unlock(&LOCK_evex_running));
   VOID(pthread_mutex_unlock(&LOCK_event_arrays));
-  end_read_record(&read_record_info);
+  table->file->ha_index_end();
 
   thd->version--;  // Force close to free memory
 

--- 1.30/sql/event_executor.cc	2006-02-16 01:27:30 +01:00
+++ 1.31/sql/event_executor.cc	2006-02-20 17:39:33 +01:00
@@ -151,7 +151,8 @@ evex_check_system_tables()
   else
   {
     table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT, mysql_db_table_fields,
-                     &mysql_db_table_last_check,ER_EVENT_CANNOT_LOAD_FROM_TABLE);    
                      
+                       NULL, &mysql_db_table_last_check,
+                       ER_EVENT_CANNOT_LOAD_FROM_TABLE);
     close_thread_tables(thd);
   }
 
@@ -377,7 +378,6 @@ executor_wait_till_next_event_exec(THD *
   DBUG_RETURN(ret);
 }
 
-
 /*
    The main scheduler thread. Inits the priority queue on start and
    destroys it on thread shutdown. Forks child threads for every event
@@ -402,12 +402,12 @@ event_executor_main(void *arg)
   TIME time_now;
 
   DBUG_ENTER("event_executor_main");
-  DBUG_PRINT("event_executor_main", ("EVEX thread started"));    
+  DBUG_PRINT("event_executor_main", ("EVEX thread started"));
 
+  sql_print_information("SCHEDULER: Starting");
 
   // init memory root
   init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
-  
 
   // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
   my_thread_init();
@@ -643,9 +643,9 @@ finish:
 
 err_no_thd:
   VOID(pthread_mutex_lock(&LOCK_evex_running));
-  evex_is_running= false;  
+  evex_is_running= false;
+  event_executor_running_global_var= false;
   VOID(pthread_mutex_unlock(&LOCK_evex_running));
-
   free_root(&evex_mem_root, MYF(0));
   sql_print_information("SCHEDULER: Stopped.");
 

--- 1.24/mysql-test/lib/init_db.sql	2006-02-01 19:27:04 +01:00
+++ 1.25/mysql-test/lib/init_db.sql	2006-02-20 17:39:32 +01:00
@@ -631,7 +631,8 @@ CREATE TABLE event (
                         'HIGH_NOT_PRECEDENCE'
                     ) DEFAULT '' NOT NULL,
   comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
-  PRIMARY KEY  (definer, db, name)
+  PRIMARY KEY  (definer, db, name),
+  UNIQUE KEY db_definer_name(db, definer, name)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
 
 CREATE DATABASE IF NOT EXISTS cluster_replication;

--- 1.40/scripts/mysql_fix_privilege_tables.sql	2006-02-02 11:35:58 +01:00
+++ 1.41/scripts/mysql_fix_privilege_tables.sql	2006-02-20 17:39:33 +01:00
@@ -622,7 +622,8 @@ CREATE TABLE event (
                         'HIGH_NOT_PRECEDENCE'
                     ) DEFAULT '' NOT NULL,
   comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
-  PRIMARY KEY  (db,name)
+  PRIMARY KEY  (db,name),
+  UNIQUE KEY db_definer_name(db, definer, name)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
 
 
@@ -666,7 +667,7 @@ ALTER TABLE event ADD sql_mode
                             'NO_AUTO_CREATE_USER',
                             'HIGH_NOT_PRECEDENCE'
                             ) DEFAULT '' NOT NULL AFTER on_completion;
-
+ALTER TABLE event ADD UNIQUE KEY db_definer_name(db, definer, name);
 --
 -- TRIGGER privilege
 --

--- 1.38/mysql-test/r/system_mysql_db.result	2006-02-02 11:35:57 +01:00
+++ 1.39/mysql-test/r/system_mysql_db.result	2006-02-20 17:39:32 +01:00
@@ -208,7 +208,8 @@ event	CREATE TABLE `event` (
   `on_completion` enum('DROP','PRESERVE') NOT NULL default 'DROP',
   `sql_mode`
set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE')
NOT NULL default '',
   `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
-  PRIMARY KEY  (`definer`,`db`,`name`)
+  PRIMARY KEY  (`definer`,`db`,`name`),
+  UNIQUE KEY `db_definer_name` (`db`,`definer`,`name`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events'
 show create table general_log;
 Table	Create Table

--- 1.37/scripts/mysql_create_system_tables.sh	2006-02-01 11:28:40 +01:00
+++ 1.38/scripts/mysql_create_system_tables.sh	2006-02-20 17:39:33 +01:00
@@ -827,7 +827,8 @@ then
   c_ev="$c_ev                         'HIGH_NOT_PRECEDENCE'"
   c_ev="$c_ev                     ) DEFAULT '' NOT NULL,"
   c_ev="$c_ev   comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default
'',"
-  c_ev="$c_ev   PRIMARY KEY  (definer, db, name)"
+  c_ev="$c_ev   PRIMARY KEY  (definer, db, name),"
+  c_ev="$c_ev   UNIQUE KEY db_definer_name(db, definer, name)"
   c_ev="$c_ev ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';"
 fi
 
Thread
bk commit into 5.1 tree (andrey:1.2122) BUG#16992ahristov20 Feb