List:Commits« Previous MessageNext Message »
From:Patrick Galbraith Date:April 8 2006 9:47pm
Subject:bk commit into 5.1 tree (patg:1.2301)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of patg. When patg 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.2301 06/04/08 14:47:25 patg@stripped +15 -0
  Merge pgalbraith@stripped:/home/bk/mysql-5.1-new
  into  govinda.patg.net:/home/patg/mysql-build/mysql-5.1-wl3031

  sql/sql_yacc.yy
    1.452 06/04/08 14:47:21 patg@stripped +0 -0
    WL# 3031
    
    Merge conflicts

  sql/sql_lex.cc
    1.176 06/04/08 14:47:21 patg@stripped +0 -0
    WL# 3031
    
    Merge conflicts

  sql/share/errmsg.txt
    1.91 06/04/08 14:47:20 patg@stripped +0 -0
    WL# 3031
    
    Merge conflicts

  sql/ha_federated.cc
    1.57 06/04/08 14:47:20 patg@stripped +0 -6
    WL# 3031
    
    Merge conflicts

  sql/Makefile.am
    1.132 06/04/08 14:47:20 patg@stripped +1 -4
    WL# 3031
    
    Merge conflicts

  libmysqld/Makefile.am
    1.81 06/04/08 14:47:20 patg@stripped +0 -1
    WL# 3031
    
    Merge conflicts to catch up after 7 weeks to current tree! 

  sql/sql_parse.cc
    1.519 06/04/08 14:08:51 patg@stripped +0 -0
    Auto merged

  sql/sql_lex.h
    1.218 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  sql/sql_acl.cc
    1.189 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  sql/mysqld.cc
    1.554 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.391 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  sql/lex.h
    1.155 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  sql/ha_federated.h
    1.28 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  scripts/mysql_create_system_tables.sh
    1.40 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

  mysql-test/lib/init_db.sql
    1.27 06/04/08 14:08:50 patg@stripped +0 -0
    Auto merged

# 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:	patg
# Host:	govinda.patg.net
# Root:	/home/patg/mysql-build/mysql-5.1-wl3031/RESYNC

--- 1.131/sql/Makefile.am	2006-02-09 18:28:58 -08:00
+++ 1.132/sql/Makefile.am	2006-04-08 14:47:20 -07:00
@@ -65,7 +65,7 @@
 			sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
 			parse_file.h sql_view.h	sql_trigger.h \
 			sql_array.h sql_cursor.h event.h event_priv.h \
-			sql_plugin.h authors.h \
+			sql_plugin.h authors.h sql_partition.h \
 			sql_servers.h
 mysqld_SOURCES =	sql_lex.cc sql_handler.cc sql_partition.cc \
 			item.cc item_sum.cc item_buff.cc item_func.cc \
@@ -103,7 +103,7 @@
                         event_executor.cc event.cc event_timed.cc \
 			sql_plugin.cc sql_binlog.cc \
 			handlerton.cc sql_tablespace.cc \
-			sql_servers.cc
+			handlerton.cc sql_tablespace.cc partition_info.cc
 EXTRA_mysqld_SOURCES =	ha_innodb.cc ha_berkeley.cc ha_archive.cc \
 			ha_innodb.h  ha_berkeley.h  ha_archive.h \
 			ha_blackhole.cc ha_federated.cc ha_ndbcluster.cc \
@@ -125,7 +125,8 @@
 			@DEFS@
 
 BUILT_SOURCES =		sql_yacc.cc sql_yacc.h lex_hash.h
-EXTRA_DIST =		udf_example.cc handlerton-win.cc $(BUILT_SOURCES)
+EXTRA_DIST =		udf_example.cc $(BUILT_SOURCES) \
+			nt_servc.cc nt_servc.h message.mc cmakelists.txt
 CLEANFILES =        	lex_hash.h sql_yacc.cc sql_yacc.h
 AM_YFLAGS =		-d
 
@@ -175,10 +176,11 @@
 handler.o:	handler.cc ha_ndbcluster.h
 		$(CXXCOMPILE) @ndbcluster_includes@ $(CXXFLAGS) -c $<
 
-# For testing of udf_example.so;  Works on platforms with gcc
-# (This is not part of our build process but only provided as an example)
-udf_example.so:	udf_example.cc
-		$(CXXCOMPILE) -shared -o $@ $<
+# For testing of udf_example.so
+noinst_LTLIBRARIES= udf_example.la
+udf_example_la_SOURCES= udf_example.cc
+udf_example_la_LDFLAGS= -module -rpath $(pkglibdir)
+
 
 # Don't update the files from bitkeeper
 %::SCCS/s.%

--- 1.154/sql/lex.h	2006-01-31 16:33:23 -08:00
+++ 1.155/sql/lex.h	2006-04-08 14:08:50 -07:00
@@ -394,10 +394,12 @@
   { "PARSER",           SYM(PARSER_SYM)},
   { "PARTIAL",		SYM(PARTIAL)},
   { "PARTITION",        SYM(PARTITION_SYM)},
+  { "PARTITIONING",     SYM(PARTITIONING_SYM)},
   { "PARTITIONS",       SYM(PARTITIONS_SYM)},
   { "PASSWORD",		SYM(PASSWORD)},
   { "PHASE",            SYM(PHASE_SYM)},
   { "PLUGIN",           SYM(PLUGIN_SYM)},
+  { "PLUGINS",          SYM(PLUGINS_SYM)},
   { "POINT",		SYM(POINT_SYM)},
   { "POLYGON",		SYM(POLYGON)},
   { "PORT",		SYM(PORT_SYM)},
@@ -414,10 +416,6 @@
   { "QUARTER",          SYM(QUARTER_SYM)},
   { "QUERY",		SYM(QUERY_SYM)},
   { "QUICK",	        SYM(QUICK)},
-  { "RAID0",		SYM(RAID_0_SYM)},
-  { "RAID_CHUNKS",	SYM(RAID_CHUNKS)},
-  { "RAID_CHUNKSIZE",	SYM(RAID_CHUNKSIZE)},
-  { "RAID_TYPE",	SYM(RAID_TYPE)},
   { "RANGE",            SYM(RANGE_SYM)},
   { "READ",		SYM(READ_SYM)},
   { "READ_ONLY",	SYM(READ_ONLY_SYM)},
@@ -436,6 +434,7 @@
   { "RELAY_THREAD",     SYM(RELAY_THREAD)},
   { "RELEASE",		SYM(RELEASE_SYM)},
   { "RELOAD",		SYM(RELOAD)},
+  { "REMOVE",		SYM(REMOVE_SYM)},
   { "RENAME",		SYM(RENAME)},
   { "REORGANIZE",	SYM(REORGANIZE_SYM)},
   { "REPAIR",		SYM(REPAIR)},
@@ -518,7 +517,6 @@
   { "STORAGE",		SYM(STORAGE_SYM)},
   { "STRAIGHT_JOIN",	SYM(STRAIGHT_JOIN)},
   { "STRING",		SYM(STRING_SYM)},
-  { "STRIPED",		SYM(RAID_STRIPED_SYM)},
   { "SUBJECT",		SYM(SUBJECT_SYM)},
   { "SUBPARTITION",     SYM(SUBPARTITION_SYM)},
   { "SUBPARTITIONS",    SYM(SUBPARTITIONS_SYM)},
@@ -563,6 +561,7 @@
   { "UNSIGNED",		SYM(UNSIGNED)},
   { "UNTIL",		SYM(UNTIL_SYM)},
   { "UPDATE",		SYM(UPDATE_SYM)},
+  { "UPGRADE",          SYM(UPGRADE_SYM)},
   { "USAGE",		SYM(USAGE)},
   { "USE",		SYM(USE_SYM)},
   { "USER",		SYM(USER)},

--- 1.390/sql/mysql_priv.h	2006-04-07 00:13:20 -07:00
+++ 1.391/sql/mysql_priv.h	2006-04-08 14:08:50 -07:00
@@ -568,6 +568,7 @@
 #include "tztime.h"
 #ifdef MYSQL_SERVER
 #include "opt_range.h"
+#include "sql_servers.h"
 
 #ifdef HAVE_QUERY_CACHE
 struct Query_cache_query_flags

--- 1.553/sql/mysqld.cc	2006-04-03 01:25:22 -07:00
+++ 1.554/sql/mysqld.cc	2006-04-08 14:08:50 -07:00
@@ -1151,6 +1151,7 @@
   my_tz_free();
   my_database_names_free();
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
+  servers_free(1);
   acl_free(1);
   grant_free();
 #endif
@@ -3627,6 +3628,10 @@
   }
   if (!opt_noacl)
     (void) grant_init();
+
+  if (servers_init(0))
+  {
+  }
 
   if (!opt_noacl)
   {

--- 1.188/sql/sql_acl.cc	2006-03-29 03:27:31 -08:00
+++ 1.189/sql/sql_acl.cc	2006-04-08 14:08:50 -07:00
@@ -284,6 +284,7 @@
     by zeros at startup.
   */
   return_val= acl_reload(thd);
+  DBUG_PRINT("info", ("acl_reload (to acl_init) returned %d", return_val));
   delete thd;
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD,  0);

--- 1.175/sql/sql_lex.cc	2006-03-13 06:34:16 -08:00
+++ 1.176/sql/sql_lex.cc	2006-04-08 14:47:21 -07:00
@@ -192,6 +192,21 @@
   lex->allow_sum_func= 0;
   lex->in_sum_func= NULL;
   lex->binlog_row_based_if_mixed= 0;
+  /*
+    ok, there must be a better solution for this, long-term
+    I tried "bzero" in the sql_yacc.yy code, but that for
+    some reason made the values zero, even if they were set
+  */
+  lex->server_options.server_name= 0;
+  lex->server_options.server_name_length= 0;
+  lex->server_options.host= 0;
+  lex->server_options.db= 0;
+  lex->server_options.username= 0;
+  lex->server_options.password= 0;
+  lex->server_options.scheme= 0;
+  lex->server_options.socket= 0;
+  lex->server_options.owner= 0;
+  lex->server_options.port= -1;
   DBUG_VOID_RETURN;
 }
 

--- 1.217/sql/sql_lex.h	2006-02-13 08:35:27 -08:00
+++ 1.218/sql/sql_lex.h	2006-04-08 14:08:50 -07:00
@@ -27,7 +27,7 @@
 class sp_pcontext;
 class st_alter_tablespace;
 class partition_info;
-class event_timed;
+class Event_timed;
 
 #ifdef MYSQL_SERVER
 /*
@@ -41,14 +41,23 @@
 #define LEX_YYSTYPE void *
 #else
 #include "lex_symbol.h"
+#if MYSQL_LEX
 #include "sql_yacc.h"
 #define LEX_YYSTYPE YYSTYPE *
+#else
+#define LEX_YYSTYPE void *
+#endif
 #endif
 #endif
 
 /*
   When a command is added here, be sure it's also added in mysqld.cc
   in "struct show_var_st status_vars[]= {" ...
+
+  If the command returns a result set or is not allowed in stored
+  functions or triggers, please also make sure that
+  sp_get_flags_for_command (sp_head.cc) returns proper flags for the
+  added SQLCOM_.
 */
 
 enum enum_sql_command {
@@ -67,6 +76,7 @@
   SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
   SQLCOM_GRANT,
   SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
+  SQLCOM_RENAME_DB,
   SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
   SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
   SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
@@ -502,6 +512,7 @@
   char *db;
   Item *where, *having;                         /* WHERE & HAVING clauses */
   Item *prep_where; /* saved WHERE clause for prepared statement processing */
+  Item *prep_having;/* saved HAVING clause for prepared statement processing */
   /* point on lex in which it was created, used in view subquery detection */
   st_lex *parent_lex;
   enum olap_type olap;
@@ -703,6 +714,8 @@
 #define ALTER_ANALYZE_PARTITION  (1L << 22)
 #define ALTER_CHECK_PARTITION    (1L << 23)
 #define ALTER_REPAIR_PARTITION   (1L << 24)
+#define ALTER_REMOVE_PARTITIONING (1L << 25)
+#define ALTER_FOREIGN_KEY         (1L << 26)
 
 typedef struct st_alter_info
 {
@@ -760,10 +773,11 @@
   const uchar *buf;		/* The beginning of string, used by SPs */
   const uchar *ptr,*tok_start,*tok_end,*end_of_query;
   
-  /* The values of tok_start/tok_end as they were one call of yylex before */
+  /* The values of tok_start/tok_end as they were one call of MYSQLlex before */
   const uchar *tok_start_prev, *tok_end_prev;
 
   char *length,*dec,*change,*name;
+  Table_ident *like_name;
   char *help_arg;
   char *backup_dir;				/* For RESTORE/BACKUP */
   char* to_log;                                 /* For PURGE MASTER LOGS TO */
@@ -826,6 +840,7 @@
     required a local context, the parser pops the top-most context.
   */
   List<Name_resolution_context> context_stack;
+  List<LEX_STRING>     db_list;
 
   SQL_LIST	      proc_list, auxilliary_table_list, save_list;
   create_field	      *last_field;
@@ -883,7 +898,11 @@
   uint8 create_view_check;
   bool drop_if_exists, drop_temporary, local_file, one_shot_set;
   bool in_comment, ignore_space, verbose, no_write_to_binlog;
-  bool tx_chain, tx_release;
+  /*
+    binlog_row_based_if_mixed tells if the parsing stage detected that some
+    items require row-based binlogging to give a reliable binlog/replication.
+  */
+  bool tx_chain, tx_release, binlog_row_based_if_mixed;
   /*
     Special JOIN::prepare mode: changing of query is prohibited.
     When creating a view, we need to just check its syntax omitting
@@ -939,7 +958,7 @@
 
   st_sp_chistics sp_chistics;
 
-  event_timed *et;
+  Event_timed *et;
   bool et_compile_phase;
 
   bool only_view;       /* used for SHOW CREATE TABLE/VIEW */
@@ -964,12 +983,16 @@
   SQL_LIST trg_table_fields;
 
   /*
-    trigger_definition_begin points to the beginning of the word "TRIGGER" in
-    CREATE TRIGGER statement. This is used to add possibly omitted DEFINER
-    clause to the trigger definition statement before dumping it to the
-    binlog. 
+    stmt_definition_begin is intended to point to the next word after
+    DEFINER-clause in the following statements:
+      - CREATE TRIGGER (points to "TRIGGER");
+      - CREATE PROCEDURE (points to "PROCEDURE");
+      - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE");
+
+    This pointer is required to add possibly omitted DEFINER-clause to the
+    DDL-statement before dumping it to the binlog. 
   */
-  const char *trigger_definition_begin;
+  const char *stmt_definition_begin;
 
   /*
     If non-0 then indicates that query requires prelocking and points to
@@ -1118,7 +1141,7 @@
 extern void lex_free(void);
 extern void lex_start(THD *thd, const uchar *buf, uint length);
 extern void lex_end(LEX *lex);
-extern int yylex(void *arg, void *yythd);
+extern int MYSQLlex(void *arg, void *yythd);
 
 extern pthread_key(LEX*,THR_LEX);
 

--- 1.518/sql/sql_parse.cc	2006-03-14 00:17:02 -08:00
+++ 1.519/sql/sql_parse.cc	2006-04-08 14:08:51 -07:00
@@ -14,6 +14,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#define MYSQL_LEX 1
 #include "mysql_priv.h"
 #include "sql_repl.h"
 #include "rpl_filter.h"
@@ -1615,6 +1616,11 @@
     statistic_increment(thd->status_var.com_other, &LOCK_status);
     thd->enable_slow_log= opt_log_slow_admin_statements;
     db= thd->alloc(db_len + tbl_len + 2);
+    if (!db)
+    {
+      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
+      break;
+    }
     tbl_name= strmake(db, packet + 1, db_len)+1;
     strmake(tbl_name, packet + db_len + 2, tbl_len);
     mysql_table_dump(thd, db, tbl_name, -1);
@@ -1628,14 +1634,14 @@
     statistic_increment(thd->status_var.com_other, &LOCK_status);
     char *user= (char*) packet;
     char *passwd= strend(user)+1;
-    /* 
+    /*
       Old clients send null-terminated string ('\0' for empty string) for
       password.  New clients send the size (1 byte) + string (not null
       terminated, so also '\0' for empty string).
     */
-    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8 
+    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8
     char *db= passwd;
-    uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? 
+    uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
       *passwd++ : strlen(passwd);
     db+= passwd_len + 1;
 #ifndef EMBEDDED_LIBRARY
@@ -2107,6 +2113,7 @@
 void log_slow_statement(THD *thd)
 {
   time_t start_of_query;
+  DBUG_ENTER("log_slow_statement");
 
   /*
     The following should never be true with our current code base,
@@ -2114,7 +2121,7 @@
     statement in a trigger or stored function
   */
   if (unlikely(thd->in_sub_stmt))
-    return;                                     // Don't set time for sub stmt
+    DBUG_VOID_RETURN;                           // Don't set time for sub stmt
 
   start_of_query= thd->start_time;
   thd->end_time();				// Set start time
@@ -2137,6 +2144,7 @@
       slow_log_print(thd, thd->query, thd->query_length, start_of_query);
     }
   }
+  DBUG_VOID_RETURN;
 }
 
 
