MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:March 9 2006 3:27am
Subject:bk commit into 5.1 tree (cmiller:1.2160) BUG#17714
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of cmiller. When cmiller 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.2160 06/03/08 22:27:00 cmiller@stripped +4 -0
  Added code to mysqldump to dump timed events when instructed to do so, with
  the '-E' or '--events' flag.  (Closes Bug#16853 and Bug#17714.)
  
  
  WARNING:
  
  At present, these tests fail due to b*g number 18078.

  sql/event_timed.cc
    1.46 06/03/08 22:26:48 cmiller@stripped +0 -2
    No longer qualify SHOW CREATE EVENT names with the database name.

  mysql-test/t/mysqldump.test
    1.91 06/03/08 22:26:47 cmiller@stripped +40 -0
    Added a test to create an event, dump it, restore it, add more events, dump
    all of them, and restore all of them.

  mysql-test/r/mysqldump.result
    1.101 06/03/08 22:26:46 cmiller@stripped +37 -0
    Added a test to create an event, dump it, restore it, add more events, dump
    all of them, and restore all of them.

  client/mysqldump.c
    1.230 06/03/08 22:26:45 cmiller@stripped +148 -6
    Added code to dump events, when asked to do so via the --events parameter.
    
    Also cleaned up some surrounding code.

# 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:	cmiller
# Host:	calliope.local
# Root:	/Users/cmiller/work/src/mysql-5.1-new__cleanup_mysqldump

--- 1.229/client/mysqldump.c	2006-02-23 10:11:41 -05:00
+++ 1.230/client/mysqldump.c	2006-03-08 22:26:45 -05:00
@@ -95,6 +95,7 @@
                 opt_complete_insert= 0, opt_drop_database= 0,
                 opt_replace_into= 0,
                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+                opt_events= 0,
                 opt_alltspcs=0;
 static ulong opt_max_allowed_packet, opt_net_buffer_length;
 static MYSQL mysql_connection,*sock=0;
@@ -231,6 +232,9 @@
   {"disable-keys", 'K',
    "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
    (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+  {"events", 'E', "Dump events.",
+     (gptr*) &opt_events, (gptr*) &opt_events, 0, GET_BOOL,
+     NO_ARG, 0, 0, 0, 0, 0, 0},
   {"extended-insert", 'e',
    "Allows utilization of the new, much faster INSERT syntax.",
    (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
@@ -1238,9 +1242,136 @@
   check_io(xml_file);
 }
 
+
+/*
+ create_delimiter
+ Generate a new (null-terminated) string that does not exist in  query 
+ and is therefore suitable for use as a query delimiter.  Store this
+ delimiter in  delimiter_buff .
+ 
+ This is quite simple in that it doesn't even try to parse statements as an
+ interpreter would.  It merely returns a string that is not in the query, which
+ is much more than adequate for constructing a delimiter.
+
+ RETURN
+   ptr to the delimiter  on Success
+   NULL                  on Failure
+*/
+static char *create_delimiter(char *query, char *delimiter_buff, 
+                              int delimiter_max_size) 
+{
+  int proposed_length;
+  char *presence;
+
+  delimiter_buff[0]= ';';  /* start with one semicolon, and */
+
+  for (proposed_length= 2; proposed_length < delimiter_max_size; 
+      delimiter_max_size++) {
+
+    delimiter_buff[proposed_length-1]= ';';  /* add semicolons, until */
+    delimiter_buff[proposed_length]= '\0';
+
+    presence = strstr(query, delimiter_buff);
+    if (presence == NULL) { /* the proposed delimiter is not in the query. */
+       return delimiter_buff;
+    }
+
+  }
+  return NULL;  /* but if we run out of space, return nothing at all. */
+}
+
+
+/*
+  dump_events_for_db
+  -- retrieves list of events for a given db, and prints out
+  the CREATE EVENT statement into the output (the dump).
+
+  RETURN
+    0  Success
+    1  Error
+*/
+static uint dump_events_for_db(char *db)
+{
+  char       query_buff[QUERY_LENGTH];
+  char       db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
+  char       *event_name;
+  char       delimiter[QUERY_LENGTH], *delimit_test;
+  FILE       *sql_file= md_result_file;
+  MYSQL_RES  *event_res, *event_list_res;
+  MYSQL_ROW  row, event_list_row;
+  DBUG_ENTER("dump_events_for_db");
+  DBUG_PRINT("enter", ("db: '%s'", db));
+
+  mysql_real_escape_string(sock, db_name_buff, db, strlen(db));
+
+  /* nice comments */
+  if (opt_comments)
+    fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db);
+
+  /*
+    not using "mysql_query_with_error_report" because we may have not
+    enough privileges to lock mysql.events.
+  */
+  if (lock_tables)
+    mysql_query(sock, "LOCK TABLES mysql.event READ");
+
+  if (mysql_query_with_error_report(sock, &event_list_res, "show events"))
+  {
+    safe_exit(EX_MYSQLERR);
+    DBUG_RETURN(0);
+  }
+
+  strcpy(delimiter, ";");
+  if (mysql_num_rows(event_list_res) > 0)
+  {
+    while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
+    {
+      event_name= quote_name(event_list_row[1], name_buff, 0);
+      DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
+      my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s", 
+          event_name);
+
+      if (mysql_query_with_error_report(sock, &event_res, query_buff))
+        DBUG_RETURN(1);
+
+      while ((row= mysql_fetch_row(event_res)) != NULL)
+      {
+        /*
+          if the user has EXECUTE privilege he can see event names, but not the
+          event body!
+        */
+        if (strlen(row[2]) != 0)
+        {
+          if (opt_drop)
+            fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", 
+                event_name, delimiter);
+
+          delimit_test= create_delimiter(row[2], delimiter, sizeof(delimiter)); 
+          if (delimit_test == NULL) {
+            fprintf(stderr, "%s: Warning: Can't dump event '%s'\n", 
+                event_name, my_progname);
+            DBUG_RETURN(1);
+          }
+
+          fprintf(sql_file, "DELIMITER %s\n", delimiter);
+          fprintf(sql_file, "/*!50106 %s */ %s\n", row[2], delimiter);
+        }
+      } /* end of event printing */
+    } /* end of list of events */
+    fprintf(sql_file, "DELIMITER ;\n");
+    mysql_free_result(event_res);
+  }
+  mysql_free_result(event_list_res);
+
+  if (lock_tables)
+    VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
+  DBUG_RETURN(0);
+}
+
+
 /*
   dump_routines_for_db
-  -- retrievs list of routines for a given db, and prints out
+  -- retrieves list of routines for a given db, and prints out
   the CREATE PROCEDURE definition into the output (the dump).
 
   This function has logic to print the appropriate syntax depending on whether
@@ -1253,7 +1384,7 @@
 
 static uint dump_routines_for_db(char *db)
 {
-  char       query_buff[512];
+  char       query_buff[QUERY_LENGTH];
   const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
   char       db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
   char       *routine_name;
@@ -1294,9 +1425,9 @@
 
       while ((routine_list_row= mysql_fetch_row(routine_list_res)))
       {
+        routine_name= quote_name(routine_list_row[1], name_buff, 0);
         DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
                             name_buff));
-        routine_name= quote_name(routine_list_row[1], name_buff, 0);
         my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
                     routine_type[i], routine_name);
 
@@ -1364,7 +1495,7 @@
   char	     *result_table, *opt_quoted_table;
   const char *insert_option;
   char	     name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
-  char	     table_buff2[NAME_LEN*2+3], query_buff[512];
+  char	     table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
   FILE       *sql_file = md_result_file;
   int        len;
   MYSQL_RES  *result;
@@ -1840,7 +1971,7 @@
 {
   char	     *result_table;
   char	     name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
-  char       query_buff[512];
+  char       query_buff[QUERY_LENGTH];
   uint old_opt_compatible_mode=opt_compatible_mode;
   FILE       *sql_file = md_result_file;
   MYSQL_RES  *result;
@@ -2500,7 +2631,6 @@
 {
   MYSQL_ROW row;
   MYSQL_RES *tableres;
-  int result=0;
   char buf[FN_REFLEN];
   int first;
 
@@ -2798,6 +2928,12 @@
         dump_triggers_for_table(table, database);
     }
   }
+  if (opt_events && !opt_xml &&
+      mysql_get_server_version(sock) >= 50106)
+  {
+    DBUG_PRINT("info", ("Dumping events for database %s", database));
+    dump_events_for_db(database);
+  }
   if (opt_routines && !opt_xml &&
       mysql_get_server_version(sock) >= 50009)
   {
@@ -3007,6 +3143,12 @@
       table_name= hash_element(&dump_tables, i);
       get_view_structure(table_name, db);
     }
+  }
+  if (opt_events && !opt_xml &&
+      mysql_get_server_version(sock) >= 50106)
+  {
+    DBUG_PRINT("info", ("Dumping events for database %s", db));
+    dump_events_for_db(db);
   }
   /* obtain dump of routines (procs/functions) */
   if (opt_routines  && !opt_xml &&

--- 1.45/sql/event_timed.cc	2006-03-02 15:01:56 -05:00
+++ 1.46/sql/event_timed.cc	2006-03-08 22:26:48 -05:00
@@ -1063,8 +1063,6 @@
     DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
 
   buf->append(STRING_WITH_LEN("CREATE EVENT "));
-  append_identifier(thd, buf, dbname.str, dbname.length);
-  buf->append(STRING_WITH_LEN("."));
   append_identifier(thd, buf, name.str, name.length);
 
   buf->append(STRING_WITH_LEN(" ON SCHEDULE "));

--- 1.100/mysql-test/r/mysqldump.result	2006-03-06 05:35:33 -05:00
+++ 1.101/mysql-test/r/mysqldump.result	2006-03-08 22:26:46 -05:00
@@ -2907,3 +2907,40 @@
 drop table t1;
 drop table t2;
 drop table words2;
+create database first;
+use first;
+set time_zone = 'UTC';
+create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;
+show events;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+first	ee1	root@localhost	ONE TIME	2035-12-31 20:01:23	NULL	NULL	NULL	NULL	ENABLED
+show create event ee1;
+Event	sql_mode	Create Event
+ee1		CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5
+drop database first;
+create database second;
+use second;
+show events;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+second	ee1	root@localhost	ONE TIME	2035-12-31 20:01:23	NULL	NULL	NULL	NULL	ENABLED
+show create event ee1;
+Event	sql_mode	Create Event
+ee1	NO_AUTO_VALUE_ON_ZERO	CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5
+create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
+create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
+show events;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+second	ee1	root@localhost	ONE TIME	2035-12-31 20:01:23	NULL	NULL	NULL	NULL	ENABLED
+second	ee2	root@localhost	ONE TIME	2018-12-31 21:01:23	NULL	NULL	NULL	NULL	ENABLED
+second	ee3	root@localhost	ONE TIME	2030-12-31 22:01:23	NULL	NULL	NULL	NULL	ENABLED
+drop database second;
+create database third;
+use third;
+show events;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+third	ee1	root@localhost	ONE TIME	2035-12-31 20:01:23	NULL	NULL	NULL	NULL	ENABLED
+third	ee2	root@localhost	ONE TIME	2018-12-31 21:01:23	NULL	NULL	NULL	NULL	ENABLED
+third	ee3	root@localhost	ONE TIME	2030-12-31 22:01:23	NULL	NULL	NULL	NULL	ENABLED
+drop database third;
+set time_zone = 'SYSTEM';
+use test;

--- 1.90/mysql-test/t/mysqldump.test	2006-02-28 17:22:05 -05:00
+++ 1.91/mysql-test/t/mysqldump.test	2006-03-08 22:26:47 -05:00
@@ -1166,3 +1166,43 @@
 drop table t2;
 
 drop table words2;
+
+#
+# BUG# 16853: mysqldump doesn't show events
+#
+create database first;
+use first;
+set time_zone = 'UTC';
+
+## prove one works
+create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;
+show events;
+show create event ee1;
+--exec $MYSQL_DUMP --events first > $MYSQLTEST_VARDIR/tmp/bug16853-1.sql
+drop database first;
+
+create database second;
+use second;
+--exec $MYSQL second < $MYSQLTEST_VARDIR/tmp/bug16853-1.sql
+show events;
+show create event ee1;
+
+## prove three works
+# start with one from the previous restore
+create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
+create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
+show events;
+--exec $MYSQL_DUMP --events second > $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
+drop database second;
+
+create database third;
+use third;
+--exec $MYSQL third < $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
+show events;
+drop database third;
+
+# revert back to normal settings
+set time_zone = 'SYSTEM';
+use test;
+
+#####
Thread
bk commit into 5.1 tree (cmiller:1.2160) BUG#17714Chad MILLER9 Mar