@@ -2350,6 +2358,9 @@
   DBUG_ENTER("mysql_execute_command");
 
   thd->net.no_send_error= 0;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  thd->work_part_info= 0;
+#endif
 
   /*
     In many cases first table of main SELECT_LEX have special meaning =>
@@ -2415,27 +2426,33 @@
     }
   }
   else
-#endif /* HAVE_REPLICATION */
-
-  /*
-    When option readonly is set deny operations which change non-temporary
-    tables. Except for the replication thread and the 'super' users.
-  */
-  if (opt_readonly &&
-      !(thd->security_ctx->master_access & SUPER_ACL) &&
-      uc_update_queries[lex->sql_command] &&
-      !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
-        (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
-      ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
-       some_non_temp_table_to_be_updated(thd, all_tables)))
   {
-    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-    DBUG_RETURN(-1);
-  }
+#endif /* HAVE_REPLICATION */
+    /*
+      When option readonly is set deny operations which change non-temporary
+      tables. Except for the replication thread and the 'super' users.
+    */
+    if (opt_readonly &&
+	!(thd->security_ctx->master_access & SUPER_ACL) &&
+	uc_update_queries[lex->sql_command] &&
+	!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
+	  (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
+	((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
+	 some_non_temp_table_to_be_updated(thd, all_tables)))
+    {
+      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+      DBUG_RETURN(-1);
+    }
+#ifdef HAVE_REPLICATION
+  } /* endif unlikely slave */
+#endif
   if(lex->orig_sql_command == SQLCOM_END)
     statistic_increment(thd->status_var.com_stat[lex->sql_command],
                         &LOCK_status);
 
+  if (lex->binlog_row_based_if_mixed)
+    thd->set_current_stmt_binlog_row_based_if_mixed();
+
   switch (lex->sql_command) {
   case SQLCOM_SELECT:
   {
@@ -2884,11 +2901,20 @@
     else
     {
       /* regular create */
-      if (lex->name)
+      if (lex->like_name)
         res= mysql_create_like_table(thd, create_table, &lex->create_info, 
-                                     (Table_ident *)lex->name); 
+                                     lex->like_name); 
       else
       {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+        partition_info *part_info= thd->lex->part_info;
+        if (part_info && !(part_info= thd->lex->part_info->get_clone()))
+        {
+          res= -1;
+          goto end_with_restore_list;
+        }
+        thd->work_part_info= part_info;
+#endif
         res= mysql_create_table(thd, create_table->db,
 				create_table->table_name, &lex->create_info,
 				lex->create_list,
@@ -3066,7 +3092,7 @@
       }
     }
     query_cache_invalidate3(thd, first_table, 0);
-    if (end_active_trans(thd) || mysql_rename_tables(thd, first_table))
+    if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
       goto error;
     break;
   }
@@ -3131,8 +3157,8 @@
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
+        thd->binlog_query(THD::STMT_QUERY_TYPE,
+                          thd->query, thd->query_length, 0, FALSE);
       }
     }
     select_lex->table_list.first= (byte*) first_table;
@@ -3165,8 +3191,8 @@
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
+        thd->binlog_query(THD::STMT_QUERY_TYPE,
+                          thd->query, thd->query_length, 0, FALSE);
       }
     }
     select_lex->table_list.first= (byte*) first_table;
@@ -3190,8 +3216,8 @@
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
+        thd->binlog_query(THD::STMT_QUERY_TYPE,
+                          thd->query, thd->query_length, 0, FALSE);
       }
     }
     select_lex->table_list.first= (byte*) first_table;
@@ -3227,8 +3253,7 @@
     else
       res= 0;
 
-    if ((res= mysql_multi_update_prepare(thd)))
-      break;
+    res= mysql_multi_update_prepare(thd);
 
 #ifdef HAVE_REPLICATION
     /* Check slave filtering rules */
@@ -3236,20 +3261,33 @@
     {
       if (all_tables_not_ok(thd, all_tables))
       {
+        if (res!= 0)
+        {
+          res= 0;             /* don't care of prev failure  */
+          thd->clear_error(); /* filters are of highest prior */
+        }
         /* we warn the slave SQL thread */
         my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
         break;
       }
+      if (res)
+        break;
     }
     else
-#endif /* HAVE_REPLICATION */
-    if (opt_readonly &&
-        !(thd->security_ctx->master_access & SUPER_ACL) &&
-        some_non_temp_table_to_be_updated(thd, all_tables))
     {
-      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-      break;
-    }
+#endif /* HAVE_REPLICATION */
+      if (res)
+        break;
+      if (opt_readonly &&
+	  !(thd->security_ctx->master_access & SUPER_ACL) &&
+	  some_non_temp_table_to_be_updated(thd, all_tables))
+      {
+	my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+	break;
+      }
+#ifdef HAVE_REPLICATION
+    }  /* unlikely */
+#endif
 
     res= mysql_multi_update(thd, all_tables,
                             &select_lex->item_list,
@@ -3314,6 +3352,19 @@
         select_lex->context.table_list= 
           select_lex->context.first_name_resolution_table= second_table;
 	res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
+        /*
+          Invalidate the table in the query cache if something changed
+          after unlocking when changes become visible.
+          TODO: this is workaround. right way will be move invalidating in
+          the unlock procedure.
+        */
+        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
+            thd->lock)
+        {
+          mysql_unlock_tables(thd, thd->lock);
+          query_cache_invalidate3(thd, first_table, 1);
+          thd->lock=0;
+        }
         delete result;
       }
       /* revert changes for SP */
@@ -3337,7 +3388,7 @@
       Don't allow this within a transaction because we want to use
       re-generate table
     */
-    if ((thd->locked_tables && !lex->sphead) || thd->active_transaction())
+    if (thd->locked_tables || thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
@@ -3644,6 +3695,48 @@
     res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
     break;
   }
+  case SQLCOM_RENAME_DB:
+  {
+    LEX_STRING *olddb, *newdb;
+    List_iterator <LEX_STRING> db_list(lex->db_list);
+    olddb= db_list++;
+    newdb= db_list++;
+    if (end_active_trans(thd))
+    {
+      res= 1;
+      break;
+    }
+#ifdef HAVE_REPLICATION
+    if (thd->slave_thread && 
+       (!rpl_filter->db_ok(olddb->str) ||
+        !rpl_filter->db_ok(newdb->str) ||
+        !rpl_filter->db_ok_with_wild_table(olddb->str) ||
+        !rpl_filter->db_ok_with_wild_table(newdb->str)))
+    {
+      res= 1;
+      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
+      break;
+    }
+#endif
+    if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
+        check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
+        check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
+    {
+      res= 1;
+      break;
+    }
+    if (thd->locked_tables || thd->active_transaction())
+    {
+      res= 1;
+      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
+                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
+      goto error;
+    }
+    res= mysql_rename_db(thd, olddb, newdb);
+    if (!res)
+      send_ok(thd);
+    break;
+  }
   case SQLCOM_ALTER_DB:
   {
     char *db= lex->name ? lex->name : thd->db;
@@ -3654,7 +3747,7 @@
     }
     if (!strip_sp(db) || check_db_name(db))
     {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+      my_error(ER_WRONG_DB_NAME, MYF(0), db);
       break;
     }
     /*
@@ -3666,8 +3759,8 @@
     */
 #ifdef HAVE_REPLICATION
     if (thd->slave_thread &&
-	(!rpl_filter->db_ok(lex->name) ||
-	 !rpl_filter->db_ok_with_wild_table(lex->name)))
+	(!rpl_filter->db_ok(db) ||
+	 !rpl_filter->db_ok_with_wild_table(db)))
     {
       my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
       break;
@@ -3712,6 +3805,12 @@
                        is_schema_db(lex->et->dbname.str)))
         break;
 
+      if (end_active_trans(thd))
+      {
+        res= -1;
+        break;
+      }
+
       switch (lex->sql_command) {
       case SQLCOM_CREATE_EVENT:
         res= evex_create_event(thd, lex->et, (uint) lex->create_info.options,
@@ -3724,18 +3823,32 @@
         res= evex_drop_event(thd, lex->et, lex->drop_if_exists, &rows_affected);
       default:;
       }
+      DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d",
+                  res, rows_affected));
       if (!res)
         send_ok(thd, rows_affected);
 
       /* lex->unit.cleanup() is called outside, no need to call it here */
-    } while (0);  
-    lex->et->free_sphead_on_delete= true;
-    delete lex->et;
-    lex->et= 0;
+    } while (0);
+    if (!thd->spcont)
+    {
+      lex->et->free_sphead_on_delete= true;
+      lex->et->free_sp();
+      lex->et->deinit_mutexes();
+    }
+    
     break;
   }
   case SQLCOM_SHOW_CREATE_EVENT:
   {
+    DBUG_ASSERT(lex->spname);
+    DBUG_ASSERT(lex->et);
+    if (! lex->spname->m_db.str)
+    {
+      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
+      res= true;
+      break;
+    }
     if (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0,
                      is_schema_db(lex->spname->m_db.str)))
       break;
@@ -3745,8 +3858,7 @@
       my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
       goto error;
     }
-    /* TODO : Implement it */
-    send_ok(thd, 1);
+    res= evex_show_create_event(thd, lex->spname, lex->et->definer);
     break;
   }
   case SQLCOM_CREATE_FUNCTION:                  // UDF function
@@ -3779,10 +3891,8 @@
     if (!(res= mysql_create_user(thd, lex->users_list)))
     {
       if (mysql_bin_log.is_open())
-      {
         thd->binlog_query(THD::MYSQL_QUERY_TYPE,
                           thd->query, thd->query_length, FALSE, FALSE);
-      }
       send_ok(thd);
     }
     break;
@@ -3972,8 +4082,8 @@
       {
         if (mysql_bin_log.is_open())
         {
-          Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-          mysql_bin_log.write(&qinfo);
+          thd->binlog_query(THD::STMT_QUERY_TYPE,
+                            thd->query, thd->query_length, 0, FALSE);
         }
       }
       send_ok(thd);
@@ -4203,6 +4313,90 @@
 #endif
 
     /*
+      If the definer is not specified, this means that CREATE-statement missed
+      DEFINER-clause. DEFINER-clause can be missed in two cases:
+      
+        - The user submitted a statement w/o the clause. This is a normal
+          case, we should assign CURRENT_USER as definer.
+
+        - Our slave received an updated from the master, that does not
+          replicate definer for stored rountines. We should also assign
+          CURRENT_USER as definer here, but also we should mark this routine
+          as NON-SUID. This is essential for the sake of backward
+          compatibility.
+          
+          The problem is the slave thread is running under "special" user (@),
+          that actually does not exist. In the older versions we do not fail
+          execution of a stored routine if its definer does not exist and
+          continue the execution under the authorization of the invoker
+          (BUG#13198). And now if we try to switch to slave-current-user (@),
+          we will fail.
+
+          Actually, this leads to the inconsistent state of master and
+          slave (different definers, different SUID behaviour), but it seems,
+          this is the best we can do.
+    */
+
+    if (!lex->definer)
+    {
+      bool res= FALSE;
+      Query_arena original_arena;
+      Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena);
+
+      if (!(lex->definer= create_default_definer(thd)))
+        res= TRUE;
+
+      if (ps_arena)
+        thd->restore_active_arena(ps_arena, &original_arena);
+
+      if (res)
+      {
+        /* Error has been already reported. */
+        delete lex->sphead;
+        lex->sphead= 0;
+        goto error;
+      }
+
+      if (thd->slave_thread)
+        lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
+    }
+
+    /*
+      If the specified definer differs from the current user, we should check
+      that the current user has SUPER privilege (in order to create a stored
+      routine under another user one must have SUPER privilege).
+    */
+    
+    else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
+        my_strcasecmp(system_charset_info,
+                      lex->definer->host.str,
+                      thd->security_ctx->priv_host))
+    {
+      if (check_global_access(thd, SUPER_ACL))
+      {
+        my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+        delete lex->sphead;
+        lex->sphead= 0;
+        goto error;
+      }
+    }
+
+    /* Check that the specified definer exists. Emit a warning if not. */
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+    if (!is_acl_user(lex->definer->host.str,
+                     lex->definer->user.str))
+    {
+      push_warning_printf(thd,
+                          MYSQL_ERROR::WARN_LEVEL_NOTE,
+                          ER_NO_SUCH_USER,
+                          ER(ER_NO_SUCH_USER),
+                          lex->definer->user.str,
+                          lex->definer->host.str);
+    }
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+
+    /*
       We need to copy name and db in order to use them for
       check_routine_access which is called after lex->sphead has
       been deleted.
@@ -4216,7 +4410,7 @@
       /*
         We must cleanup the unit and the lex here because
         sp_grant_privileges calls (indirectly) db_find_routine,
-        which in turn may call yyparse with THD::lex.
+        which in turn may call MYSQLparse with THD::lex.
         TODO: fix db_find_routine to use a temporary lex.
       */
       lex->unit.cleanup();
@@ -4471,21 +4665,17 @@
   case SQLCOM_DROP_PROCEDURE:
   case SQLCOM_DROP_FUNCTION:
     {
-      sp_head *sp;
       int result;
-      char *db, *name;
+      int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
+                 TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
 
-      if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-                            &thd->sp_proc_cache, FALSE);
-      else
-        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-                            &thd->sp_func_cache, FALSE);
+      result= sp_routine_exists_in_table(thd, type, lex->spname);
       mysql_reset_errors(thd, 0);
-      if (sp)
+      if (result == SP_OK)
       {
-        db= thd->strdup(sp->m_db.str);
-	name= thd->strdup(sp->m_name.str);
+        char *db= lex->spname->m_db.str;
+	char *name= lex->spname->m_name.str;
+
 	if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
                                  lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
           goto error;
@@ -4625,7 +4815,7 @@
       else
         sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
                             &thd->sp_func_cache, FALSE);
-      if (!sp || !sp->show_routine_code(thd))
+      if (!sp || sp->show_routine_code(thd))
       {
         /* We don't distinguish between errors for now */
         my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4952,10 +5142,14 @@
     break;
   }
   default:
+#ifndef EMBEDDED_LIBRARY
     DBUG_ASSERT(0);                             /* Impossible */
+#endif
     send_ok(thd);
     break;
   }
+
+end:
   thd->proc_info="query end";
 
   /*
@@ -4970,6 +5164,7 @@
   */
   if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
     reset_one_shot_variables(thd);
+  thd->reset_current_stmt_binlog_row_based();
 
   /*
     The return value for ROW_COUNT() is "implementation dependent" if the
@@ -4985,7 +5180,8 @@
   DBUG_RETURN(res || thd->net.report_error);
 
 error:
-  DBUG_RETURN(1);
+  res= 1;           // would be better to set res=1 before "goto error"
+  goto end;
 }
 
 
@@ -5708,7 +5904,7 @@
     sp_cache_flush_obsolete(&thd->sp_proc_cache);
     sp_cache_flush_obsolete(&thd->sp_func_cache);
     
-    if (!yyparse((void *)thd) && ! thd->is_fatal_error)
+    if (!MYSQLparse((void *)thd) && ! thd->is_fatal_error)
     {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
       if (mqh_used && thd->user_connect &&
@@ -5721,16 +5917,15 @@
       {
 	if (thd->net.report_error)
 	{
-	  if (thd->lex->sphead)
-	  {
-	    delete thd->lex->sphead;
-	    thd->lex->sphead= NULL;
-	  }
-          if (thd->lex->et)
+          delete lex->sphead;
+          lex->sphead= NULL;
+          if (lex->et)
           {
-            thd->lex->et->free_sphead_on_delete= true;
-            delete thd->lex->et;
-            thd->lex->et= NULL;
+            lex->et->free_sphead_on_delete= true;
+            /* alloced on thd->mem_root so no real memory free but dtor call */
+            lex->et->free_sp();
+            lex->et->deinit_mutexes();
+            lex->et= NULL;
           }
 	}
 	else
@@ -5761,17 +5956,18 @@
 			 thd->is_fatal_error));
       query_cache_abort(&thd->net);
       lex->unit.cleanup();
-      if (thd->lex->sphead)
+      if (lex->sphead)
       {
 	/* Clean up after failed stored procedure/function */
-	delete thd->lex->sphead;
-	thd->lex->sphead= NULL;
+	delete lex->sphead;
+	lex->sphead= NULL;
       }
-      if (thd->lex->et)
+      if (lex->et)
       {
-        thd->lex->et->free_sphead_on_delete= true;
-        delete thd->lex->et;
-        thd->lex->et= NULL;
+        lex->et->free_sphead_on_delete= true;
+        lex->et->free_sp();
+        lex->et->deinit_mutexes();
+        lex->et= NULL;
       }
     }
     thd->proc_info="freeing items";
@@ -5800,7 +5996,7 @@
   DBUG_ENTER("mysql_test_parse_for_slave");
 
   mysql_init_query(thd, (uchar*) inBuf, length);
-  if (!yyparse((void*) thd) && ! thd->is_fatal_error &&
+  if (!MYSQLparse((void*) thd) && ! thd->is_fatal_error &&
       all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
     error= 1;                  /* Ignore question */
   thd->end_statement();
@@ -5896,10 +6092,7 @@
     */
     char buf[32];
     my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
-    push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
-                        ER_WARN_DEPRECATED_SYNTAX,
-                        ER(ER_WARN_DEPRECATED_SYNTAX),
-                        buf, "TIMESTAMP");
+    WARN_DEPRECATED(thd, "5.2", buf, "'TIMESTAMP'");
   }
 
   if (!(new_field= new create_field()) ||
@@ -6129,10 +6322,11 @@
     /*
       table_list.next points to the last inserted TABLE_LIST->next_local'
       element
+      We don't use the offsetof() macro here to avoid warnings from gcc
     */
-    previous_table_ref= (TABLE_LIST*) (table_list.next -
-                                       offsetof(TABLE_LIST, next_local));
-    DBUG_ASSERT(previous_table_ref);
+    previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
+                                       ((char*) &(ptr->next_local) -
+                                        (char*) ptr));
     /*
       Set next_name_resolution_table of the previous table reference to point
       to the current table reference. In effect the list
@@ -6684,6 +6878,7 @@
 #ifdef HAVE_REPLICATION
   if (options & REFRESH_MASTER)
   {
+    DBUG_ASSERT(thd);
     tmp_write_to_binlog= 0;
     if (reset_master(thd))
     {
@@ -7320,47 +7515,54 @@
 
 /*
   Set the specified definer to the default value, which is the current user in
-  the thread. Also check that the current user satisfies to the definers
-  requirements.
+  the thread.
  
   SYNOPSIS
     get_default_definer()
     thd       [in] thread handler
     definer   [out] definer
- 
-  RETURN
-    error status, that is:
-      - FALSE -- on success;
-      - TRUE -- on error (current user can not be a definer).
 */
  
-bool get_default_definer(THD *thd, LEX_USER *definer)
+void get_default_definer(THD *thd, LEX_USER *definer)
 {
-  /* Check that current user has non-empty host name. */
-
   const Security_context *sctx= thd->security_ctx;
 
-  if (sctx->priv_host[0] == 0)
-  {
-    my_error(ER_MALFORMED_DEFINER, MYF(0));
-    return TRUE;
-  }
-
-  /* Fill in. */
-
   definer->user.str= (char *) sctx->priv_user;
   definer->user.length= strlen(definer->user.str);
 
   definer->host.str= (char *) sctx->priv_host;
   definer->host.length= strlen(definer->host.str);
+}
 
-  return FALSE;
+
+/*
+  Create default definer for the specified THD.
+
+  SYNOPSIS
+    create_default_definer()
+    thd         [in] thread handler
+
+  RETURN
+    On success, return a valid pointer to the created and initialized
+    LEX_USER, which contains definer information.
+    On error, return 0.
+*/
+
+LEX_USER *create_default_definer(THD *thd)
+{
+  LEX_USER *definer;
+
+  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
+    return 0;
+
+  get_default_definer(thd, definer);
+
+  return definer;
 }
 
 
 /*
-  Create definer with the given user and host names. Also check that the user
-  and host names satisfy definers requirements.
+  Create definer with the given user and host names.
 
   SYNOPSIS
     create_definer()
@@ -7370,21 +7572,13 @@
 
   RETURN
     On success, return a valid pointer to the created and initialized
-    LEX_STRING, which contains definer information.
+    LEX_USER, which contains definer information.
     On error, return 0.
 */
 
 LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
 {
   LEX_USER *definer;
-
-  /* Check that specified host name is valid. */
-
-  if (host_name->length == 0)
-  {
-    my_error(ER_MALFORMED_DEFINER, MYF(0));
-    return 0;
-  }
 
   /* Create and initialize. */
 

--- 1.451/sql/sql_yacc.yy	2006-03-14 00:17:03 -08:00
+++ 1.452/sql/sql_yacc.yy	2006-04-08 14:47:21 -07:00
@@ -42,18 +42,19 @@
 #include <myisam.h>
 #include <myisammrg.h>
 
+typedef struct p_elem_val
+{ 
+  longlong value;
+  bool null_value;
+} part_elem_value;
+
 int yylex(void *yylval, void *yythd);
 
 const LEX_STRING null_lex_str={0,0};
 
 #define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
 
-#define WARN_DEPRECATED(A,B)                                        \
-  push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN, \
-		      ER_WARN_DEPRECATED_SYNTAX,                    \
-		      ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
-
-#define YYERROR_UNLESS(A)                  \
+#define YYERROR_UNLESS(A)               \
   if (!(A))                             \
   {					\
     yyerror(ER(ER_SYNTAX_ERROR));	\
@@ -110,6 +111,7 @@
   sp_name *spname;
   struct st_lex *lex;
   sp_head *sphead;
+  struct p_elem_val *p_elem_value;
 }
 
 %{
@@ -496,11 +498,13 @@
 %token  PARSER_SYM
 %token  PARTIAL
 %token  PARTITION_SYM
+%token  PARTITIONING_SYM
 %token  PARTITIONS_SYM
 %token  PASSWORD
 %token  PARAM_MARKER
 %token  PHASE_SYM
 %token  PLUGIN_SYM
+%token  PLUGINS_SYM
 %token  POINTFROMTEXT
 %token  POINT_SYM
 %token  POLYFROMTEXT
@@ -520,11 +524,6 @@
 %token  QUARTER_SYM
 %token  QUERY_SYM
 %token  QUICK
-%token  RAID_0_SYM
-%token  RAID_CHUNKS
-%token  RAID_CHUNKSIZE
-%token  RAID_STRIPED_SYM
-%token  RAID_TYPE
 %token  RAND
 %token  RANGE_SYM
 %token  READS_SYM
@@ -544,6 +543,7 @@
 %token  RELAY_THREAD
 %token  RELEASE_SYM
 %token  RELOAD
+%token  REMOVE_SYM
 %token  RENAME
 %token  REORGANIZE_SYM
 %token  REPAIR
@@ -677,6 +677,7 @@
 %token  UNSIGNED
 %token  UNTIL_SYM
 %token  UPDATE_SYM
+%token  UPGRADE_SYM
 %token  USAGE
 %token  USER
 %token  USE_FRM
@@ -759,14 +760,17 @@
         opt_ignore_leaves fulltext_options spatial_type union_option
         start_transaction_opts opt_chain opt_release
         union_opt select_derived_init option_type2
+        opt_natural_language_mode opt_query_expansion
+        opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
+        ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
 
 %type <ulong_num>
-	ulong_num raid_types merge_insert_types
+	ulong_num merge_insert_types
 
 %type <ulonglong_number>
 	ulonglong_num size_number
 
-%type <longlong_number>
+%type <p_elem_value>
         part_bit_expr
 
 %type <lock_type>
@@ -833,7 +837,7 @@
 
 %type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp
 
-%type <lex_user> user grant_user get_definer
+%type <lex_user> user grant_user
 
 %type <charset>
 	opt_collate
@@ -876,7 +880,7 @@
 	clear_privileges flush_options flush_option
 	equal optional_braces opt_key_definition key_usage_list2
 	opt_mi_check_type opt_to mi_check_types normal_join
-	table_to_table_list table_to_table opt_table_list opt_as
+	db_to_db table_to_table_list table_to_table opt_table_list opt_as
 	handler_rkey_function handler_read_or_scan
 	single_multi table_wild_list table_wild_one opt_wild
 	union_clause union_list
@@ -888,8 +892,9 @@
 	sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
         load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
         definer view_replace_or_algorithm view_replace view_algorithm_opt
-        view_algorithm view_or_trigger_tail view_suid view_tail view_list_opt
-        view_list view_select view_check_option trigger_tail
+        view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_tail
+        view_suid view_tail view_list_opt view_list view_select
+        view_check_option trigger_tail sp_tail
         install uninstall partition_entry binlog_base64_event
         server_def server_options_list server_option
 END_OF_INPUT
@@ -1221,7 +1226,8 @@
 	  lex->create_info.options=$2 | $4;
 	  lex->create_info.db_type= lex->thd->variables.table_type;
 	  lex->create_info.default_table_charset= NULL;
-	  lex->name=0;
+	  lex->name= 0;
+         lex->like_name= 0;
 	}
 	create2
 	  { Lex->current_select= &Lex->select_lex; }
@@ -1260,81 +1266,9 @@
 	    lex->name=$4.str;
             lex->create_info.options=$3;
 	  }
-	| CREATE udf_func_type FUNCTION_SYM sp_name
-	  {
-	    LEX *lex=Lex;
-	    lex->spname= $4;
-	    lex->udf.type= $2;
-	  }
-	  create_function_tail
-	  {}
-	| CREATE PROCEDURE sp_name
-	  {
-	    LEX *lex= Lex;
-	    sp_head *sp;
-
-	    if (lex->sphead)
-	    {
-	      my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
-	      YYABORT;
-	    }
-	    /* Order is important here: new - reset - init */
-	    sp= new sp_head();
-	    sp->reset_thd_mem_root(YYTHD);
-	    sp->init(lex);
-
-	    sp->m_type= TYPE_ENUM_PROCEDURE;
-	    lex->sphead= sp;
-	    /*
-	     * We have to turn of CLIENT_MULTI_QUERIES while parsing a
-	     * stored procedure, otherwise yylex will chop it into pieces
-	     * at each ';'.
-	     */
-            $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
-	    YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
-	  }
-          '('
-	  {
-	    LEX *lex= Lex;
-
-	    lex->sphead->m_param_begin= lex->tok_start+1;
-	  }
-	  sp_pdparam_list
-	  ')'
-	  {
-	    LEX *lex= Lex;
-
-	    lex->sphead->m_param_end= lex->tok_start;
-	    bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
-	  }
-	  sp_c_chistics
-	  {
-	    LEX *lex= Lex;
-
-	    lex->sphead->m_chistics= &lex->sp_chistics;
-	    lex->sphead->m_body_begin= lex->tok_start;
-	  }
-	  sp_proc_stmt
-	  {
-	    LEX *lex= Lex;
-	    sp_head *sp= lex->sphead;
-
-	    if (sp->check_backpatch(YYTHD))
-	      YYABORT;
-	    sp->init_strings(YYTHD, lex, $3);
-	    lex->sql_command= SQLCOM_CREATE_PROCEDURE;
-            
-	    /* 
-              Restore flag if it was cleared above 
-              Be careful with counting. the block where we save the value
-              is $4.
-            */
-	    YYTHD->client_capabilities |= $<ulong_num>4;
-	    sp->restore_thd_mem_root(YYTHD);
-	  }
 	| CREATE EVENT_SYM opt_if_not_exists sp_name
-          /* 
-             BE CAREFUL when you add a new rule to update the block where 
+          /*
+             BE CAREFUL when you add a new rule to update the block where
              YYTHD->client_capabilities is set back to original value
           */
           {
@@ -1352,10 +1286,10 @@
             }
 
             lex->create_info.options= $3;
-	    
-            if (!(lex->et= new event_timed())) // implicitly calls event_timed::init()
+
+            if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls Event_timed::init()
               YYABORT;
-	    
+
             /*
               We have to turn of CLIENT_MULTI_QUERIES while parsing a
               stored procedure, otherwise yylex will chop it into pieces
@@ -1398,7 +1332,7 @@
             Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
             Lex->create_view_suid= TRUE;
 	  }
-	  view_or_trigger
+	  view_or_trigger_or_sp
 	  {}
 	| CREATE USER clear_privileges grant_list
 	  {
@@ -1484,6 +1418,8 @@
                 break;
               case EVEX_BAD_PARAMS:
                 my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0));
+              case EVEX_MICROSECOND_UNSUP:
+                my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND");
                 YYABORT;
                 break;
               }
@@ -1510,41 +1446,44 @@
                            str2? str2->c_ptr():"NULL");
                   YYABORT;
                   break;
-                }          
+                }
               case EVEX_BAD_PARAMS:
                 my_error(ER_EVENT_EXEC_TIME_IN_THE_PAST, MYF(0));
                 YYABORT;
-                break;             
+                break;
               }
             }
           }
       ;
-    
-opt_ev_status: /* empty */ {$<ulong_num>$= 0;}
+
+opt_ev_status: /* empty */ { $$= 0; }
         | ENABLE_SYM
           {
             LEX *lex=Lex;
             if (!lex->et_compile_phase)
               lex->et->status= MYSQL_EVENT_ENABLED;
-            $<ulong_num>$= 1;	   
+            $$= 1;
           }
         | DISABLE_SYM
           {
             LEX *lex=Lex;
-            
+
             if (!lex->et_compile_phase)
               lex->et->status= MYSQL_EVENT_DISABLED;
-            $<ulong_num>$= 1;
+            $$= 1;
           }
       ;
 
 ev_starts: /* empty */
+          {
+            Lex->et->init_starts(YYTHD, new Item_func_now_local());
+          }
         | STARTS_SYM expr
           {
             LEX *lex= Lex;
             if (!lex->et_compile_phase)
             {
-              
+
               switch (lex->et->init_starts(YYTHD, $2)) {
               case EVEX_PARSE_ERROR:
                 yyerror(ER(ER_SYNTAX_ERROR));
@@ -1585,28 +1524,28 @@
           }
       ;
 
-opt_ev_on_completion: /* empty */ {$<ulong_num>$= 0;}
+opt_ev_on_completion: /* empty */ { $$= 0; }
         | ev_on_completion
       ;
 
-ev_on_completion: 
+ev_on_completion:
           ON COMPLETION_SYM PRESERVE_SYM
           {
             LEX *lex=Lex;
             if (!lex->et_compile_phase)
               lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
-            $<ulong_num>$= 1;
+            $$= 1;
           }
         | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
           {
             LEX *lex=Lex;
             if (!lex->et_compile_phase)
               lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
-            $<ulong_num>$= 1;
+            $$= 1;
           }
       ;
 
-opt_ev_comment: /* empty */ {$<ulong_num>$= 0;}
+opt_ev_comment: /* empty */ { $$= 0; }
         | COMMENT_SYM TEXT_STRING_sys
           {
             LEX *lex= Lex;
@@ -1615,7 +1554,7 @@
               lex->comment= $2;
               lex->et->init_comment(YYTHD, &$2);
             }
-            $<ulong_num>$= 1;
+            $$= 1;
           }
       ;
 
@@ -1623,9 +1562,9 @@
           {
             LEX *lex= Lex;
             sp_head *sp;
-	    
+
             $<sphead>$= lex->sphead;
-            
+
             if (!lex->sphead)
             {
               if (!(sp= new sp_head()))
@@ -1633,14 +1572,14 @@
 
               sp->reset_thd_mem_root(YYTHD);
               sp->init(lex);
-            
+
               sp->m_type= TYPE_ENUM_PROCEDURE;
-            
+
               lex->sphead= sp;
 
               bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
               lex->sphead->m_chistics= &lex->sp_chistics;
-	
+
               lex->sphead->m_body_begin= lex->ptr;
             }
 
@@ -1650,14 +1589,14 @@
           ev_sql_stmt_inner
           {
             LEX *lex=Lex;
-            
+
             if (!$<sphead>1)
             {
               sp_head *sp= lex->sphead;
               // return back to the original memory root ASAP
               sp->init_strings(YYTHD, lex, NULL);
               sp->restore_thd_mem_root(YYTHD);
-	    
+
               lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
 
               lex->et->sphead= lex->sphead;
@@ -1669,14 +1608,14 @@
             }
           }
       ;
-	  
+
 ev_sql_stmt_inner:
           sp_proc_stmt_statement
         | sp_proc_stmt_return
         | sp_proc_stmt_if
         | sp_proc_stmt_case_simple
         | sp_proc_stmt_case
-        | sp_labeled_control {}
+        | sp_labeled_control
         | sp_proc_stmt_unlabeled
         | sp_proc_stmt_leave
         | sp_proc_stmt_iterate
@@ -1705,11 +1644,26 @@
 sp_name:
 	  ident '.' ident
 	  {
+            if (!$1.str || check_db_name($1.str))
+            {
+	      my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
+	      YYABORT;
+	    }
+	    if (check_routine_name($3))
+            {
+	      my_error(ER_SP_WRONG_NAME, MYF(0), $3.str);
+	      YYABORT;
+	    }
 	    $$= new sp_name($1, $3);
 	    $$->init_qname(YYTHD);
 	  }
 	| ident
 	  {
+	    if (check_routine_name($1))
+            {
+	      my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
+	      YYABORT;
+	    }
 	    $$= sp_name_current_db_new(YYTHD, $1);
 	  }
 	;
@@ -1728,6 +1682,16 @@
 	    LEX *lex= Lex;
 	    sp_head *sp;
 
+            /* 
+              First check if AGGREGATE was used, in that case it's a
+              syntax error.
+            */
+            if (lex->udf.type == UDFTYPE_AGGREGATE)
+            {
+              my_error(ER_SP_NO_AGGREGATE, MYF(0));
+              YYABORT;
+            }
+
 	    if (lex->sphead)
 	    {
 	      my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
@@ -2339,7 +2303,6 @@
 	| sp_proc_stmt_case_simple
         | sp_proc_stmt_case
 	| sp_labeled_control
-	  {}
 	| sp_proc_stmt_unlabeled
 	| sp_proc_stmt_leave
 	| sp_proc_stmt_iterate
@@ -2351,7 +2314,9 @@
         ;
 
 sp_proc_stmt_if:
-        IF sp_if END IF {}
+        IF { Lex->sphead->new_cont_backpatch(NULL); }
+        sp_if END IF
+        { Lex->sphead->do_cont_backpatch(); }
         ;
         
 sp_proc_stmt_statement:
@@ -2407,7 +2372,7 @@
 	    LEX *lex= Lex;
 	    sp_head *sp= lex->sphead;
 
-	    if (sp->m_type == TYPE_ENUM_PROCEDURE)
+	    if (sp->m_type != TYPE_ENUM_FUNCTION)
 	    {
 	      my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0));
 	      YYABORT;
@@ -2429,36 +2394,42 @@
 	CASE_SYM WHEN_SYM
 	  {
 	    Lex->sphead->m_flags&= ~sp_head::IN_SIMPLE_CASE;
+            Lex->sphead->new_cont_backpatch(NULL);
 	  }
-	  sp_case END CASE_SYM {}
+          sp_case END CASE_SYM { Lex->sphead->do_cont_backpatch(); }
         ;
         
 sp_proc_stmt_case:
           CASE_SYM
-          { Lex->sphead->reset_lex(YYTHD); }
+          {
+            Lex->sphead->reset_lex(YYTHD);
+            Lex->sphead->new_cont_backpatch(NULL);
+          }
           expr WHEN_SYM
 	  {
 	    LEX *lex= Lex;
 	    sp_head *sp= lex->sphead;
 	    sp_pcontext *parsing_ctx= lex->spcont;
 	    int case_expr_id= parsing_ctx->register_case_expr();
+            sp_instr_set_case_expr *i;
 	    
 	    if (parsing_ctx->push_case_expr_id(case_expr_id))
               YYABORT;
-	    
-	    sp->add_instr(
-	      new sp_instr_set_case_expr(sp->instructions(),
-	                                 parsing_ctx,
-	                                 case_expr_id,
-	                                 $3,
-	                                 lex));
-	    
+
+            i= new sp_instr_set_case_expr(sp->instructions(),
+                                          parsing_ctx,
+                                          case_expr_id,
+                                          $3,
+                                          lex);
+            sp->add_cont_backpatch(i);
+            sp->add_instr(i);
 	    sp->m_flags|= sp_head::IN_SIMPLE_CASE;
 	    sp->restore_lex(YYTHD);
 	  }
 	  sp_case END CASE_SYM
 	  {
 	    Lex->spcont->pop_case_expr_id();
+            Lex->sphead->do_cont_backpatch();
 	  }
         ;
 
@@ -2491,17 +2462,16 @@
 	    }
 	    else
 	    {
-	      uint ip= sp->instructions();
 	      sp_instr_jump *i;
-	      sp_instr_hpop *ih;
-	      sp_instr_cpop *ic;
+	      uint ip= sp->instructions();
+	      uint n;
 
-	      ih= new sp_instr_hpop(ip++, ctx, 0);
-	      sp->push_backpatch(ih, lab);
-	      sp->add_instr(ih);
-	      ic= new sp_instr_cpop(ip++, ctx, 0);
-	      sp->push_backpatch(ic, lab);
-	      sp->add_instr(ic);
+	      n= ctx->diff_handlers(lab->ctx, TRUE);  /* Exclusive the dest. */
+	      if (n)
+	        sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
+	      n= ctx->diff_cursors(lab->ctx, TRUE);  /* Exclusive the dest. */
+	      if (n)
+	        sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
 	      i= new sp_instr_jump(ip, ctx);
 	      sp->push_backpatch(i, lab);  /* Jumping forward */
               sp->add_instr(i);
@@ -2528,10 +2498,10 @@
 	      uint ip= sp->instructions();
 	      uint n;
 
-	      n= ctx->diff_handlers(lab->ctx);
+	      n= ctx->diff_handlers(lab->ctx, FALSE);  /* Inclusive the dest. */
 	      if (n)
 	        sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
-	      n= ctx->diff_cursors(lab->ctx);
+	      n= ctx->diff_cursors(lab->ctx, FALSE);  /* Inclusive the dest. */
 	      if (n)
 	        sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
 	      i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
@@ -2749,6 +2719,7 @@
                                                                $2, lex);
 
 	    sp->push_backpatch(i, ctx->push_label((char *)"", 0));
+            sp->add_cont_backpatch(i);
             sp->add_instr(i);
             sp->restore_lex(YYTHD);
 	  }
@@ -2807,6 +2778,7 @@
 	      i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
 	    }
 	    sp->push_backpatch(i, ctx->push_label((char *)"", 0));
+            sp->add_cont_backpatch(i);
             sp->add_instr(i);
             sp->restore_lex(YYTHD);
 	  }
@@ -2936,6 +2908,7 @@
 
 	    /* Jumping forward */
 	    sp->push_backpatch(i, lex->spcont->last_label());
+            sp->new_cont_backpatch(i);
             sp->add_instr(i);
             sp->restore_lex(YYTHD);
 	  }
@@ -2947,6 +2920,7 @@
 	    sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
 
 	    lex->sphead->add_instr(i);
+            lex->sphead->do_cont_backpatch();
 	  }
         | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM 
           { Lex->sphead->reset_lex(YYTHD); }
@@ -2960,6 +2934,8 @@
                                                                lex);
             lex->sphead->add_instr(i);
             lex->sphead->restore_lex(YYTHD);
+            /* We can shortcut the cont_backpatch here */
+            i->m_cont_dest= ip+1;
 	  }
 	;
 
@@ -3250,7 +3226,7 @@
             LEX *lex= Lex;
             if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)
             {
-              my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
+              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
               YYABORT;
             }
             lex->alter_tablespace_info->nodegroup_id= $3;
@@ -3262,7 +3238,7 @@
             LEX *lex= Lex;
             if (lex->alter_tablespace_info->ts_comment != NULL)
             {
-              my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
+              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
               YYABORT;
             }
             lex->alter_tablespace_info->ts_comment= $3.str;
@@ -3274,7 +3250,7 @@
             LEX *lex= Lex;
             if (lex->alter_tablespace_info->storage_engine != DB_TYPE_UNKNOWN)
             {
-              my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),
+              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),
                        "STORAGE ENGINE");
               YYABORT;
             }
@@ -3297,7 +3273,7 @@
             LEX *lex= Lex;
             if (!(lex->alter_tablespace_info->wait_until_completed))
             {
-              my_error(ER_TABLESPACE_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
+              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
               YYABORT;
             }
             lex->alter_tablespace_info->wait_until_completed= FALSE;
@@ -3363,13 +3339,13 @@
         | LIKE table_ident
           {
             LEX *lex=Lex;
-            if (!(lex->name= (char *)$2))
+            if (!(lex->like_name= $2))
               YYABORT;
           }
         | '(' LIKE table_ident ')'
           {
             LEX *lex=Lex;
-            if (!(lex->name= (char *)$3))
+            if (!(lex->like_name= $3))
               YYABORT;
           }
         ;
@@ -3511,7 +3487,7 @@
           uint expr_len= (uint)($4 - $2) - 1;
           lex->part_info->list_of_part_fields= FALSE;
           lex->part_info->part_expr= $3;
-          lex->part_info->part_func_string= $2+1;
+          lex->part_info->part_func_string= (char* ) sql_memdup($2+1, expr_len);
           lex->part_info->part_func_len= expr_len;
         }
         ;
@@ -3523,7 +3499,7 @@
           uint expr_len= (uint)($4 - $2) - 1;
           lex->part_info->list_of_subpart_fields= FALSE;
           lex->part_info->subpart_expr= $3;
-          lex->part_info->subpart_func_string= $2+1;
+          lex->part_info->subpart_func_string= (char* ) sql_memdup($2+1, expr_len);        
           lex->part_info->subpart_func_len= expr_len;
         }
         ;
@@ -3754,6 +3730,8 @@
               YYABORT;
             }
           }
+          else
+            lex->part_info->part_type= HASH_PARTITION;
         }
         | VALUES LESS_SYM THAN_SYM part_func_max
         {
@@ -3767,6 +3745,8 @@
               YYABORT;
             }
           }
+          else
+            lex->part_info->part_type= RANGE_PARTITION;
         }
         | VALUES IN_SYM '(' part_list_func ')'
         {
@@ -3780,6 +3760,8 @@
               YYABORT;
             }
           }
+          else
+            lex->part_info->part_type= LIST_PARTITION;
         }
         ;
 
@@ -3808,7 +3790,7 @@
 part_range_func:
         '(' part_bit_expr ')' 
         {
-          Lex->part_info->curr_part_elem->range_value= $2;
+          Lex->part_info->curr_part_elem->range_value= $2->value;
         }
         ;
 
@@ -3820,12 +3802,12 @@
 part_list_item:
         part_bit_expr
         {
-          longlong *value_ptr;
-          if (!(value_ptr= (longlong*)sql_alloc(sizeof(longlong))) ||
-              ((*value_ptr= $1, FALSE) ||
-     Lex->part_info->curr_part_elem->list_val_list.push_back(value_ptr)))
+          part_elem_value *value_ptr= $1;
+          if (!value_ptr->null_value &&
+             Lex->part_info->curr_part_elem->
+              list_val_list.push_back((longlong*) &value_ptr->value))
           {
-            mem_alloc_error(sizeof(longlong));
+            mem_alloc_error(sizeof(part_elem_value));
             YYABORT;
           }
         }
@@ -3845,6 +3827,15 @@
 
           context->table_list= 0;
           thd->where= "partition function";
+
+          part_elem_value *value_ptr= 
+            (part_elem_value*)sql_alloc(sizeof(part_elem_value));
+          if (!value_ptr)
+          {
+            mem_alloc_error(sizeof(part_elem_value));
+            YYABORT;
+          }
+
           if (part_expr->fix_fields(YYTHD, (Item**)0) ||
               ((context->table_list= save_list), FALSE) ||
               (!part_expr->const_item()) ||
@@ -3854,18 +3845,36 @@
             YYABORT;
           }
           thd->where= save_where;
-          if (part_expr->result_type() != INT_RESULT)
+          value_ptr->value= part_expr->val_int();
+          if ((value_ptr->null_value= part_expr->null_value))
+          {
+            if (Lex->part_info->curr_part_elem->has_null_value)
+            {
+              my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+              YYABORT;
+            }
+            Lex->part_info->curr_part_elem->has_null_value= TRUE;
+          }
+          else if (part_expr->result_type() != INT_RESULT &&
+                   !part_expr->null_value)
           {
             yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR));
             YYABORT;
           }
-          item_value= part_expr->val_int();
-          $$= item_value; 
+          $$= value_ptr; 
         }
         ;
 
 opt_sub_partition:
-        /* empty */ {}
+        /* empty */
+        {
+          if (Lex->part_info->no_subparts != 0 &&
+              !Lex->part_info->use_default_subpartitions)
+          {
+            yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
+            YYABORT;
+          }
+        }
         | '(' sub_part_list ')'
         {
           LEX *lex= Lex;
@@ -3881,6 +3890,11 @@
           }
           else if (part_info->count_curr_subparts > 0)
           {
+            if (part_info->partitions.elements > 1)
+            {
+              yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
+              YYABORT;
+            }
             part_info->no_subparts= part_info->count_curr_subparts;
           }
           part_info->count_curr_subparts= 0;
@@ -4031,7 +4045,13 @@
 
 create_table_option:
 	ENGINE_SYM opt_equal storage_engines    { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
-	| TYPE_SYM opt_equal storage_engines    { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine");   Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
+	| TYPE_SYM opt_equal storage_engines
+          {
+            Lex->create_info.db_type= $3;
+            WARN_DEPRECATED(yythd, "5.2", "TYPE=storage_engine",
+                            "'ENGINE=storage_engine'");
+            Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
+          }
 	| MAX_ROWS opt_equal ulonglong_num	{ Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
 	| MIN_ROWS opt_equal ulonglong_num	{ Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
 	| AVG_ROW_LENGTH opt_equal ulong_num	{ Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
@@ -4062,21 +4082,6 @@
 	| CHECKSUM_SYM opt_equal ulong_num	{ Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
 	| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE;  Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
 	| ROW_FORMAT_SYM opt_equal row_types	{ Lex->create_info.row_type= $3;  Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
-	| RAID_TYPE opt_equal raid_types
-	  {
-	    my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_TYPE", "PARTITION");
-	    YYABORT;
-	  }
-	| RAID_CHUNKS opt_equal ulong_num
-	  {
-	    my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_CHUNKS", "PARTITION");
-	    YYABORT;
-	  }
-	| RAID_CHUNKSIZE opt_equal ulong_num
-	  {
-	    my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_CHUNKSIZE", "PARTITION");
-	    YYABORT;
-	  }
 	| UNION_SYM opt_equal '(' table_list ')'
 	  {
 	    /* Move the union list to the merge_list */
@@ -4156,11 +4161,6 @@
 	| REDUNDANT_SYM	{ $$= ROW_TYPE_REDUNDANT; }
 	| COMPACT_SYM	{ $$= ROW_TYPE_COMPACT; };
 
-raid_types:
-	RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
-	| RAID_0_SYM	 { $$= RAID_TYPE_0; }
-	| ulong_num	 { $$=$1;};
-
 merge_insert_types:
        NO_SYM            { $$= MERGE_INSERT_DISABLED; }
        | FIRST_SYM       { $$= MERGE_INSERT_TO_FIRST; }
@@ -4231,6 +4231,9 @@
 					    HA_KEY_ALG_UNDEF, 1,
 					    lex->col_list));
 	    lex->col_list.empty();		/* Alloced by sql_alloc */
+
+            /* Only used for ALTER TABLE. Ignored otherwise. */
+            lex->alter_info.flags|= ALTER_FOREIGN_KEY;
 	  }
 	| constraint opt_check_constraint
 	  {
@@ -4779,8 +4782,8 @@
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
+         lex->name= 0;
 	  lex->sql_command= SQLCOM_ALTER_TABLE;
-	  lex->name= 0;
 	  lex->duplicates= DUP_ERROR; 
 	  if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
 						 TL_OPTION_UPDATING))
@@ -4789,13 +4792,15 @@
 	  lex->key_list.empty();
 	  lex->col_list.empty();
           lex->select_lex.init_order();
-	  lex->select_lex.db=lex->name=0;
+	  lex->select_lex.db=lex->name= 0;
+	  lex->like_name= 0;
 	  bzero((char*) &lex->create_info,sizeof(lex->create_info));
 	  lex->create_info.db_type= (handlerton*) &default_hton;
 	  lex->create_info.default_table_charset= NULL;
 	  lex->create_info.row_type= ROW_TYPE_NOT_USED;
 	  lex->alter_info.reset();
 	  lex->alter_info.flags= 0;
+          lex->no_write_to_binlog= 0;
 	}
 	alter_commands
 	{}
@@ -4859,13 +4864,13 @@
 	  view_list_opt AS view_select view_check_option
 	  {}
 	| ALTER EVENT_SYM sp_name
-          /* 
-             BE CAREFUL when you add a new rule to update the block where 
+          /*
+             BE CAREFUL when you add a new rule to update the block where
              YYTHD->client_capabilities is set back to original value
           */
           {
             LEX *lex=Lex;
-            event_timed *et;
+            Event_timed *et;
 
             if (lex->et)
             {
@@ -4877,8 +4882,8 @@
               YYABORT;
             }
             lex->spname= 0;//defensive programming
-	    
-            if (!(et= new event_timed()))// implicitly calls event_timed::init()
+
+            if (!(et= new (YYTHD->mem_root) Event_timed()))// implicitly calls Event_timed::init()
               YYABORT;
             lex->et = et;
 
@@ -4887,7 +4892,7 @@
               et->init_definer(YYTHD);
               et->init_name(YYTHD, $3);
             }
-            
+
             /*
                 We have to turn of CLIENT_MULTI_QUERIES while parsing a
                 stored procedure, otherwise yylex will chop it into pieces
@@ -4914,8 +4919,7 @@
               sql_command is set here because some rules in ev_sql_stmt
               can overwrite it
             */
-            if (!($<ulong_num>5 || $<ulong_num>6 || $<ulong_num>7 ||
-                  $<ulong_num>8 || $<ulong_num>9))
+            if (!($5 || $6 || $7 || $8 || $9))
             {
 	      yyerror(ER(ER_SYNTAX_ERROR));
               YYABORT;
@@ -4927,7 +4931,7 @@
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
           }
-        | ALTER LOGFILE_SYM GROUP alter_logfile_group_info 
+        | ALTER LOGFILE_SYM GROUP alter_logfile_group_info
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
@@ -4937,7 +4941,7 @@
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE;
           }
-        | ALTER TABLESPACE change_tablespace_access 
+        | ALTER TABLESPACE change_tablespace_access
           {
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE;
@@ -4951,27 +4955,24 @@
           }
 	;
 
-ev_alter_on_schedule_completion: /* empty */ { $<ulong_num>$= 0;}
-        | ON SCHEDULE_SYM ev_schedule_time { $<ulong_num>$= 1; }
-        | ev_on_completion { $<ulong_num>$= 1; }
-        | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $<ulong_num>$= 1; }
+ev_alter_on_schedule_completion: /* empty */ { $$= 0;}
+        | ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
+        | ev_on_completion { $$= 1; }
+        | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; }
       ;
 
-opt_ev_rename_to: /* empty */ { $<ulong_num>$= 0;}
+opt_ev_rename_to: /* empty */ { $$= 0;}
         | RENAME TO_SYM sp_name
           {
             LEX *lex=Lex;
             lex->spname= $3; //use lex's spname to hold the new name
-	                     //the original name is in the event_timed object
-            $<ulong_num>$= 1;
+	                     //the original name is in the Event_timed object
+            $$= 1;
           }
       ;
- 
-opt_ev_sql_stmt: /* empty*/ { $<ulong_num>$= 0;}
-        | DO_SYM ev_sql_stmt
-          {
-            $<ulong_num>$= 1;
-          }
+
+opt_ev_sql_stmt: /* empty*/ { $$= 0;}
+        | DO_SYM ev_sql_stmt { $$= 1; }
         ;
 
 
@@ -4984,6 +4985,9 @@
 	| IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; }
         | alter_list
           opt_partitioning
+        | alter_list
+          remove_partitioning
+        | remove_partitioning
         | partitioning
 /*
   This part was added for release 5.1 by Mikael Ronström.
@@ -5049,8 +5053,15 @@
         | reorg_partition_rule
         ;
 
+remove_partitioning:
+        REMOVE_SYM PARTITIONING_SYM
+        {
+          Lex->alter_info.flags|= ALTER_REMOVE_PARTITIONING;
+        }
+        ;
+
 all_or_alt_part_name_list:
-        | ALL
+        ALL
         {
 	  Lex->alter_info.flags|= ALTER_ALL_PARTITION;
         }
@@ -5200,7 +5211,7 @@
 	  }
 	| DROP FOREIGN KEY_SYM opt_ident
           {
-	    Lex->alter_info.flags|= ALTER_DROP_INDEX;
+	    Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY;
           }
 	| DROP PRIMARY_SYM KEY_SYM
 	  {
@@ -5419,6 +5430,8 @@
 	RESTORE_SYM table_or_tables
 	{
 	   Lex->sql_command = SQLCOM_RESTORE_TABLE;
+           WARN_DEPRECATED(yythd, "5.2", "RESTORE TABLE",
+                           "MySQL Administrator (mysqldump, mysql)");
 	}
 	table_list FROM TEXT_STRING_sys
         {
@@ -5429,6 +5442,8 @@
 	BACKUP_SYM table_or_tables
 	{
 	   Lex->sql_command = SQLCOM_BACKUP_TABLE;
+           WARN_DEPRECATED(yythd, "5.2", "BACKUP TABLE",
+                           "MySQL Administrator (mysqldump, mysql)");
 	}
 	table_list TO_SYM TEXT_STRING_sys
         {
@@ -5526,7 +5541,8 @@
 	| FAST_SYM { Lex->check_opt.flags|= T_FAST; }
 	| MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
 	| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
-	| CHANGED  { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; };
+	| CHANGED  { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
+        | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; };
 
 optimize:
 	OPTIMIZE opt_no_write_to_binlog table_or_tables
@@ -5553,6 +5569,13 @@
 	}
 	table_to_table_list
 	{}
+	| RENAME DATABASE
+          {
+            Lex->db_list.empty();
+            Lex->sql_command= SQLCOM_RENAME_DB;
+          }
+          db_to_db
+          {}
 	| RENAME USER clear_privileges rename_list
           {
 	    Lex->sql_command = SQLCOM_RENAME_USER;
@@ -5588,6 +5611,17 @@
 	    YYABORT;
 	};
 
+db_to_db:
+	ident TO_SYM ident
+	{
+	  LEX *lex=Lex;
+          if (Lex->db_list.push_back((LEX_STRING*)
+                                     sql_memdup(&$1, sizeof(LEX_STRING))) ||
+              Lex->db_list.push_back((LEX_STRING*)
+                                     sql_memdup(&$3, sizeof(LEX_STRING))))
+              YYABORT;
+	};
+
 keycache:
         CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
         {
@@ -6416,9 +6450,19 @@
 	| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
 	  { $$= new Item_func_substr_index($3,$5,$7); }
 	| SYSDATE optional_braces
-	  { $$= new Item_func_sysdate_local(); Lex->safe_to_cache_query=0;}
+          {
+            if (global_system_variables.sysdate_is_now == 0)
+              $$= new Item_func_sysdate_local();
+            else $$= new Item_func_now_local();
+            Lex->safe_to_cache_query=0;
+          }
 	| SYSDATE '(' expr ')'
-	  { $$= new Item_func_sysdate_local($3); Lex->safe_to_cache_query=0;}
+          {
+            if (global_system_variables.sysdate_is_now == 0)
+              $$= new Item_func_sysdate_local($3);
+            else $$= new Item_func_now_local($3);
+            Lex->safe_to_cache_query=0;
+          }
 	| TIME_SYM '(' expr ')'
 	  { $$= new Item_time_typecast($3); }
 	| TIMESTAMP '(' expr ')'
@@ -6489,6 +6533,8 @@
               if (udf->type == UDFTYPE_AGGREGATE)
                 Select->in_sum_expr--;
 
+              Lex->binlog_row_based_if_mixed= 1;
+
               switch (udf->returns) {
               case STRING_RESULT:
                 if (udf->type == UDFTYPE_FUNCTION)
@@ -6675,9 +6721,20 @@
 	;
 
 fulltext_options:
-        /* nothing */                   { $$= FT_NL;  }
-        | WITH QUERY_SYM EXPANSION_SYM  { $$= FT_NL | FT_EXPAND; }
-        | IN_SYM BOOLEAN_SYM MODE_SYM   { $$= FT_BOOL; }
+          opt_natural_language_mode opt_query_expansion
+          { $$= $1 | $2; }
+        | IN_SYM BOOLEAN_SYM MODE_SYM
+          { $$= FT_BOOL; }
+        ;
+
+opt_natural_language_mode:
+        /* nothing */                           { $$= FT_NL;  }
+        | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM  { $$= FT_NL; }
+        ;
+
+opt_query_expansion:
+        /* nothing */                           { $$= 0;         }
+        | WITH QUERY_SYM EXPANSION_SYM          { $$= FT_EXPAND; }
         ;
 
 udf_expr_list:
@@ -7168,9 +7225,8 @@
         {
 	  LEX *lex= Lex;
 	  lex->derived_tables|= DERIVED_SUBQUERY;
-	  if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
-	       lex->sql_command <= (int)SQLCOM_HA_READ) ||
-	       lex->sql_command == (int)SQLCOM_KILL)
+          if (lex->sql_command == (int)SQLCOM_HA_READ ||
+              lex->sql_command == (int)SQLCOM_KILL)
 	  {
 	    yyerror(ER(ER_SYNTAX_ERROR));
 	    YYABORT;
@@ -7748,7 +7804,7 @@
               YYABORT;
             }
 
-            if (!(lex->et= new event_timed()))
+            if (!(lex->et= new (YYTHD->mem_root) Event_timed()))
               YYABORT;
 	  
             if (!lex->et_compile_phase)
@@ -7847,7 +7903,19 @@
 	;
 
 insert_lock_option:
-	/* empty */	{ $$= TL_WRITE_CONCURRENT_INSERT; }
+	/* empty */
+          {
+#ifdef HAVE_QUERY_CACHE
+            /*
+              If it is SP we do not allow insert optimisation whan result of
+              insert visible only after the table unlocking but everyone can
+              read table.
+            */
+            $$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT);
+#else
+            $$= TL_WRITE_CONCURRENT_INSERT;
+#endif
+          }
 	| LOW_PRIORITY	{ $$= TL_WRITE_LOW_PRIORITY; }
 	| DELAYED_SYM	{ $$= TL_WRITE_DELAYED; }
 	| HIGH_PRIORITY { $$= TL_WRITE; }
@@ -8185,6 +8253,15 @@
         | PLUGIN_SYM
 	  {
 	    LEX *lex= Lex;
+	    WARN_DEPRECATED(yythd, "5.2", "SHOW PLUGIN", "'SHOW PLUGINS'");
+            lex->sql_command= SQLCOM_SELECT;
+            lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
+            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
+              YYABORT;
+	  }
+        | PLUGINS_SYM
+	  {
+	    LEX *lex= Lex;
             lex->sql_command= SQLCOM_SELECT;
             lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
             if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
@@ -8248,7 +8325,7 @@
 	  {
 	    LEX *lex=Lex;
 	    lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
-	    WARN_DEPRECATED("SHOW TABLE TYPES", "SHOW [STORAGE] ENGINES");
+	    WARN_DEPRECATED(yythd, "5.2", "SHOW TABLE TYPES", "'SHOW [STORAGE] ENGINES'");
 	  }
 	| opt_storage ENGINES_SYM
 	  {
@@ -8284,7 +8361,7 @@
             lex->option_type= $1;
             if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
               YYABORT;
-	  }	
+	  }
         | INNOBASE_SYM STATUS_SYM
           {
             LEX *lex= Lex;
@@ -8295,19 +8372,19 @@
 	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
 	      YYABORT;
             }
-            WARN_DEPRECATED("SHOW INNODB STATUS", "SHOW ENGINE INNODB STATUS");
+            WARN_DEPRECATED(yythd, "5.2", "SHOW INNODB STATUS", "'SHOW ENGINE INNODB STATUS'");
 	  }
         | MUTEX_SYM STATUS_SYM
           {
 	    LEX *lex= Lex;
-            lex->sql_command = SQLCOM_SHOW_ENGINE_MUTEX; 
+            lex->sql_command = SQLCOM_SHOW_ENGINE_MUTEX;
             if (!(lex->create_info.db_type=
                   ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB)))
             {
 	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB");
 	      YYABORT;
             }
-            WARN_DEPRECATED("SHOW MUTEX STATUS", "SHOW ENGINE INNODB MUTEX");
+            WARN_DEPRECATED(yythd, "5.2", "SHOW MUTEX STATUS", "'SHOW ENGINE INNODB MUTEX'");
 	  }
 	| opt_full PROCESSLIST_SYM
 	  { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
@@ -8346,7 +8423,7 @@
 	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "BerkeleyDB");
 	      YYABORT;
             }
-	    WARN_DEPRECATED("SHOW BDB LOGS", "SHOW ENGINE BDB LOGS");
+	    WARN_DEPRECATED(yythd, "5.2", "SHOW BDB LOGS", "'SHOW ENGINE BDB LOGS'");
 	  }
 	| LOGS_SYM
 	  {
@@ -8358,7 +8435,7 @@
 	      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "BerkeleyDB");
 	      YYABORT;
             }
-	    WARN_DEPRECATED("SHOW LOGS", "SHOW ENGINE BDB LOGS");
+	    WARN_DEPRECATED(yythd, "5.2", "SHOW LOGS", "'SHOW ENGINE BDB LOGS'");
 	  }
 	| GRANTS
 	  {
@@ -8479,6 +8556,10 @@
           {
             Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
             Lex->spname= $3;
+            Lex->et= new (YYTHD->mem_root) Event_timed();
+            if (!Lex->et)
+              YYABORT;
+            Lex->et->init_definer(YYTHD);
           }
       ;
 
@@ -8668,18 +8749,18 @@
 /* kill threads */
 
 kill:
-	KILL_SYM kill_option expr
+	KILL_SYM { Lex->sql_command= SQLCOM_KILL; } kill_option expr
 	{
 	  LEX *lex=Lex;
 	  lex->value_list.empty();
-	  lex->value_list.push_front($3);
-          lex->sql_command= SQLCOM_KILL;
+	  lex->value_list.push_front($4);
 	};
 
 kill_option:
 	/* empty */	 { Lex->type= 0; }
 	| CONNECTION_SYM { Lex->type= 0; }
-	| QUERY_SYM      { Lex->type= ONLY_KILL_QUERY; };
+	| QUERY_SYM      { Lex->type= ONLY_KILL_QUERY; }
+        ;
 
 /* change database */
 
@@ -8692,7 +8773,7 @@
 
 /* import, export of files */
 
-load:   LOAD DATA_SYM 
+load:   LOAD DATA_SYM
         {
           LEX *lex=Lex;
 	  if (lex->sphead)
@@ -8708,7 +8789,9 @@
         LOAD TABLE_SYM table_ident FROM MASTER_SYM
         {
 	  LEX *lex=Lex;
-	  if (lex->sphead)
+          WARN_DEPRECATED(yythd, "5.2", "LOAD TABLE FROM MASTER",
+                          "MySQL Administrator (mysqldump, mysql)");
+          if (lex->sphead)
 	  {
 	    my_error(ER_SP_BADSTATEMENT, MYF(0), "LOAD TABLE");
 	    YYABORT;
@@ -8760,7 +8843,16 @@
 
 load_data_lock:
 	/* empty */	{ $$= YYTHD->update_lock_default; }
-	| CONCURRENT	{ $$= TL_WRITE_CONCURRENT_INSERT ; }
+	| CONCURRENT
+          {
+#ifdef HAVE_QUERY_CACHE
+            /*
+              Ignore this option in SP to avoid problem with query cache
+            */
+            if (Lex->sphead != 0)
+#endif
+              $$= TL_WRITE_CONCURRENT_INSERT;
+          }
 	| LOW_PRIORITY	{ $$= TL_WRITE_LOW_PRIORITY; };
 
 
@@ -9092,7 +9184,8 @@
                                                   new_row ?
                                                   Item_trigger_field::NEW_ROW:
                                                   Item_trigger_field::OLD_ROW,
-                                                  $3.str)))
+                                                  $3.str,
+                                                  Item_trigger_field::AT_READ)))
               YYABORT;
 
             /*
@@ -9357,9 +9450,9 @@
 	| OWNER_SYM		{}
         | PARSER_SYM            {}
 	| PARTITION_SYM		{}
-        | PLUGIN_SYM            {}
         | PORT_SYM              {}
         | PREPARE_SYM           {}
+	| REMOVE_SYM		{}
 	| REPAIR		{}
 	| RESET_SYM		{}
 	| RESTORE_SYM		{}
@@ -9537,9 +9630,12 @@
         | ONE_SYM               {}
 	| PACK_KEYS_SYM		{}
 	| PARTIAL		{}
+	| PARTITIONING_SYM	{}
 	| PARTITIONS_SYM	{}
 	| PASSWORD		{}
         | PHASE_SYM             {}
+        | PLUGIN_SYM            {}
+        | PLUGINS_SYM           {}
 	| POINT_SYM		{}
 	| POLYGON		{}
         | PRESERVE_SYM          {}
@@ -9550,15 +9646,10 @@
 	| QUARTER_SYM		{}
 	| QUERY_SYM		{}
 	| QUICK			{}
-	| RAID_0_SYM		{}
-	| RAID_CHUNKS		{}
-	| RAID_CHUNKSIZE	{}
-	| RAID_STRIPED_SYM	{}
-	| RAID_TYPE		{}
         | REBUILD_SYM           {}
         | RECOVER_SYM           {}
 	| REDO_BUFFER_SIZE_SYM	{}
-	| REDOFILE_SYM  	{}
+	| REDOFILE_SYM          {}
         | REDUNDANT_SYM         {}
 	| RELAY_LOG_FILE_SYM	{}
 	| RELAY_LOG_POS_SYM	{}
@@ -9782,7 +9873,9 @@
 
             if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
                                                   Item_trigger_field::NEW_ROW,
-                                                  $2.base_name.str)) ||
+                                                  $2.base_name.str,
+                                                  Item_trigger_field::AT_UPDATE)
+                                                  ) ||
                 !(sp_fld= new sp_instr_set_trigger_field(lex->sphead->
                           	                         instructions(),
                                 	                 lex->spcont,
@@ -9835,8 +9928,7 @@
         | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
 	{
 	  LEX *lex=Lex;
-          if ($1)
-            lex->option_type= $1;
+	  lex->option_type= $1;
 	  lex->var_list.push_back(new set_var(lex->option_type,
                                               find_sys_var("tx_isolation"),
                                               &null_lex_str,
@@ -10320,6 +10412,7 @@
 	| ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; }
 	| CREATE USER { Lex->grant |= CREATE_USER_ACL; }
         | EVENT_SYM { Lex->grant |= EVENT_ACL;}
+        | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; }
 	;
 
 
@@ -10766,9 +10859,8 @@
 	'(' SELECT_SYM
 	{
 	  LEX *lex=Lex;
-	  if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN &&
-	       lex->sql_command <= (int)SQLCOM_HA_READ) ||
-	       lex->sql_command == (int)SQLCOM_KILL)
+          if (lex->sql_command == (int)SQLCOM_HA_READ ||
+              lex->sql_command == (int)SQLCOM_KILL)
 	  {
             yyerror(ER(ER_SYNTAX_ERROR));
 	    YYABORT;
@@ -10786,45 +10878,61 @@
           lex->nest_level--;
 	};
 
+/**************************************************************************
+
+ CREATE VIEW | TRIGGER | PROCEDURE statements.
+
+**************************************************************************/
+
+view_or_trigger_or_sp:
+	definer view_or_trigger_or_sp_tail
+	{}
+	| view_replace_or_algorithm definer view_tail
+	{}
+	;
+
+view_or_trigger_or_sp_tail:
+	view_tail
+	{}
+	| trigger_tail
+	{}
+	| sp_tail
+	{}
+	;
+
+/**************************************************************************
+
+ DEFINER clause support.
+
+**************************************************************************/
+
 definer:
-	get_definer
+	/* empty */
 	{
-	  THD *thd= YYTHD;
-	  
-	  if (! (thd->lex->definer= create_definer(thd, &$1->user, &$1->host)))
-	    YYABORT;
+          /*
+            We have to distinguish missing DEFINER-clause from case when
+            CURRENT_USER specified as definer explicitly in order to properly
+            handle CREATE TRIGGER statements which come to replication thread
+            from older master servers (i.e. to create non-suid trigger in this
+            case).
+           */
+          YYTHD->lex->definer= 0;
 	}
-	;
-
-get_definer:
-	opt_current_definer
+	| DEFINER_SYM EQ CURRENT_USER optional_braces
 	{
-	  THD *thd= YYTHD;
-          
-	  if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
-	    YYABORT;
-
-	  if (get_default_definer(thd, $$))
-	    YYABORT;
+          if (! (YYTHD->lex->definer= create_default_definer(YYTHD)))
+            YYABORT;
 	}
 	| DEFINER_SYM EQ ident_or_text '@' ident_or_text
 	{
-	  if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
-	    YYABORT;
-
-	  $$->user= $3;
-	  $$->host= $5;
+          if (!(YYTHD->lex->definer= create_definer(YYTHD, &$3, &$5)))
+            YYABORT;
 	}
 	;
 
-opt_current_definer:
-	/* empty */
-	| DEFINER_SYM EQ CURRENT_USER optional_braces
-	;
-
 /**************************************************************************
 
- CREATE VIEW statement options.
+ CREATE VIEW statement parts.
 
 **************************************************************************/
 
@@ -10858,20 +10966,6 @@
 	{}
 	;
 
-view_or_trigger:
-	definer view_or_trigger_tail
-	{}
-	| view_replace_or_algorithm definer view_tail
-	{}
-	;
-
-view_or_trigger_tail:
-	view_tail
-	{}
-	| trigger_tail
-	{}
-	;
-
 view_suid:
 	/* empty */
 	{ Lex->create_view_suid= TRUE; }
@@ -10953,25 +11047,27 @@
 **************************************************************************/
 
 trigger_tail:
-	TRIGGER_SYM remember_name sp_name trg_action_time trg_event 
-	ON table_ident FOR_SYM EACH_SYM ROW_SYM
+	TRIGGER_SYM remember_name sp_name trg_action_time trg_event
+	ON remember_name table_ident FOR_SYM remember_name EACH_SYM ROW_SYM
 	{
 	  LEX *lex= Lex;
 	  sp_head *sp;
-	 
+
 	  if (lex->sphead)
 	  {
 	    my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
 	    YYABORT;
 	  }
-	
+
 	  if (!(sp= new sp_head()))
 	    YYABORT;
 	  sp->reset_thd_mem_root(YYTHD);
 	  sp->init(lex);
-	
-	  lex->trigger_definition_begin= $2;
-	  
+
+	  lex->stmt_definition_begin= $2;
+          lex->ident.str= $7;
+          lex->ident.length= $10 - $7;
+
 	  sp->m_type= TYPE_ENUM_TRIGGER;
 	  lex->sphead= sp;
 	  lex->spname= $3;
@@ -10982,7 +11078,7 @@
 	  */
 	  $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
 	  YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
-	  
+
 	  bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
 	  lex->sphead->m_chistics= &lex->sp_chistics;
 	  lex->sphead->m_body_begin= lex->ptr;
@@ -10993,31 +11089,111 @@
 	{
 	  LEX *lex= Lex;
 	  sp_head *sp= lex->sphead;
-	  
+
 	  lex->sql_command= SQLCOM_CREATE_TRIGGER;
 	  sp->init_strings(YYTHD, lex, $3);
 	  /* Restore flag if it was cleared above */
 
-	  YYTHD->client_capabilities |= $<ulong_num>11;
+	  YYTHD->client_capabilities |= $<ulong_num>13;
 	  sp->restore_thd_mem_root(YYTHD);
-	
+
 	  if (sp->is_not_allowed_in_function("trigger"))
 	      YYABORT;
-	
+
 	  /*
 	    We have to do it after parsing trigger body, because some of
 	    sp_proc_stmt alternatives are not saving/restoring LEX, so
 	    lex->query_tables can be wiped out.
-	    
-	    QQ: What are other consequences of this?
-	    
-	    QQ: Could we loosen lock type in certain cases ?
 	  */
-	  if (!lex->select_lex.add_table_to_list(YYTHD, $7, 
+	  if (!lex->select_lex.add_table_to_list(YYTHD, $8,
 	                                         (LEX_STRING*) 0,
 	                                         TL_OPTION_UPDATING,
-	                                         TL_WRITE))
+                                                 TL_IGNORE))
 	    YYABORT;
+	}
+	;
+
+/**************************************************************************
+
+ CREATE FUNCTION | PROCEDURE statements parts.
+
+**************************************************************************/
+
+sp_tail:
+	udf_func_type remember_name FUNCTION_SYM sp_name
+	{
+	  LEX *lex=Lex;
+	  lex->udf.type= $1;
+	  lex->stmt_definition_begin= $2;
+	  lex->spname= $4;
+	}
+	create_function_tail
+	{}
+	| PROCEDURE remember_name sp_name
+	{
+	  LEX *lex= Lex;
+	  sp_head *sp;
+
+	  if (lex->sphead)
+	  {
+	    my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
+	    YYABORT;
+	  }
+	  
+	  lex->stmt_definition_begin= $2;
+	  
+	  /* Order is important here: new - reset - init */
+	  sp= new sp_head();
+	  sp->reset_thd_mem_root(YYTHD);
+	  sp->init(lex);
+
+	  sp->m_type= TYPE_ENUM_PROCEDURE;
+	  lex->sphead= sp;
+	  /*
+	   * We have to turn of CLIENT_MULTI_QUERIES while parsing a
+	   * stored procedure, otherwise yylex will chop it into pieces
+	   * at each ';'.
+	   */
+          $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
+	  YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
+	}
+        '('
+	{
+	  LEX *lex= Lex;
+
+	  lex->sphead->m_param_begin= lex->tok_start+1;
+	}
+	sp_pdparam_list
+	')'
+	{
+	  LEX *lex= Lex;
+
+	  lex->sphead->m_param_end= lex->tok_start;
+	  bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
+	}
+	sp_c_chistics
+	{
+	  LEX *lex= Lex;
+
+	  lex->sphead->m_chistics= &lex->sp_chistics;
+	  lex->sphead->m_body_begin= lex->tok_start;
+	}
+	sp_proc_stmt
+	{
+	  LEX *lex= Lex;
+	  sp_head *sp= lex->sphead;
+
+	  if (sp->check_backpatch(YYTHD))
+	    YYABORT;
+	  sp->init_strings(YYTHD, lex, $3);
+	  lex->sql_command= SQLCOM_CREATE_PROCEDURE;
+          /*
+            Restore flag if it was cleared above
+            Be careful with counting. the block where we save the value
+            is $4.
+          */
+          YYTHD->client_capabilities |= $<ulong_num>4;
+	  sp->restore_thd_mem_root(YYTHD);
 	}
 	;
 

--- 1.90/sql/share/errmsg.txt	2006-03-20 12:41:16 -08:00
+++ 1.91/sql/share/errmsg.txt	2006-04-08 14:47:20 -07:00
@@ -5763,6 +5763,9 @@
 	eng "Table definition on master and slave does not match"
 ER_BINLOG_ROW_RBR_TO_SBR
 	eng "Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events"
+ER_FOREIGN_SERVER_DOESNT_EXIST
+        eng "The foreign server name you are trying to reference does not exist. Data source error:  %-.64s"
+	ger "Die externe Verbindung, auf die Sie zugreifen wollen, existiert nicht. Datenquellenfehlermeldung:  %-.64s"
 ER_EVENT_ALREADY_EXISTS
         eng "Event '%-.64s' already exists"
 ER_EVENT_STORE_FAILED
@@ -5802,6 +5805,8 @@
         eng "You can't write-lock a log table. Only read access is possible."
 ER_CANT_READ_LOCK_LOG_TABLE
         eng "You can't use usual read lock with log tables. Try READ LOCAL instead."
+ER_FOREIGN_SERVER_EXISTS
+        eng "The foreign server, %s, you are trying to create already exists."
 ER_SP_WRONG_NAME 42000
 	eng "Incorrect routine name '%-.64s'"
 ER_FOREIGN_DUPLICATE_KEY 23000 S1009

--- 1.26/mysql-test/lib/init_db.sql	2006-03-24 08:45:44 -08:00
+++ 1.27/mysql-test/lib/init_db.sql	2006-04-08 14:08:50 -07:00
@@ -114,6 +114,21 @@
 INSERT  INTO user (host,user) VALUES ('localhost','');
 INSERT  INTO user (host,user) VALUES ('@HOSTNAME@%','');
 
+CREATE TABLE servers (
+  Server_name char(64) NOT NULL DEFAULT '',
+  Host char(64) NOT NULL DEFAULT '',
+  Db char(64) NOT NULL DEFAULT '',
+  Username char(64) NOT NULL DEFAULT '',
+  Password char(64) NOT NULL DEFAULT '',
+  Port INT(4) NOT NULL DEFAULT '0',
+  Socket char(64) NOT NULL DEFAULT '',
+  Wrapper char(64) NOT NULL DEFAULT '',
+  Owner char(64) NOT NULL DEFAULT '',
+  PRIMARY KEY (Server_name))
+  comment='MySQL Foreign Servers table';
+
+INSERT INTO servers VALUES ('test','localhost','test','root','', 0,'','mysql','root');
+
 
 CREATE TABLE func (
   name char(64) binary DEFAULT '' NOT NULL,

--- 1.80/libmysqld/Makefile.am	2006-02-09 18:28:58 -08:00
+++ 1.81/libmysqld/Makefile.am	2006-04-08 14:47:20 -07:00
@@ -22,6 +22,7 @@
 MYSQLBASEdir=		$(prefix)
 MYSQLLIBdir=            $(libdir)
 
+EXTRA_DIST =		libmysqld.def
 DEFS =			-DEMBEDDED_LIBRARY -DMYSQL_SERVER \
 			-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
 			-DDATADIR="\"$(MYSQLDATAdir)\"" \
@@ -67,7 +68,7 @@
         event_executor.cc event.cc event_timed.cc \
         rpl_filter.cc sql_partition.cc handlerton.cc sql_plugin.cc \
         sql_tablespace.cc \
-        rpl_injector.cc my_user.c \
+        rpl_injector.cc my_user.c partition_info.cc
 	sql_servers.cc
 
 libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
@@ -94,8 +95,12 @@
 		$(top_builddir)/dbug/libdbug.a \
 		$(top_builddir)/vio/libvio.a \
 		@mysql_se_libs@ \
-                @yassl_libs_with_path@
+		$(yassl_las)
 
+if HAVE_YASSL
+yassl_las = $(top_srcdir)/extra/yassl/src/libyassl.la \
+	    $(top_srcdir)/extra/yassl/taocrypt/src/libtaocrypt.la
+endif
 
 # Storage engine specific compilation options
 

--- 1.56/sql/ha_federated.cc	2006-03-29 03:27:30 -08:00
+++ 1.57/sql/ha_federated.cc	2006-04-08 14:47:20 -07:00
@@ -586,13 +586,14 @@
   int buf_len;
   DBUG_ENTER("ha_federated parse_url_error");
 
-  if (share->scheme)
+  if (share->connection_string)
   {
     DBUG_PRINT("info",
                ("error: parse_url. Returning error code %d \
-                freeing share->scheme %lx", error_num, share->scheme));
-    my_free((gptr) share->scheme, MYF(0));
-    share->scheme= 0;
+                freeing share->connection_string %lx",
+                error_num, share->connection_string));
+    my_free((gptr) share->connection_string, MYF(0));
+    share->connection_string= 0;
   }
   buf_len= min(table->s->connect_string.length,
                FEDERATED_QUERY_BUFFER_SIZE-1);
@@ -602,6 +603,75 @@
 }
 
 /*
+  retrieve server object which contains server meta-data 
+  from the system table given a server's name, set share
+  connection parameter members
+*/
+int get_connection(FEDERATED_SHARE *share)
+{
+  int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST;
+  char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
+  FOREIGN_SERVER *server;
+  MYSQL *mysql_conn;
+  MYSQL_RES *result= 0;
+  MYSQL_ROW row;
+  DBUG_ENTER("ha_federated::get_connection");
+
+  if (!(server=
+       get_server_by_name(share->connection_string)))
+  {
+    DBUG_PRINT("info", ("get_server_by_name returned > 0 error condition!"));
+    /* need to come up with error handling */
+    error_num=1;
+    goto error;
+  }
+  DBUG_PRINT("info", ("get_server_by_name returned server at %lx", server));
+
+  /*
+    Most of these should never be empty strings, error handling will
+    need to be implemented. Also, is this the best way to set the share
+    members? Is there some allocation needed? In running this code, it works
+    except there are errors in the trace file of the share being overrun 
+    at the address of the share.
+  */
+  if (server->server_name)
+    share->server_name= server->server_name;
+  share->server_name_length= server->server_name_length ?
+    server->server_name_length : 0;
+  if (server->username)
+    share->username= server->username;
+  if (server->password)
+    share->password= server->password;
+  if (server->db)
+    share->database= server->db;
+  if (server->sport)
+    share->sport= server->sport;
+  share->port= server->port ? server->port : 0;
+  if (server->host)
+    share->hostname= server->host;
+  if (server->socket)
+    share->socket= server->socket;
+  if (server->scheme)
+    share->scheme= server->scheme;
+  else
+    share->scheme= NULL;
+
+  DBUG_PRINT("info", ("share->username %s", share->username));
+  DBUG_PRINT("info", ("share->password %s", share->password));
+  DBUG_PRINT("info", ("share->hostname %s", share->hostname));
+  DBUG_PRINT("info", ("share->database %s", share->database));
+  DBUG_PRINT("info", ("share->port %d", share->port));
+  DBUG_PRINT("info", ("share->socket %d", share->socket));
+  DBUG_RETURN(0);
+
+error:
+  my_sprintf(error_buffer,
+             (error_buffer, "server name: '%s' doesn't exist!",
+              share->connection_string));
+  my_error(error_num, MYF(0), error_buffer);
+  DBUG_RETURN(error_num);
+}
+/*
   Parse connection info from table->s->connect_string
 
   SYNOPSIS
@@ -613,22 +683,39 @@
   DESCRIPTION
     Populates the share with information about the connection
     to the foreign database that will serve as the data source.
-    This string must be specified (currently) in the "comment" field,
+    This string must be specified (currently) in the "CONNECTION" field,
     listed in the CREATE TABLE statement.
 
     This string MUST be in the format of any of these:
 
-    scheme://username:password@hostname:port/database/table
-    scheme://username@hostname/database/table
-    scheme://username@hostname:port/database/table
-    scheme://username:password@hostname/database/table
+    CONNECTION="scheme://username:password@hostname:port/database/table"
+    CONNECTION="scheme://username@hostname/database/table"
+    CONNECTION="scheme://username@hostname:port/database/table"
+    CONNECTION="scheme://username:password@hostname/database/table"
+
+    _OR_
+
+    CONNECTION="connection name"
+
+    
 
   An Example:
 
-  mysql://joe:joespass@stripped:9308/federated/testtable
+  CREATE TABLE t1 (id int(32))
+    ENGINE="FEDERATED"
+    CONNECTION="mysql://joe:joespass@stripped:9308/federated/testtable";
+
+  CREATE TABLE t2 (
+    id int(4) NOT NULL auto_increment,
+    name varchar(32) NOT NULL,
+    PRIMARY KEY(id)
+    ) ENGINE="FEDERATED" CONNECTION="my_conn";
 
   ***IMPORTANT***
-  Currently, only "mysql://" is supported.
+  Currently, the Federated Storage Engine only supports connecting to another
+  MySQL Database ("scheme" of "mysql"). Connections using JDBC as well as 
+  other connectors are in the planning stage.
+  
 
   'password' and 'port' are both optional.
 
@@ -648,89 +735,122 @@
 
   share->port= 0;
   share->socket= 0;
+  DBUG_PRINT("info", ("share at %lx", share));
   DBUG_PRINT("info", ("Length: %d", table->s->connect_string.length));
-  DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length, 
+  DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length,
                       table->s->connect_string.str));
-  share->scheme= my_strndup((const byte*)table->s->
+  share->connection_string= my_strndup((const byte*)table->s->
                                        connect_string.str, 
                                        table->s->connect_string.length,
                                        MYF(0));
 
   // Add a null for later termination of table name
-  share->scheme[table->s->connect_string.length]= 0;
-  DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme));
-
-  /*
-    remove addition of null terminator and store length
-    for each string  in share
-  */
-  if (!(share->username= strstr(share->scheme, "://")))
-    goto error;
-  share->scheme[share->username - share->scheme]= '\0';
-
-  if (strcmp(share->scheme, "mysql") != 0)
-    goto error;
-
-  share->username+= 3;
+  share->connection_string[table->s->connect_string.length]= 0;
+  DBUG_PRINT("info",("parse_url alloced share->scheme %lx",
+                     share->connection_string));
+
+  DBUG_PRINT("info",("share->connection_string %s",share->connection_string));
+  /* No delimiters, must be a straight connection name */
+  if ( (!strchr(share->connection_string, '/')) &&
+       (!strchr(share->connection_string, '@')) &&
+       (!strchr(share->connection_string, ';')))
+  {
 
-  if (!(share->hostname= strchr(share->username, '@')))
-    goto error;
-    
-  share->username[share->hostname - share->username]= '\0';
-  share->hostname++;
+    DBUG_PRINT("info",
+               ("share->connection_string %s internal format \
+                share->connection_string",
+                share->connection_string, share->connection_string));
 
-  if ((share->password= strchr(share->username, ':')))
-  {
-    share->username[share->password - share->username]= '\0';
-    share->password++;
-    share->username= share->username;
-    /* make sure there isn't an extra / or @ */
-    if ((strchr(share->password, '/') || strchr(share->hostname, '@')))
+    if ((error_num= get_connection(share)))
       goto error;
+
     /*
-      Found that if the string is:
-      user:@hostname:port/database/table
-      Then password is a null string, so set to NULL
+      connection specifies everything but, resort to
+      expecting remote and foreign table names to match
     */
-    if ((share->password[0] == '\0'))
-      share->password= NULL;
+    share->table_name= table->s->table_name.str;
+    share->table_name_length= table->s->table_name.length;
+    share->table_name[share->table_name_length]= '\0';
   }
   else
-    share->username= share->username;
+  {
+    // Add a null for later termination of table name
+    share->connection_string[table->s->connect_string.length]= 0;
+    share->scheme= share->connection_string;
+    DBUG_PRINT("info",("parse_url alloced share->scheme %lx", share->scheme));
 
-  /* make sure there isn't an extra / or @ */
-  if ((strchr(share->username, '/')) || (strchr(share->hostname, '@')))
-    goto error;
+    /*
+      remove addition of null terminator and store length
+      for each string  in share
+    */
+    if (!(share->username= strstr(share->scheme, "://")))
+      goto error;
+    share->scheme[share->username - share->scheme]= '\0';
 
-  if (!(share->database= strchr(share->hostname, '/')))
-    goto error;
-  share->hostname[share->database - share->hostname]= '\0';
-  share->database++;
+    if (strcmp(share->scheme, "mysql") != 0)
+      goto error;
 
-  if ((share->sport= strchr(share->hostname, ':')))
-  {
-    share->hostname[share->sport - share->hostname]= '\0';
-    share->sport++;
-    if (share->sport[0] == '\0')
-      share->sport= NULL;
+    share->username+= 3;
+
+    if (!(share->hostname= strchr(share->username, '@')))
+      goto error;
+
+    share->username[share->hostname - share->username]= '\0';
+    share->hostname++;
+
+    if ((share->password= strchr(share->username, ':')))
+    {
+      share->username[share->password - share->username]= '\0';
+      share->password++;
+      share->username= share->username;
+      /* make sure there isn't an extra / or @ */
+      if ((strchr(share->password, '/') || strchr(share->hostname, '@')))
+        goto error;
+      /*
+        Found that if the string is:
+user:@hostname:port/db/table
+Then password is a null string, so set to NULL
+    */
+      if ((share->password[0] == '\0'))
+        share->password= NULL;
+    }
     else
-      share->port= atoi(share->sport);
-  }
+      share->username= share->username;
 
-  if (!(share->table_name= strchr(share->database, '/')))
-    goto error;
-  share->database[share->table_name - share->database]= '\0';
-  share->table_name++;
+    /* make sure there isn't an extra / or @ */
+    if ((strchr(share->username, '/')) || (strchr(share->hostname, '@')))
+      goto error;
 
-  share->table_name_length= strlen(share->table_name);
-      
-  /* make sure there's not an extra / */
-  if ((strchr(share->table_name, '/')))
-    goto error;
+    if (!(share->database= strchr(share->hostname, '/')))
+      goto error;
+    share->hostname[share->database - share->hostname]= '\0';
+    share->database++;
 
-  if (share->hostname[0] == '\0')
-    share->hostname= NULL;
+    if ((share->sport= strchr(share->hostname, ':')))
+    {
+      share->hostname[share->sport - share->hostname]= '\0';
+      share->sport++;
+      if (share->sport[0] == '\0')
+        share->sport= NULL;
+      else
+        share->port= atoi(share->sport);
+    }
 
+    if (!(share->table_name= strchr(share->database, '/')))
+      goto error;
+    share->database[share->table_name - share->database]= '\0';
+    share->table_name++;
+
+    share->table_name_length= strlen(share->table_name);
+
+    /* make sure there's not an extra / */
+    if ((strchr(share->table_name, '/')))
+      goto error;
+
+    if (share->hostname[0] == '\0')
+      share->hostname= NULL;
+
+  }
   if (!share->port)
   {
     if (strcmp(share->hostname, my_localhost) == 0)
@@ -741,7 +861,7 @@
 
   DBUG_PRINT("info",
              ("scheme: %s  username: %s  password: %s \
-               hostname: %s  port: %d  database: %s  tablename: %s",
+               hostname: %s  port: %d  db: %s  tablename: %s",
               share->scheme, share->username, share->password,
               share->hostname, share->port, share->database,
               share->table_name));
@@ -752,7 +872,6 @@
   DBUG_RETURN(parse_url_error(share, table, error_num));
 }
 
-
 /*****************************************************************************
 ** FEDERATED tables
 *****************************************************************************/
@@ -1410,14 +1529,13 @@
   if (!--share->use_count)
   {
     hash_delete(&federated_open_tables, (byte*) share);
-    my_free((gptr) share->scheme, MYF(MY_ALLOW_ZERO_PTR));
-    share->scheme= 0;
+    my_free((gptr) share->connection_string, MYF(MY_ALLOW_ZERO_PTR));
+    share->connection_string= 0;
     if (share->socket)
     {
       my_free((gptr) share->socket, MYF(MY_ALLOW_ZERO_PTR));
       share->socket= 0;
     }
-
     thr_lock_delete(&share->lock);
     VOID(pthread_mutex_destroy(&share->mutex));
     my_free((gptr) share, MYF(0));
@@ -2623,7 +2741,7 @@
   if (!(retval= parse_url(&tmp_share, table_arg, 1)))
     retval= check_foreign_data_source(&tmp_share, 1);
 
-  my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR));
+  my_free((gptr) tmp_share.connection_string, MYF(MY_ALLOW_ZERO_PTR));
   DBUG_RETURN(retval);
 
 }

--- 1.27/sql/ha_federated.h	2006-02-09 18:28:58 -08:00
+++ 1.28/sql/ha_federated.h	2006-04-08 14:08:50 -07:00
@@ -155,7 +155,6 @@
   FEDERATED_SHARE *share;    /* Shared lock info */
   MYSQL *mysql; /* MySQL connection */
   MYSQL_RES *stored_result;
-  bool scan_flag;
   uint ref_length;
   uint fetch_num; // stores the fetch num
   MYSQL_ROW_OFFSET current_position;  // Current position used by ::position()
@@ -288,6 +287,7 @@
   void position(const byte *record);                            //required
   void info(uint);                                              //required
 
+  void update_auto_increment(void);
   int repair(THD* thd, HA_CHECK_OPT* check_opt);
   int optimize(THD* thd, HA_CHECK_OPT* check_opt);
 

--- 1.39/scripts/mysql_create_system_tables.sh	2006-03-24 08:45:44 -08:00
+++ 1.40/scripts/mysql_create_system_tables.sh	2006-04-08 14:08:50 -07:00
@@ -192,6 +192,28 @@
   fi 
 fi
 
+# Check for old tables
+if test ! -f $mdata/servers.frm
+then
+  if test "$1" = "verbose" ; then
+    echo "Preparing servers table" 1>&2; 
+  fi
+
+  c_d="$c_d CREATE TABLE  servers ("
+  c_d="$c_d   Server_name char(64) NOT NULL,"
+  c_d="$c_d   Hostname char(64) NOT NULL,"
+  c_d="$c_d   Db char(64) NOT NULL,"
+  c_d="$c_d   Username char(64) NOT NULL,"
+  c_d="$c_d   Passwd char(64) NOT NULL,"
+  c_d="$c_d   Portnum INT(4),"
+  c_d="$c_d   Sock char(64),"
+  c_d="$c_d   Scheme char(64) NOT NULL,"
+  c_d="$c_d   Owner_name char(64) NOT NULL,"
+  c_d="$c_d   PRIMARY KEY  (Server_name));"
+
+  i_d="INSERT INTO servers VALUES ('test','localhost','test','root','', 0, '','mysql','root');"
+fi
+
 if test ! -f $mdata/func.frm
 then
   if test "$1" = "verbose" ; then
Thread
bk commit into 5.1 tree (patg:1.2301)Patrick Galbraith8 Apr