MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:November 20 2009 12:52pm
Subject:bzr push into mysql-5.6-next-mr branch (kostja:2922 to 2923)
View as plain text  
 2923 Davi Arnaut	2009-11-19 [merge]
      Manual merge of mysql-next-mr-runtime upstream.

    added:
      mysql-test/r/partition_sync.result
      mysql-test/r/rpl_mysqldump_slave.result
      mysql-test/t/partition_sync.test
      mysql-test/t/rpl_mysqldump_slave.test
    modified:
      client/client_priv.h
      client/mysql.cc
      client/mysqladmin.cc
      client/mysqlcheck.c
      client/mysqldump.c
      client/mysqltest.cc
      client/sql_string.cc
      client/sql_string.h
      config/ac-macros/misc.m4
      include/m_string.h
      include/mysql_com.h
      include/violite.h
      libmysql/libmysql.c
      libmysqld/lib_sql.cc
      mysql-test/r/alias.result
      mysql-test/r/delete.result
      mysql-test/r/derived.result
      mysql-test/r/dirty_close.result
      mysql-test/r/func_sapdb.result
      mysql-test/r/func_time.result
      mysql-test/r/mysql.result
      mysql-test/r/sp-error.result
      mysql-test/r/sp.result
      mysql-test/r/trigger.result
      mysql-test/r/type_time.result
      mysql-test/suite/rpl/r/rpl_multi_delete2.result
      mysql-test/suite/rpl/t/rpl_multi_delete2.test
      mysql-test/suite/sys_vars/r/group_concat_max_len_func.result
      mysql-test/t/alias.test
      mysql-test/t/delete.test
      mysql-test/t/derived.test
      mysql-test/t/dirty_close.test
      mysql-test/t/func_sapdb.test
      mysql-test/t/func_time.test
      mysql-test/t/lock_multi.test
      mysql-test/t/mysql.test
      mysql-test/t/shm.test
      mysql-test/t/sp-error.test
      mysql-test/t/sp.test
      mysql-test/t/trigger.test
      mysql-test/t/type_time.test
      mysys/my_alloc.c
      mysys/my_getopt.c
      sql/event_data_objects.cc
      sql/field.cc
      sql/field.h
      sql/ha_partition.cc
      sql/item_cmpfunc.cc
      sql/item_func.cc
      sql/item_subselect.cc
      sql/item_timefunc.cc
      sql/mysql_priv.h
      sql/opt_sum.cc
      sql/share/errmsg.txt
      sql/sp.cc
      sql/sp_head.cc
      sql/sql_cache.cc
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_list.h
      sql/sql_parse.cc
      sql/sql_partition.cc
      sql/sql_select.cc
      sql/sql_servers.cc
      sql/sql_show.cc
      sql/sql_string.cc
      sql/sql_string.h
      sql/sql_trigger.cc
      sql/sql_update.cc
      sql/sql_yacc.yy
      sql/table.h
      sql/tztime.cc
      storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
      strings/ctype-bin.c
      strings/ctype-latin1.c
      strings/ctype-mb.c
      strings/ctype-simple.c
      vio/vio.c
      vio/vio_priv.h
      vio/viosocket.c
 2922 Alexander Nozdrin	2009-11-12
      Update version tag (new: 5.6).

    modified:
      .bzr-mysql/default.conf
      configure.in
=== modified file 'client/client_priv.h'
--- a/client/client_priv.h	2009-10-15 12:23:43 +0000
+++ b/client/client_priv.h	2009-11-04 13:31:03 +0000
@@ -62,6 +62,9 @@ enum options_client
   OPT_MYSQL_NUMBER_OF_QUERY,
   OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
   OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
+  OPT_MYSQLDUMP_SLAVE_APPLY,
+  OPT_MYSQLDUMP_SLAVE_DATA,
+  OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
   OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING,
   OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
   OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
@@ -78,6 +81,7 @@ enum options_client
   OPT_SLAP_DETACH,
   OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID,
   OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
+  OPT_AUTO_VERTICAL_OUTPUT,
   OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
   OPT_WRITE_BINLOG, OPT_DUMP_DATE,
   OPT_INIT_COMMAND,

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2009-11-06 14:20:27 +0000
+++ b/client/mysql.cc	2009-11-19 23:48:08 +0000
@@ -143,6 +143,7 @@ static my_bool ignore_errors=0,wait_flag
 	       tty_password= 0, opt_nobeep=0, opt_reconnect=1,
 	       opt_secure_auth= 0,
                default_pager_set= 0, opt_sigint_ignore= 0,
+               auto_vertical_output= 0,
                show_warnings= 0, executing_query= 0, interrupted_query= 0,
                ignore_spaces= 0;
 static my_bool debug_info_flag, debug_check_flag;
@@ -185,6 +186,7 @@ static MEM_ROOT hash_mem_root;
 static uint prompt_counter;
 static char delimiter[16]= DEFAULT_DELIMITER;
 static uint delimiter_length= 1;
+unsigned short terminal_width= 80;
 
 #ifdef HAVE_SMEM
 static char *shared_memory_base_name=0;
@@ -238,6 +240,8 @@ static const char* construct_prompt();
 static char *get_arg(char *line, my_bool get_next_arg);
 static void init_username();
 static void add_int_to_prompt(int toadd);
+static int get_result_width(MYSQL_RES *res);
+static int get_field_disp_length(MYSQL_FIELD * field);
 
 /* A structure which contains information on the commands this program
    can understand. */
@@ -1065,6 +1069,10 @@ static void mysql_end_timer(ulong start_
 static void nice_time(double sec,char *buff,bool part_second);
 extern "C" sig_handler mysql_end(int sig);
 extern "C" sig_handler handle_sigint(int sig);
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+static sig_handler window_resize(int sig);
+#endif
+
 
 int main(int argc,char *argv[])
 {
@@ -1144,8 +1152,8 @@ int main(int argc,char *argv[])
   if (sql_connect(current_host,current_db,current_user,opt_password,
 		  opt_silent))
   {
-    quick=1;					// Avoid history
-    status.exit_status=1;
+    quick= 1;					// Avoid history
+    status.exit_status= 1;
     mysql_end(-1);
   }
   if (!status.batch)
@@ -1157,6 +1165,13 @@ int main(int argc,char *argv[])
     signal(SIGINT, handle_sigint);              // Catch SIGINT to clean up
   signal(SIGQUIT, mysql_end);			// Catch SIGQUIT to clean up
 
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+  /* Readline will call this if it installs a handler */
+  signal(SIGWINCH, window_resize);
+  /* call the SIGWINCH handler to get the default term width */
+  window_resize(0);
+#endif
+
   put_info("Welcome to the MySQL monitor.  Commands end with ; or \\g.",
 	   INFO_INFO);
   sprintf((char*) glob_buffer.ptr(),
@@ -1329,6 +1344,16 @@ err:
 }
 
 
+#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
+sig_handler window_resize(int sig)
+{
+  struct winsize window_size;
+
+  if (ioctl(fileno(stdin), TIOCGWINSZ, &window_size) == 0)
+    terminal_width= window_size.ws_col;
+}
+#endif
+
 static struct my_option my_long_options[] =
 {
   {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
@@ -1346,6 +1371,9 @@ static struct my_option my_long_options[
   {"no-auto-rehash", 'A',
    "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+   {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
+    "Automatically switch to vertical output mode if the result is wider than the terminal width.",
+    (uchar**) &auto_vertical_output, (uchar**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"batch", 'B',
    "Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"character-sets-dir", OPT_CHARSETS_DIR,
@@ -3052,7 +3080,7 @@ com_go(String *buffer,char *line __attri
 	  print_table_data_html(result);
 	else if (opt_xml)
 	  print_table_data_xml(result);
-	else if (vertical)
+  else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
 	  print_table_data_vertically(result);
 	else if (opt_silent && verbose <= 2 && !output_tables)
 	  print_tab_data(result);
@@ -3383,6 +3411,65 @@ print_table_data(MYSQL_RES *result)
   my_afree((uchar*) num_flag);
 }
 
+/**
+  Return the length of a field after it would be rendered into text.
+
+  This doesn't know or care about multibyte characters.  Assume we're
+  using such a charset.  We can't know that all of the upcoming rows 
+  for this column will have bytes that each render into some fraction
+  of a character.  It's at least possible that a row has bytes that 
+  all render into one character each, and so the maximum length is 
+  still the number of bytes.  (Assumption 1:  This can't be better 
+  because we can never know the number of characters that the DB is 
+  going to send -- only the number of bytes.  2: Chars <= Bytes.)
+
+  @param  field  Pointer to a field to be inspected
+
+  @returns  number of character positions to be used, at most
+*/
+static int get_field_disp_length(MYSQL_FIELD *field)
+{
+  uint length= column_names ? field->name_length : 0;
+
+  if (quick)
+    length= max(length, field->length);
+  else
+    length= max(length, field->max_length);
+
+  if (length < 4 && !IS_NOT_NULL(field->flags))
+    length= 4;				/* Room for "NULL" */
+
+  return length;
+}
+
+/**
+  For a new result, return the max number of characters that any
+  upcoming row may return.
+
+  @param  result  Pointer to the result to judge
+
+  @returns  The max number of characters in any row of this result
+*/
+static int get_result_width(MYSQL_RES *result)
+{
+  unsigned int len= 0;
+  MYSQL_FIELD *field;
+  MYSQL_FIELD_OFFSET offset;
+  
+#ifndef DBUG_OFF
+  offset= mysql_field_tell(result);
+  DBUG_ASSERT(offset == 0);
+#else
+  offset= 0;
+#endif
+
+  while ((field= mysql_fetch_field(result)) != NULL)
+    len+= get_field_disp_length(field) + 3; /* plus bar, space, & final space */
+
+  (void) mysql_field_seek(result, offset);	
+
+  return len + 1; /* plus final bar. */
+}
 
 static void
 tee_print_sized_data(const char *data, unsigned int data_length, unsigned int total_bytes_to_send, bool right_justified)

=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc	2009-10-21 12:59:47 +0000
+++ b/client/mysqladmin.cc	2009-11-11 16:22:27 +0000
@@ -900,23 +900,38 @@ static int execute_commands(MYSQL *mysql
     {
       char buff[128],crypted_pw[64];
       time_t start_time;
+      char *typed_password= NULL, *verified= NULL;
       /* Do initialization the same way as we do in mysqld */
       start_time=time((time_t*) 0);
       randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
 
-      if (argc < 2)
+      if (argc < 1)
       {
 	my_printf_error(0, "Too few arguments to change password", error_flags);
 	return 1;
       }
-      if (argv[1][0])
+      else if (argc == 1)
+      {
+        /* prompt for password */
+        typed_password= get_tty_password("New password: ");
+        verified= get_tty_password("Confirm new password: ");
+        if (strcmp(typed_password, verified) != 0)
+        {
+          my_printf_error(0,"Passwords don't match",MYF(ME_BELL));
+          return -1;
+        }
+      }
+      else
+        typed_password= argv[1];
+
+      if (typed_password[0])
       {
-        char *pw= argv[1];
         bool old= (find_type(argv[0], &command_typelib, 2) ==
                    ADMIN_OLD_PASSWORD);
 #ifdef __WIN__
-        uint pw_len= (uint) strlen(pw);
-        if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
+        size_t pw_len= strlen(typed_password);
+        if (pw_len > 1 && typed_password[0] == '\'' &&
+            typed_password[pw_len-1] == '\'')
           printf("Warning: single quotes were not trimmed from the password by"
                  " your command\nline client, as you might have expected.\n");
 #endif
@@ -954,9 +969,9 @@ static int execute_commands(MYSQL *mysql
           }
         }
         if (old)
-          make_scrambled_password_323(crypted_pw, pw);
+          make_scrambled_password_323(crypted_pw, typed_password);
         else
-          make_scrambled_password(crypted_pw, pw);
+          make_scrambled_password(crypted_pw, typed_password);
       }
       else
 	crypted_pw[0]=0;			/* No password */
@@ -991,6 +1006,12 @@ static int execute_commands(MYSQL *mysql
 	  return -1;
 	}
       }
+      /* free up memory from prompted password */
+      if (typed_password != argv[1]) 
+      {
+        my_free(typed_password,MYF(MY_ALLOW_ZERO_PTR));
+        my_free(verified,MYF(MY_ALLOW_ZERO_PTR));
+      }
       argc--; argv++;
       break;
     }
@@ -1082,8 +1103,8 @@ static void usage(void)
   kill id,id,...	Kill mysql threads");
 #if MYSQL_VERSION_ID >= 32200
   puts("\
-  password new-password Change old password to new-password, MySQL 4.1 hashing.\n\
-  old-password new-password Change old password to new-password in old format.\n");
+  password [new-password] Change old password to new-password in current format\n\
+  old-password [new-password] Change old password to new-password in old format");
 #endif
   puts("\
   ping			Check if mysqld is alive\n\

=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c	2009-10-22 20:20:44 +0000
+++ b/client/mysqlcheck.c	2009-11-03 09:22:22 +0000
@@ -128,7 +128,7 @@ static struct my_option my_long_options[
    "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"write-binlog", OPT_WRITE_BINLOG,
-   "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Enabled by default; use --skip-write-binlog when commands should not be sent to replication slaves.",
+   "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.",
    (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
    1, 0, 0, 0, 0, 0},
   {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,

=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2009-10-14 16:37:38 +0000
+++ b/client/mysqldump.c	2009-11-04 13:31:03 +0000
@@ -98,6 +98,8 @@ static my_bool  verbose= 0, opt_no_creat
                 opt_complete_insert= 0, opt_drop_database= 0,
                 opt_replace_into= 0,
                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+                opt_slave_apply= 0, 
+                opt_include_master_host_port= 0,
                 opt_events= 0,
                 opt_alltspcs=0, opt_notspcs= 0;
 static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
@@ -118,7 +120,10 @@ static my_bool server_supports_switching
 static ulong opt_compatible_mode= 0;
 #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
+#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
+#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
 static uint opt_mysql_port= 0, opt_master_data;
+static uint opt_slave_data;
 static uint my_end_arg;
 static char * opt_mysql_unix_port=0;
 static int   first_error=0;
@@ -206,6 +211,10 @@ static struct my_option my_long_options[
   {"allow-keywords", OPT_KEYWORDS,
    "Allow creation of column names that are keywords.", (uchar**) &opt_keywords,
    (uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
+   "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
+   (uchar**) &opt_slave_apply, (uchar**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
+   0, 0, 0, 0, 0, 0},
 #ifdef __NETWARE__
   {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -264,6 +273,19 @@ static struct my_option my_long_options[
   {"disable-keys", 'K',
    "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys,
    (uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+  {"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
+   "This causes the binary log position and filename of the master to be "
+   "appended to the dumped data output. Setting the value to 1, will print"
+   "it as a CHANGE MASTER command in the dumped data output; if equal"
+   " to 2, that command will be prefixed with a comment symbol. "
+   "This option will turn --lock-all-tables on, unless "
+   "--single-transaction is specified too (in which case a "
+   "global read lock is only taken a short time at the beginning of the dump "
+   "- don't forget to read about --single-transaction below). In all cases "
+   "any action on logs will happen at the exact moment of the dump."
+   "Option automatically turns --lock-tables off.",
+   (uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0,
+   GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
   {"events", 'E', "Dump events.",
      (uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
      NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -317,6 +339,12 @@ static struct my_option my_long_options[
    "use the directive multiple times, once for each table.  Each table must "
    "be specified with both database and table names, e.g. --ignore-table=database.table",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
+   "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
+   (uchar**) &opt_include_master_host_port, 
+   (uchar**) &opt_include_master_host_port, 
+   0, GET_BOOL, NO_ARG,
+   0, 0, 0, 0, 0, 0},
   {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
    (uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
    0, 0},
@@ -402,7 +430,7 @@ static struct my_option my_long_options[
      (uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL,
      NO_ARG, 0, 0, 0, 0, 0, 0},
   {"set-charset", OPT_SET_CHARSET,
-   "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
+   "Add 'SET NAMES default_character_set' to the output.",
    (uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
    0, 0, 0, 0, 0},
   {"set-variable", 'O',
@@ -764,6 +792,10 @@ get_one_option(int optid, const struct m
     if (!argument) /* work like in old versions */
       opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
     break;
+  case (int) OPT_MYSQLDUMP_SLAVE_DATA:
+    if (!argument) /* work like in old versions */
+      opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
+    break;
   case (int) OPT_OPTIMIZE:
     extended_insert= opt_drop= opt_lock= quick= create_options=
       opt_disable_keys= lock_tables= opt_set_charset= 1;
@@ -896,6 +928,14 @@ static int get_options(int *argc, char *
     return(EX_USAGE);
   }
 
+  /* We don't delete master logs if slave data option */
+  if (opt_slave_data)
+  {
+    opt_lock_all_tables= !opt_single_transaction;
+    opt_master_data= 0;
+    opt_delete_master_logs= 0;
+  }
+
   /* Ensure consistency of the set of binlog & locking options */
   if (opt_delete_master_logs && !opt_master_data)
     opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
@@ -906,7 +946,10 @@ static int get_options(int *argc, char *
     return(EX_USAGE);
   }
   if (opt_master_data)
+  {
     opt_lock_all_tables= !opt_single_transaction;
+    opt_slave_data= 0;
+  }
   if (opt_single_transaction || opt_lock_all_tables)
     lock_tables= 0;
   if (enclosed && opt_enclosed)
@@ -4333,6 +4376,130 @@ static int do_show_master_status(MYSQL *
   return 0;
 }
 
+static int do_stop_slave_sql(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  /* We need to check if the slave sql is running in the first place */
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+    return(1);
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[11])
+    {
+      /* if SLAVE SQL is not running, we don't stop it */
+      if (!strcmp(row[11],"No"))
+      {
+        mysql_free_result(slave);
+        /* Silently assume that they don't have the slave running */
+        return(0);
+      }
+    }
+  }
+  mysql_free_result(slave);
+
+  /* now, stop slave if running */
+  if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
+    return(1);
+
+  return(0);
+}
+
+static int add_stop_slave(void)
+{
+  if (opt_comments)
+    fprintf(md_result_file,
+            "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
+  fprintf(md_result_file, "STOP SLAVE;\n");
+  return(0);
+}
+
+static int add_slave_statements(void)
+{
+  if (opt_comments)
+    fprintf(md_result_file,
+            "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
+  fprintf(md_result_file, "START SLAVE;\n");
+  return(0);
+}
+
+static int do_show_slave_status(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  const char *comment_prefix=
+    (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+  {
+    if (!ignore_errors)
+    {
+      /* SHOW SLAVE STATUS reports nothing and --force is not enabled */
+      my_printf_error(0, "Error: Slave not set up", MYF(0));
+    }
+    mysql_free_result(slave);
+    return 1;
+  }
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[9] && row[21])
+    {
+      /* SHOW MASTER STATUS reports file and position */
+      if (opt_comments)
+        fprintf(md_result_file,
+                "\n--\n-- Position to start replication or point-in-time "
+                "recovery from (the master of this slave)\n--\n\n");
+
+      fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
+
+      if (opt_include_master_host_port)
+      {
+        if (row[1])
+          fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
+        if (row[3])
+          fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
+      }
+      fprintf(md_result_file,
+              "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
+
+      check_io(md_result_file);
+    }
+    mysql_free_result(slave);
+  }
+  return 0;
+}
+
+static int do_start_slave_sql(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  /* We need to check if the slave sql is stopped in the first place */
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+    return(1);
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[11])
+    {
+      /* if SLAVE SQL is not running, we don't start it */
+      if (!strcmp(row[11],"Yes"))
+      {
+        mysql_free_result(slave);
+        /* Silently assume that they don't have the slave running */
+        return(0);
+      }
+    }
+  }
+  mysql_free_result(slave);
+
+  /* now, start slave if stopped */
+  if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
+  {
+    my_printf_error(0, "Error: Unable to start slave", MYF(0));
+    return 1;
+  }
+  return(0);
+}
+
+
 
 static int do_flush_tables_read_lock(MYSQL *mysql_con)
 {
@@ -4995,6 +5162,9 @@ int main(int argc, char **argv)
   if (!path)
     write_header(md_result_file, *argv);
 
+  if (opt_slave_data && do_stop_slave_sql(mysql))
+    goto err;
+
   if ((opt_lock_all_tables || opt_master_data) &&
       do_flush_tables_read_lock(mysql))
     goto err;
@@ -5013,8 +5183,13 @@ int main(int argc, char **argv)
       goto err;
     flush_logs= 0; /* not anymore; that would not be sensible */
   }
+  /* Add 'STOP SLAVE to beginning of dump */
+  if (opt_slave_apply && add_stop_slave())
+    goto err;
   if (opt_master_data && do_show_master_status(mysql))
     goto err;
+  if (opt_slave_data && do_show_slave_status(mysql))
+    goto err;
   if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
     goto err;
 
@@ -5042,6 +5217,14 @@ int main(int argc, char **argv)
     dump_databases(argv);
   }
 
+  /* if --dump-slave , start the slave sql thread */
+  if (opt_slave_data && do_start_slave_sql(mysql))
+    goto err;
+
+  /* add 'START SLAVE' to end of dump */
+  if (opt_slave_apply && add_slave_statements())
+    goto err;
+
   /* ensure dumped data flushed */
   if (md_result_file && fflush(md_result_file))
   {

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2009-11-12 15:00:24 +0000
+++ b/client/mysqltest.cc	2009-11-19 23:48:08 +0000
@@ -75,7 +75,8 @@
 enum {
   OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
   OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
-  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
+  OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
+  OPT_RESULT_FORMAT_VERSION
 };
 
 static int record= 0, opt_sleep= -1;
@@ -88,6 +89,7 @@ const char *opt_logdir= "";
 const char *opt_include= 0, *opt_charsets_dir;
 static int opt_port= 0;
 static int opt_max_connect_retries;
+static int opt_result_format_version;
 static my_bool opt_compress= 0, silent= 0, verbose= 0;
 static my_bool debug_info_flag= 0, debug_check_flag= 0;
 static my_bool tty_password= 0;
@@ -284,11 +286,12 @@ enum enum_commands {
   Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
   Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
   Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER,
+  Q_RESULT_FORMAT_VERSION,
   Q_MOVE_FILE, Q_SEND_EVAL,
-
   Q_UNKNOWN,			       /* Unknown command.   */
   Q_COMMENT,			       /* Comments, ignored. */
-  Q_COMMENT_WITH_COMMAND
+  Q_COMMENT_WITH_COMMAND,
+  Q_EMPTY_LINE
 };
 
 
@@ -378,6 +381,7 @@ const char *command_names[]=
   "list_files_append_file",
   "send_shutdown",
   "shutdown_server",
+  "result_format",
   "move_file",
   "send_eval",
 
@@ -2193,6 +2197,59 @@ void var_query_set(VAR *var, const char 
 }
 
 
+static void
+set_result_format_version(ulong new_version)
+{
+  switch (new_version){
+  case 1:
+    /* The first format */
+    break;
+  case 2:
+    /* New format that also writes comments and empty lines
+       from test file to result */
+    break;
+  default:
+    die("Version format %lu has not yet been implemented", new_version);
+    break;
+  }
+  opt_result_format_version= new_version;
+}
+
+
+/*
+  Set the result format version to use when generating
+  the .result file
+*/
+
+static void
+do_result_format_version(struct st_command *command)
+{
+  long version;
+  static DYNAMIC_STRING ds_version;
+  const struct command_arg result_format_args[] = {
+    "version", ARG_STRING, TRUE, &ds_version, "Version to use",
+  };
+
+  DBUG_ENTER("do_result_format_version");
+
+  check_command_args(command, command->first_argument,
+                     result_format_args,
+                     sizeof(result_format_args)/sizeof(struct command_arg),
+                     ',');
+
+  /* Convert version  number to int */
+  if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version))
+    die("Invalid version number: '%s'", ds_version.str);
+
+  set_result_format_version(version);
+
+  dynstr_append(&ds_res, "result_format: ");
+  dynstr_append_mem(&ds_res, ds_version.str, ds_version.length);
+  dynstr_append(&ds_res, "\n");
+  dynstr_free(&ds_version);
+}
+
+
 /*
   Set variable from the result of a field in a query
 
@@ -5273,7 +5330,7 @@ my_bool end_of_query(int c)
 
 int read_line(char *buf, int size)
 {
-  char c, UNINIT_VAR(last_quote);
+  char c, UNINIT_VAR(last_quote), last_char= 0;
   char *p= buf, *buf_end= buf + size - 1;
   int skip_char= 0;
   enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
@@ -5371,14 +5428,24 @@ int read_line(char *buf, int size)
       }
       else if (my_isspace(charset_info, c))
       {
-        /* Skip all space at begining of line */
 	if (c == '\n')
         {
+          if (last_char == '\n')
+          {
+            /* Two new lines in a row, return empty line */
+            DBUG_PRINT("info", ("Found two new lines in a row"));
+            *p++= c;
+            *p= 0;
+            DBUG_RETURN(0);
+          }
+
           /* Query hasn't started yet */
 	  start_lineno= cur_file->lineno;
           DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
                               start_lineno));
         }
+
+        /* Skip all space at begining of line */
 	skip_char= 1;
       }
       else if (end_of_query(c))
@@ -5419,6 +5486,8 @@ int read_line(char *buf, int size)
 
     }
 
+    last_char= c;
+
     if (!skip_char)
     {
       /* Could be a multibyte character */
@@ -5628,9 +5697,10 @@ int read_command(struct st_command** com
     DBUG_RETURN(1);
   }
 
-  convert_to_format_v1(read_command_buf);
+  if (opt_result_format_version == 1)
+    convert_to_format_v1(read_command_buf);
 
-  DBUG_PRINT("info", ("query: %s", read_command_buf));
+  DBUG_PRINT("info", ("query: '%s'", read_command_buf));
   if (*p == '#')
   {
     command->type= Q_COMMENT;
@@ -5640,6 +5710,10 @@ int read_command(struct st_command** com
     command->type= Q_COMMENT_WITH_COMMAND;
     p+= 2; /* Skip past -- */
   }
+  else if (*p == '\n')
+  {
+    command->type= Q_EMPTY_LINE;
+  }
 
   /* Skip leading spaces */
   while (*p && my_isspace(charset_info, *p))
@@ -5734,6 +5808,11 @@ static struct my_option my_long_options[
   {"result-file", 'R', "Read/Store result from/in this file.",
    (uchar**) &result_file_name, (uchar**) &result_file_name, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"result-format-version", OPT_RESULT_FORMAT_VERSION,
+   "Version of the result file format to use",
+   (uchar**) &opt_result_format_version,
+   (uchar**) &opt_result_format_version, 0,
+   GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0},
   {"server-arg", 'A', "Send option value to embedded server as a parameter.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"server-file", 'F', "Read embedded server arguments from file.",
@@ -5943,6 +6022,9 @@ get_one_option(int optid, const struct m
     sf_malloc_quick=1;
 #endif
     break;
+  case OPT_RESULT_FORMAT_VERSION:
+    set_result_format_version(opt_result_format_version);
+    break;
   case 'V':
     print_version();
     exit(0);
@@ -7816,6 +7898,7 @@ int main(int argc, char **argv)
       case Q_MOVE_FILE: do_move_file(command); break;
       case Q_CHMOD_FILE: do_chmod_file(command); break;
       case Q_PERL: do_perl(command); break;
+      case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
       case Q_DELIMITER:
         do_delimiter(command);
 	break;
@@ -7933,9 +8016,38 @@ int main(int argc, char **argv)
 	do_sync_with_master2(command, 0);
 	break;
       }
-      case Q_COMMENT:				/* Ignore row */
+      case Q_COMMENT:
+      {
         command->last_argument= command->end;
+
+        /* Don't output comments in v1 */
+        if (opt_result_format_version == 1)
+          break;
+
+        /* Don't output comments if query logging is off */
+        if (disable_query_log)
+          break;
+
+        /* Write comment's with two starting #'s to result file */
+        const char* p= command->query;
+        if (p && *p == '#' && *(p+1) == '#')
+        {
+          dynstr_append_mem(&ds_res, command->query, command->query_len);
+          dynstr_append(&ds_res, "\n");
+        }
 	break;
+      }
+      case Q_EMPTY_LINE:
+        /* Don't output newline in v1 */
+        if (opt_result_format_version == 1)
+          break;
+
+        /* Don't output newline if query logging is off */
+        if (disable_query_log)
+          break;
+
+        dynstr_append(&ds_res, "\n");
+        break;
       case Q_PING:
         handle_command_error(command, mysql_ping(&cur_con->mysql));
         break;

=== modified file 'client/sql_string.cc'
--- a/client/sql_string.cc	2009-03-24 13:58:52 +0000
+++ b/client/sql_string.cc	2009-11-11 20:19:41 +0000
@@ -23,6 +23,7 @@
 #include <my_sys.h>
 #include <m_string.h>
 #include <m_ctype.h>
+#include <mysql_com.h>
 #ifdef HAVE_FCONVERT
 #include <floatingpoint.h>
 #endif

=== modified file 'client/sql_string.h'
--- a/client/sql_string.h	2009-09-23 21:32:31 +0000
+++ b/client/sql_string.h	2009-11-11 20:19:41 +0000
@@ -22,10 +22,6 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
-#ifndef NOT_FIXED_DEC
-#define NOT_FIXED_DEC			31
-#endif
-
 class String;
 int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);

=== modified file 'config/ac-macros/misc.m4'
--- a/config/ac-macros/misc.m4	2009-07-30 15:24:09 +0000
+++ b/config/ac-macros/misc.m4	2009-11-11 20:43:31 +0000
@@ -601,15 +601,15 @@ dnl ------------------------------------
 
 dnl MYSQL_NEEDS_MYSYS_NEW
 AC_DEFUN([MYSQL_NEEDS_MYSYS_NEW],
-[AC_CACHE_CHECK([needs mysys_new helpers], mysql_use_mysys_new,
+[AC_CACHE_CHECK([needs mysys_new helpers], mysql_cv_use_mysys_new,
 [
 AC_LANG_PUSH(C++)
 AC_TRY_LINK([], [
 class A { public: int b; }; A *a=new A; a->b=10; delete a;
-], mysql_use_mysys_new=no, mysql_use_mysys_new=yes)
+], mysql_cv_use_mysys_new=no, mysql_cv_use_mysys_new=yes)
 AC_LANG_POP(C++)
 ])
-if test "$mysql_use_mysys_new" = "yes"
+if test "$mysql_cv_use_mysys_new" = "yes"
 then
   AC_DEFINE([USE_MYSYS_NEW], [1], [Needs to use mysys_new helpers])
 fi

=== modified file 'include/m_string.h'
--- a/include/m_string.h	2009-11-02 20:05:42 +0000
+++ b/include/m_string.h	2009-11-19 23:48:08 +0000
@@ -260,4 +260,73 @@ typedef struct st_mysql_lex_string LEX_S
 #define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
 #define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
 
+/* SPACE_INT is a word that contains only spaces */
+#if SIZEOF_INT == 4
+#define SPACE_INT 0x20202020
+#elif SIZEOF_INT == 8
+#define SPACE_INT 0x2020202020202020
+#else
+#error define the appropriate constant for a word full of spaces
+#endif
+
+/**
+  Skip trailing space.
+
+  On most systems reading memory in larger chunks (ideally equal to the size of
+  the chinks that the machine physically reads from memory) causes fewer memory
+  access loops and hence increased performance.
+  This is why the 'int' type is used : it's closest to that (according to how
+  it's defined in C).
+  So when we determine the amount of whitespace at the end of a string we do
+  the following :
+    1. We divide the string into 3 zones :
+      a) from the start of the string (__start) to the first multiple
+        of sizeof(int)  (__start_words)
+      b) from the end of the string (__end) to the last multiple of sizeof(int)
+        (__end_words)
+      c) a zone that is aligned to sizeof(int) and can be safely accessed
+        through an int *
+    2. We start comparing backwards from (c) char-by-char. If all we find is
+       space then we continue
+    3. If there are elements in zone (b) we compare them as unsigned ints to a
+       int mask (SPACE_INT) consisting of all spaces
+    4. Finally we compare the remaining part (a) of the string char by char.
+       This covers for the last non-space unsigned int from 3. (if any)
+
+   This algorithm works well for relatively larger strings, but it will slow
+   the things down for smaller strings (because of the additional calculations
+   and checks compared to the naive method). Thus the barrier of length 20
+   is added.
+
+   @param     ptr   pointer to the input string
+   @param     len   the length of the string
+   @return          the last non-space character
+*/
+
+static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
+{
+  const uchar *end= ptr + len;
+
+  if (len > 20)
+  {
+    const uchar *end_words= (const uchar *)(intptr)
+      (((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
+    const uchar *start_words= (const uchar *)(intptr)
+       ((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
+
+    DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
+    if (end_words > ptr)
+    {
+      while (end > end_words && end[-1] == 0x20)
+        end--;
+      if (end[-1] == 0x20 && start_words < end_words)
+        while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
+          end -= SIZEOF_INT;
+    }
+  }
+  while (end > ptr && end[-1] == 0x20)
+    end--;
+  return (end);
+}
+
 #endif

=== modified file 'include/mysql_com.h'
--- a/include/mysql_com.h	2009-11-02 11:10:04 +0000
+++ b/include/mysql_com.h	2009-11-11 20:19:41 +0000
@@ -524,4 +524,5 @@ uchar *net_store_length(uchar *pkg, ulon
 #define MYSQL_STMT_HEADER       4
 #define MYSQL_LONG_DATA_HEADER  6
 
+#define NOT_FIXED_DEC           31
 #endif

=== modified file 'include/violite.h'
--- a/include/violite.h	2009-11-02 22:19:58 +0000
+++ b/include/violite.h	2009-11-19 23:48:08 +0000
@@ -51,9 +51,6 @@ Vio* vio_new_win32shared_memory(HANDLE h
                                 HANDLE event_client_wrote,
                                 HANDLE event_client_read,
                                 HANDLE event_conn_closed);
-size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
-int vio_close_pipe(Vio * vio);
 #else
 #define HANDLE void *
 #endif /* __WIN__ */
@@ -87,7 +84,8 @@ my_socket vio_fd(Vio*vio);
 my_bool	vio_peer_addr(Vio* vio, char *buf, uint16 *port);
 /* Remotes in_addr */
 void	vio_in_addr(Vio *vio, struct in_addr *in);
-my_bool	vio_poll_read(Vio *vio,uint timeout);
+my_bool vio_poll_read(Vio *vio, uint timeout);
+my_bool vio_is_connected(Vio *vio);
 
 #ifdef HAVE_OPENSSL
 #include <openssl/opensslv.h>
@@ -136,12 +134,6 @@ struct st_VioSSLFd
 void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
 #endif /* HAVE_OPENSSL */
 
-#ifdef HAVE_SMEM
-size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
-int vio_close_shared_memory(Vio * vio);
-#endif
-
 void vio_end(void);
 
 #ifdef	__cplusplus
@@ -164,6 +156,8 @@ void vio_end(void);
 #define vio_peer_addr(vio, buf, prt)		(vio)->peer_addr(vio, buf, prt)
 #define vio_in_addr(vio, in)			(vio)->in_addr(vio, in)
 #define vio_timeout(vio, which, seconds)	(vio)->timeout(vio, which, seconds)
+#define vio_poll_read(vio, timeout)             (vio)->poll_read(vio, timeout)
+#define vio_is_connected(vio)                   (vio)->is_connected(vio)
 #endif /* !defined(DONT_MAP_VIO) */
 
 /* This enumerator is used in parser - should be always visible */
@@ -208,6 +202,8 @@ struct st_vio
   my_bool (*was_interrupted)(Vio*);
   int     (*vioclose)(Vio*);
   void	  (*timeout)(Vio*, unsigned int which, unsigned int timeout);
+  my_bool (*poll_read)(Vio *vio, uint timeout);
+  my_bool (*is_connected)(Vio*);
 #ifdef HAVE_OPENSSL
   void	  *ssl_arg;
 #endif

=== modified file 'libmysql/libmysql.c'
--- a/libmysql/libmysql.c	2009-11-10 07:31:33 +0000
+++ b/libmysql/libmysql.c	2009-11-19 23:48:08 +0000
@@ -3478,10 +3478,7 @@ static void fetch_float_with_conversion(
     */
     char buff[MAX_DOUBLE_STRING_REP_LENGTH];
     char *end;
-    /* TODO: move this to a header shared between client and server. */
-#define NOT_FIXED_DEC  31
     if (field->decimals >= NOT_FIXED_DEC)
-#undef NOT_FIXED_DEC
     {
       /*
         DBL_DIG below is to ensure that the server and client has the same

=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2009-10-23 11:22:21 +0000
+++ b/libmysqld/lib_sql.cc	2009-11-10 14:23:55 +0000
@@ -138,6 +138,7 @@ emb_advanced_command(MYSQL *mysql, enum 
 
   result= dispatch_command(command, thd, (char *) arg, arg_length);
   thd->cur_data= 0;
+  thd->mysys_var= NULL;
 
   if (!skip_check)
     result= thd->is_error() ? -1 : 0;

=== modified file 'mysql-test/r/alias.result'
--- a/mysql-test/r/alias.result	2005-06-27 11:12:10 +0000
+++ b/mysql-test/r/alias.result	2009-11-10 20:43:43 +0000
@@ -73,3 +73,142 @@ UPDATE t1 SET t1.xstatus_vor = Greatest(
 "40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr
 ASC LIMIT 1;
 drop table t1;
+drop table if exists t1,t2,t3;
+create table t1 (a int, b int, c int);
+create table t2 (d int);
+create table t3 (a1 int, b1 int, c1 int);
+insert into t1 values(1,2,3);
+insert into t1 values(11,22,33);
+insert into t2 values(99);
+select t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t2.* as 'with_alias' from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t2' at line 1
+select t1.*, t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t1.* as 'with_alias', t1.* from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', t1.* from t1' at line 1
+select t1.* as 'with_alias', t1.* as 'alias2' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', t1.* as 'alias2' from t1' at line 1
+select t1.* as 'with_alias', a, t1.* as 'alias2' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a, t1.* as 'alias2' from t1' at line 1
+select a, t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t1.* as 'with_alias', a from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a from t1' at line 1
+select a, t1.* as 'with_alias', b from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', b from t1' at line 1
+select (select d from t2 where d > a), t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t1.* as 'with_alias', (select a from t2 where d > a) from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', (select a from t2 where d > a) from t1' at line 1
+select a as 'x', t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t1.* as 'with_alias', a as 'x' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', a as 'x' from t1' at line 1
+select a as 'x', t1.* as 'with_alias', b as 'x' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', b as 'x' from t1' at line 1
+select (select d from t2 where d > a) as 'x', t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+select t1.* as 'with_alias', (select a from t2 where d > a) as 'x' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', (select a from t2 where d > a) as 'x' from t1' at line 1
+select (select t2.* as 'x' from t2) from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
+select a, (select t2.* as 'x' from t2) from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
+select t1.*, (select t2.* as 'x' from t2) from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'x' from t2) from t1' at line 1
+insert into t3 select t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+insert into t3 select t2.* as 'with_alias', 1, 2 from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 1, 2 from t2' at line 1
+insert into t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', d as 'x', d as 'z' from t2' at line 1
+insert into t3 select t2.*, t2.* as 'with_alias', 3 from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 3 from t2' at line 1
+create table t3 select t1.* as 'with_alias' from t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias' from t1' at line 1
+create table t3 select t2.* as 'with_alias', 1, 2 from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 1, 2 from t2' at line 1
+create table t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', d as 'x', d as 'z' from t2' at line 1
+create table t3 select t2.*, t2.* as 'with_alias', 3 from t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as 'with_alias', 3 from t2' at line 1
+select t1.* from t1;
+a	b	c
+1	2	3
+11	22	33
+select t2.* from t2;
+d
+99
+select t1.*, t1.* from t1;
+a	b	c	a	b	c
+1	2	3	1	2	3
+11	22	33	11	22	33
+select t1.*, a, t1.* from t1;
+a	b	c	a	a	b	c
+1	2	3	1	1	2	3
+11	22	33	11	11	22	33
+select a, t1.* from t1;
+a	a	b	c
+1	1	2	3
+11	11	22	33
+select t1.*, a from t1;
+a	b	c	a
+1	2	3	1
+11	22	33	11
+select a, t1.*, b from t1;
+a	a	b	c	b
+1	1	2	3	2
+11	11	22	33	22
+select (select d from t2 where d > a), t1.* from t1;
+(select d from t2 where d > a)	a	b	c
+99	1	2	3
+99	11	22	33
+select t1.*, (select a from t2 where d > a) from t1;
+a	b	c	(select a from t2 where d > a)
+1	2	3	1
+11	22	33	11
+select a as 'x', t1.* from t1;
+x	a	b	c
+1	1	2	3
+11	11	22	33
+select t1.*, a as 'x' from t1;
+a	b	c	x
+1	2	3	1
+11	22	33	11
+select a as 'x', t1.*, b as 'x' from t1;
+x	a	b	c	x
+1	1	2	3	2
+11	11	22	33	22
+select (select d from t2 where d > a) as 'x', t1.* from t1;
+x	a	b	c
+99	1	2	3
+99	11	22	33
+select t1.*, (select a from t2 where d > a) as 'x' from t1;
+a	b	c	x
+1	2	3	1
+11	22	33	11
+select (select t2.* from t2) from t1;
+(select t2.* from t2)
+99
+99
+select a, (select t2.* from t2) from t1;
+a	(select t2.* from t2)
+1	99
+11	99
+select t1.*, (select t2.* from t2) from t1;
+a	b	c	(select t2.* from t2)
+1	2	3	99
+11	22	33	99
+insert into t3 select t1.* from t1;
+insert into t3 select t2.*, 1, 2 from t2;
+insert into t3 select t2.*, d as 'x', d as 'z' from t2;
+insert into t3 select t2.*, t2.*, 3 from t2;
+create table t4 select t1.* from t1;
+drop table t4;
+create table t4 select t2.*, 1, 2 from t2;
+drop table t4;
+create table t4 select t2.*, d as 'x', d as 'z' from t2;
+drop table t4;
+drop table t1,t2,t3;

=== modified file 'mysql-test/r/delete.result'
--- a/mysql-test/r/delete.result	2009-09-28 10:48:52 +0000
+++ b/mysql-test/r/delete.result	2009-11-10 18:48:46 +0000
@@ -259,8 +259,8 @@ ERROR 42S02: Unknown table 't2' in MULTI
 DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a' at line 1
 DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
-ERROR 42S02: Unknown table 'alias' in MULTI DELETE
 DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
+ERROR 42S02: Unknown table 'alias' in MULTI DELETE
 DELETE FROM t1 USING t1 WHERE a = 1;
 SELECT * FROM t1;
 a
@@ -279,6 +279,147 @@ ERROR 42000: Incorrect number of argumen
 DROP TABLE t1;
 DROP FUNCTION f1;
 End of 5.0 tests
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+DROP DATABASE IF EXISTS db3;
+DROP DATABASE IF EXISTS db4;
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS count;
+USE test;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+CREATE TABLE db1.t1 (a INT, b INT);
+INSERT INTO db1.t1 VALUES (1,1),(2,2),(3,3);
+CREATE TABLE db1.t2 AS SELECT * FROM db1.t1;
+CREATE TABLE db2.t1 AS SELECT * FROM db1.t2;
+CREATE TABLE db2.t2 AS SELECT * FROM db2.t1;
+CREATE TABLE t1 AS SELECT * FROM db2.t2;
+CREATE TABLE t2 AS SELECT * FROM t1;
+CREATE PROCEDURE count_rows()
+BEGIN
+SELECT COUNT(*) AS "COUNT(db1.t1)" FROM db1.t1;
+SELECT COUNT(*) AS "COUNT(db1.t2)" FROM db1.t2;
+SELECT COUNT(*) AS "COUNT(db2.t1)" FROM db2.t1;
+SELECT COUNT(*) AS "COUNT(db2.t2)" FROM db2.t2;
+SELECT COUNT(*) AS "COUNT(test.t1)" FROM test.t1;
+SELECT COUNT(*) AS "COUNT(test.t2)" FROM test.t2;
+END|
+CREATE DATABASE db3;
+USE db3;
+DROP DATABASE db3;
+SELECT * FROM t1;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db1.t1, db2.t2;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db1.t1, db2.t2;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+ERROR 3D000: No database selected
+DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
+ERROR 3D000: No database selected
+DELETE a1 FROM db1.a1, db2.t2 AS a1;
+ERROR 3D000: No database selected
+DELETE a1 FROM a1, db1.t1 AS a1;
+ERROR 3D000: No database selected
+DELETE t1 FROM db1.t1, db2.t1 AS a1;
+ERROR 3D000: No database selected
+DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
+ERROR 3D000: No database selected
+DELETE t1 FROM db1.t1, db2.t1;
+ERROR 3D000: No database selected
+USE test;
+DELETE a1,a2 FROM db1.t1, db2.t2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE a1,a2 FROM db1.t1, db2.t2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
+ERROR 42S02: Unknown table 'a2' in MULTI DELETE
+DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+ERROR 42S02: Table 'db3.t1' doesn't exist
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+ERROR 42S02: Table 'db3.t1' doesn't exist
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
+ERROR 42S02: Unknown table 'a2' in MULTI DELETE
+DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
+ERROR 42S02: Unknown table 'a1' in MULTI DELETE
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+ERROR 42S02: Table 'db3.t1' doesn't exist
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+ERROR 42S02: Table 'db3.t1' doesn't exist
+DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
+ERROR 42000: Not unique table/alias: 'a1'
+DELETE a1 FROM db1.a1, db2.t2 AS a1;
+ERROR 42S02: Table 'db1.a1' doesn't exist
+DELETE a1 FROM a1, db1.t1 AS a1;
+ERROR 42000: Not unique table/alias: 'a1'
+DELETE t1 FROM db1.t1, db2.t1 AS a1;
+ERROR 42S02: Unknown table 't1' in MULTI DELETE
+DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
+ERROR 42S02: Unknown table 't1' in MULTI DELETE
+DELETE t1 FROM db1.t1, db2.t1;
+ERROR 42S02: Unknown table 't1' in MULTI DELETE
+DELETE t1 FROM db1.t2 AS t1, db2.t2 AS t2 WHERE t2.a = 1 AND t1.a = t2.a;
+SELECT ROW_COUNT();
+ROW_COUNT()
+1
+CALL count_rows();
+COUNT(db1.t1)
+3
+COUNT(db1.t2)
+2
+COUNT(db2.t1)
+3
+COUNT(db2.t2)
+3
+COUNT(test.t1)
+3
+COUNT(test.t2)
+3
+DELETE a1, a2 FROM db2.t1 AS a1, t2 AS a2 WHERE a1.a = 2 AND a2.a = 2;
+SELECT ROW_COUNT();
+ROW_COUNT()
+2
+CALL count_rows();
+COUNT(db1.t1)
+3
+COUNT(db1.t2)
+2
+COUNT(db2.t1)
+2
+COUNT(db2.t2)
+3
+COUNT(test.t1)
+3
+COUNT(test.t2)
+2
+DROP DATABASE db1;
+DROP DATABASE db2;
+DROP PROCEDURE count_rows;
+DROP TABLE t1, t2;
 #
 # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger, 
 # merge table

=== modified file 'mysql-test/r/derived.result'
--- a/mysql-test/r/derived.result	2009-07-11 18:44:29 +0000
+++ b/mysql-test/r/derived.result	2009-11-10 18:48:46 +0000
@@ -277,7 +277,7 @@ select * from t1;
 N	M
 3	0
 delete P1.*,p2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS p2 ON P1.N = p2.N;
-ERROR 42S02: Unknown table 'p2' in MULTI DELETE
+ERROR HY000: The target table p2 of the DELETE is not updatable
 delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
 ERROR 42S22: Unknown column 'aaa' in 'field list'
 drop table t1;

=== modified file 'mysql-test/r/dirty_close.result'
--- a/mysql-test/r/dirty_close.result	2009-03-03 20:34:18 +0000
+++ b/mysql-test/r/dirty_close.result	2009-11-10 19:09:27 +0000
@@ -7,3 +7,13 @@ n
 2
 3
 DROP TABLE t1;
+SELECT GET_LOCK("dangling", 0);
+GET_LOCK("dangling", 0)
+1
+SELECT GET_LOCK('dangling', 3600);;
+SELECT GET_LOCK('dangling', 3600);;
+SELECT RELEASE_LOCK('dangling');
+RELEASE_LOCK('dangling')
+1
+GET_LOCK('dangling', 3600)
+1

=== modified file 'mysql-test/r/func_sapdb.result'
--- a/mysql-test/r/func_sapdb.result	2009-10-13 16:50:08 +0000
+++ b/mysql-test/r/func_sapdb.result	2009-11-04 09:17:39 +0000
@@ -282,3 +282,33 @@ TIMEDIFF(TIME('17:59:00'),TIME('17:00:00
 TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
 1Eq	1NEq1	1NEq2	2Eq	2NEq1	2NEq2	3Eq	3NEq1	3NEq2	Time0	Time00	Literal0000	TIMEDIFF(TIME('17:59:00'),TIME('17:00:00'))	TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'))
 1	0	0	1	0	0	1	0	0	00:00:00	00:00:00	00:00:00	00:59:00	-00:59:00
+SELECT sec_to_time(3020399)=TIME('838:59:59');
+sec_to_time(3020399)=TIME('838:59:59')
+1
+SELECT sec_to_time(-3020399)=TIME('-838:59:59');
+sec_to_time(-3020399)=TIME('-838:59:59')
+1
+SELECT sec_to_time(-3020399)='-838:59:59';
+sec_to_time(-3020399)='-838:59:59'
+1
+SELECT time(sec_to_time(-3020399))=TIME('-838:59:59');
+time(sec_to_time(-3020399))=TIME('-838:59:59')
+1
+SELECT time(sec_to_time(-3020399))=TIME('-838:59:58');
+time(sec_to_time(-3020399))=TIME('-838:59:58')
+0
+SELECT maketime(-1,0,1)='-01:00:01';
+maketime(-1,0,1)='-01:00:01'
+1
+SELECT TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME);
+TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME)
+1
+SELECT maketime(-1,0,1)=CAST('-01:00:01' AS TIME);
+maketime(-1,0,1)=CAST('-01:00:01' AS TIME)
+1
+SELECT maketime(1,0,1)=CAST('01:00:01' AS TIME);
+maketime(1,0,1)=CAST('01:00:01' AS TIME)
+1
+SELECT maketime(1,0,1)=CAST('01:00:02' AS TIME);
+maketime(1,0,1)=CAST('01:00:02' AS TIME)
+0

=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result	2009-10-13 16:50:08 +0000
+++ b/mysql-test/r/func_time.result	2009-11-03 22:29:16 +0000
@@ -1301,6 +1301,12 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
+select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
+date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond)
+1000-01-02 03:02:01.050000
+select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
+date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond)
+1000-01-01 00:00:01.020000
 End of 5.0 tests
 select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
 date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)

=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result	2009-10-15 12:23:43 +0000
+++ b/mysql-test/r/mysql.result	2009-11-04 12:20:02 +0000
@@ -201,6 +201,202 @@ COUNT (*)
 ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno)
 End of 5.0 tests
 WARNING: --server-arg option not supported in this configuration.
+*************************** 1. row ***************************
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0

+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8

+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6

+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4

+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
+1: 1
+2: 2
+3: 3
+4: 4
+5: 5
+6: 6
+7: 7
+8: 8
+9: 9
+0: 0
++---+
+| 1 |
++---+
+| 1 |
++---+
 Warning (Code 1286): Unknown table engine 'nonexistent'
 Warning (Code 1266): Using storage engine MyISAM for table 't2'
 Warning (Code 1286): Unknown table engine 'nonexistent2'

=== added file 'mysql-test/r/partition_sync.result'
--- a/mysql-test/r/partition_sync.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/partition_sync.result	2009-11-04 11:59:46 +0000
@@ -0,0 +1,25 @@
+#
+# Bug #43867 ALTER TABLE on a partitioned table 
+#            causes unnecessary deadlocks
+#
+CREATE TABLE t1 (a int) PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (1),
+PARTITION p1 VALUES LESS THAN (2));
+INSERT INTO t1 VALUES (0),(1);
+# Connection 2
+BEGIN;
+SELECT * FROM t1;
+a
+0
+1
+# Connection 1
+ALTER TABLE t1 DROP PARTITION p3;
+ERROR HY000: Error in list of partitions to DROP
+# Connection 2
+# This failed with deadlock and should not do so.
+SELECT * FROM t1;
+a
+0
+1
+# Connection 1
+DROP TABLE t1;

=== added file 'mysql-test/r/rpl_mysqldump_slave.result'
--- a/mysql-test/r/rpl_mysqldump_slave.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/rpl_mysqldump_slave.result	2009-11-04 13:31:03 +0000
@@ -0,0 +1,17 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+#
+# New --dump-slave, --apply-slave-statements functionality
+#
+use test;
+CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
+STOP SLAVE;
+CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
+START SLAVE;
+STOP SLAVE;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT='MASTER_MYPORT', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=107;
+START SLAVE;

=== modified file 'mysql-test/r/sp-error.result'
--- a/mysql-test/r/sp-error.result	2009-11-05 09:20:41 +0000
+++ b/mysql-test/r/sp-error.result	2009-11-19 23:48:08 +0000
@@ -1659,6 +1659,18 @@ begin
 declare continue handler for sqlstate '00000' set @x=0;
 end$$
 ERROR 42000: Bad SQLSTATE: '00000'
+drop procedure if exists p1;
+set @old_recursion_depth = @@max_sp_recursion_depth;
+set @@max_sp_recursion_depth = 255;
+create procedure p1(a int)
+begin
+declare continue handler for 1436 -- ER_STACK_OVERRUN_NEED_MORE
+select 'exception';
+call p1(a+1);
+end|
+call p1(1);
+set @@max_sp_recursion_depth = @old_recursion_depth;
+drop procedure p1;
 LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc;
 CREATE TABLE t1 (a INT, b INT);
 INSERT INTO t1 VALUES (1,1), (2,2);

=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result	2009-11-06 14:20:27 +0000
+++ b/mysql-test/r/sp.result	2009-11-19 23:48:08 +0000
@@ -6941,6 +6941,101 @@ SELECT * FROM t1 WHERE a = f1();
 ERROR 42S02: Table 'test.t_non_existing' doesn't exist
 DROP FUNCTION f1;
 DROP TABLE t1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE PROCEDURE p1(a INT, b CHAR)
+BEGIN
+IF a > 0 THEN
+CALL p1(a-1, 'ab');
+ELSE
+SELECT 1;
+END IF;
+END|
+SET @save_max_sp_recursion= @@max_sp_recursion_depth;
+SET @@max_sp_recursion_depth= 5;
+CALL p1(4, 'a');
+1
+1
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+SET @@max_sp_recursion_depth= @save_max_sp_recursion;
+DROP PROCEDURE p1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE PROCEDURE p1(a CHAR)
+BEGIN
+SELECT 1;
+SELECT CAST('10 ' as UNSIGNED INTEGER);
+SELECT 1;
+END|
+CALL p1('data truncated parameter');
+1
+1
+CAST('10 ' as UNSIGNED INTEGER)
+10
+1
+1
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+Warning	1292	Truncated incorrect INTEGER value: '10 '
+DROP PROCEDURE p1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+CREATE PROCEDURE p1()
+CALL p2()|
+CREATE PROCEDURE p2()
+CALL p3()|
+CREATE PROCEDURE p3()
+CALL p4()|
+CREATE PROCEDURE p4()
+BEGIN
+SELECT 1;
+SELECT CAST('10 ' as UNSIGNED INTEGER);
+SELECT 2;
+END|
+CALL p1();
+1
+1
+CAST('10 ' as UNSIGNED INTEGER)
+10
+2
+2
+Warnings:
+Warning	1292	Truncated incorrect INTEGER value: '10 '
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a CHAR(2));
+INSERT INTO t1 VALUES ('aa');
+CREATE FUNCTION f1() RETURNS CHAR
+RETURN (SELECT f2())|
+CREATE FUNCTION f2() RETURNS CHAR
+RETURN (SELECT f3())|
+CREATE FUNCTION f3() RETURNS CHAR
+RETURN (SELECT f4())|
+CREATE FUNCTION f4() RETURNS CHAR
+BEGIN
+RETURN (SELECT a FROM t1);
+END|
+SELECT f1();
+f1()
+a
+Warnings:
+Warning	1265	Data truncated for column 'f4()' at row 1
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP FUNCTION f4;
+DROP TABLE t1;
 #
 # Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non 
 #            strict SQL mode

=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result	2009-10-12 10:59:55 +0000
+++ b/mysql-test/r/trigger.result	2009-11-10 18:11:27 +0000
@@ -2115,3 +2115,50 @@ s1
 DELETE FROM t1;
 DROP TABLE t1;
 DROP TEMPORARY TABLE t2;
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+DECLARE a CHAR;
+SELECT 'ab' INTO a;
+SELECT 'ab' INTO a;
+SELECT 'a' INTO a;
+END|
+INSERT INTO t1 VALUES (1);
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+DROP TRIGGER trg1;
+DROP TABLE t1;
+DROP TRIGGER IF EXISTS trg1;
+DROP TRIGGER IF EXISTS trg2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+DECLARE trg1 CHAR;
+SELECT 'ab' INTO trg1;
+END|
+CREATE TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
+BEGIN
+DECLARE trg2 CHAR;
+SELECT 'ab' INTO trg2;
+END|
+INSERT INTO t1 VALUES (0);
+Warnings:
+Warning	1265	Data truncated for column 'trg1' at row 1
+Warning	1265	Data truncated for column 'trg2' at row 1
+SELECT * FROM t1;
+a
+0
+SHOW WARNINGS;
+Level	Code	Message
+INSERT INTO t1 VALUES (1),(2);
+Warnings:
+Warning	1265	Data truncated for column 'trg1' at row 1
+Warning	1265	Data truncated for column 'trg2' at row 1
+Warning	1265	Data truncated for column 'trg1' at row 1
+Warning	1265	Data truncated for column 'trg2' at row 1
+DROP TRIGGER trg1;
+DROP TRIGGER trg2;
+DROP TABLE t1;

=== modified file 'mysql-test/r/type_time.result'
--- a/mysql-test/r/type_time.result	2009-05-15 08:42:57 +0000
+++ b/mysql-test/r/type_time.result	2009-11-04 10:28:50 +0000
@@ -85,6 +85,7 @@ sec_to_time(time_to_sec(t))
 13:00:00
 09:00:00
 drop table t1;
+End of 4.1 tests
 select cast('100:55:50' as time) < cast('24:00:00' as time);
 cast('100:55:50' as time) < cast('24:00:00' as time)
 0
@@ -138,3 +139,27 @@ CAST(c AS TIME)
 00:00:00
 DROP TABLE t1;
 End of 5.0 tests
+CREATE TABLE t1 (f1 TIME);
+INSERT INTO t1 VALUES ('24:00:00');
+SELECT      '24:00:00' = (SELECT f1 FROM t1);
+'24:00:00' = (SELECT f1 FROM t1)
+1
+SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
+CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1)
+1
+SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
+CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1)
+0
+TRUNCATE t1;
+INSERT INTO t1 VALUES ('-24:00:00');
+SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
+CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1)
+0
+SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
+CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1)
+1
+SELECT '-24:00:00' = (SELECT f1 FROM t1);
+'-24:00:00' = (SELECT f1 FROM t1)
+1
+DROP TABLE t1;
+End of 6.0 tests

=== modified file 'mysql-test/suite/rpl/r/rpl_multi_delete2.result'
--- a/mysql-test/suite/rpl/r/rpl_multi_delete2.result	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_multi_delete2.result	2009-11-10 18:48:46 +0000
@@ -16,7 +16,7 @@ DELETE alias FROM a alias WHERE alias.i=
 SELECT * FROM a;
 i
 insert into a values(2),(3);
-delete a alias FROM a alias where alias.i=2;
+delete alias FROM a alias where alias.i=2;
 select * from a;
 i
 3

=== modified file 'mysql-test/suite/rpl/t/rpl_multi_delete2.test'
--- a/mysql-test/suite/rpl/t/rpl_multi_delete2.test	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_multi_delete2.test	2009-11-10 18:48:46 +0000
@@ -25,7 +25,7 @@ INSERT INTO a VALUES(1);
 DELETE alias FROM a alias WHERE alias.i=1;
 SELECT * FROM a;
 insert into a values(2),(3);
-delete a alias FROM a alias where alias.i=2;
+delete alias FROM a alias where alias.i=2;
 select * from a;
 save_master_pos;
 connection slave;

=== modified file 'mysql-test/suite/sys_vars/r/group_concat_max_len_func.result'
--- a/mysql-test/suite/sys_vars/r/group_concat_max_len_func.result	2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/r/group_concat_max_len_func.result	2009-11-10 18:26:39 +0000
@@ -41,7 +41,10 @@ id	rollno	GROUP_CONCAT(name)
 4	3	Reco
 7	4	Reco
 Warnings:
-Warning	1260	4 line(s) were cut by GROUP_CONCAT()
+Warning	1260	Row 1 was cut by GROUP_CONCAT()
+Warning	1260	Row 2 was cut by GROUP_CONCAT()
+Warning	1260	Row 3 was cut by GROUP_CONCAT()
+Warning	1260	Row 4 was cut by GROUP_CONCAT()
 ## Changing session value of variable and verifying its behavior, ##
 ## warning should come here ##
 SET @@session.group_concat_max_len = 10;
@@ -52,7 +55,9 @@ id	rollno	GROUP_CONCAT(name)
 4	3	Record_4,R
 7	4	Record_7,R
 Warnings:
-Warning	1260	3 line(s) were cut by GROUP_CONCAT()
+Warning	1260	Row 2 was cut by GROUP_CONCAT()
+Warning	1260	Row 5 was cut by GROUP_CONCAT()
+Warning	1260	Row 7 was cut by GROUP_CONCAT()
 '#--------------------FN_DYNVARS_034_03-------------------------#'
 ## Connecting with new connection test_con2 ##
 ## Verifying initial value of variable. It should be 4 ##
@@ -71,7 +76,7 @@ id	rollno	GROUP_CONCAT(name)
 4	3	Record_4,Record_6
 7	4	Record_7,Record_8
 Warnings:
-Warning	1260	1 line(s) were cut by GROUP_CONCAT()
+Warning	1260	Row 3 was cut by GROUP_CONCAT()
 '#--------------------FN_DYNVARS_034_04-------------------------#'
 ## Setting session value of variable to 26. No warning should appear here ##
 ## because the value after concatination is less than 30 ##

=== modified file 'mysql-test/t/alias.test'
--- a/mysql-test/t/alias.test	2005-10-31 11:25:08 +0000
+++ b/mysql-test/t/alias.test	2009-11-10 20:43:43 +0000
@@ -86,3 +86,132 @@ ASC LIMIT 1;
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug#27249 table_wild with alias: select t1.* as something
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+create table t1 (a int, b int, c int);
+create table t2 (d int);
+create table t3 (a1 int, b1 int, c1 int);
+insert into t1 values(1,2,3);
+insert into t1 values(11,22,33);
+insert into t2 values(99);
+
+# Invalid queries with alias on wild
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+select t2.* as 'with_alias' from t2;
+--error ER_PARSE_ERROR
+select t1.*, t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', t1.* from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', t1.* as 'alias2' from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', a, t1.* as 'alias2' from t1;
+
+# other fields without alias
+--error ER_PARSE_ERROR
+select a, t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', a from t1;
+--error ER_PARSE_ERROR
+select a, t1.* as 'with_alias', b from t1;
+--error ER_PARSE_ERROR
+select (select d from t2 where d > a), t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', (select a from t2 where d > a) from t1;
+
+# other fields with alias
+--error ER_PARSE_ERROR
+select a as 'x', t1.* as 'with_alias' from t1;

+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', a as 'x' from t1;
+--error ER_PARSE_ERROR
+select a as 'x', t1.* as 'with_alias', b as 'x' from t1;
+--error ER_PARSE_ERROR
+select (select d from t2 where d > a) as 'x', t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+select t1.* as 'with_alias', (select a from t2 where d > a) as 'x' from t1;
+
+# some more subquery
+--error ER_PARSE_ERROR
+select (select t2.* as 'x' from t2) from t1;
+--error ER_PARSE_ERROR
+select a, (select t2.* as 'x' from t2) from t1;
+--error ER_PARSE_ERROR
+select t1.*, (select t2.* as 'x' from t2) from t1;
+
+# insert
+--error ER_PARSE_ERROR
+insert into t3 select t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+insert into t3 select t2.* as 'with_alias', 1, 2 from t2;
+--error ER_PARSE_ERROR
+insert into t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
+--error ER_PARSE_ERROR
+insert into t3 select t2.*, t2.* as 'with_alias', 3 from t2;
+
+# create
+--error ER_PARSE_ERROR
+create table t3 select t1.* as 'with_alias' from t1;
+--error ER_PARSE_ERROR
+create table t3 select t2.* as 'with_alias', 1, 2 from t2;
+--error ER_PARSE_ERROR
+create table t3 select t2.* as 'with_alias', d as 'x', d as 'z' from t2;
+--error ER_PARSE_ERROR
+create table t3 select t2.*, t2.* as 'with_alias', 3 from t2;
+
+#
+# Valid queries without alias on wild
+# (proof the above fail due to invalid aliasing)
+#
+
+select t1.* from t1;
+select t2.* from t2;
+select t1.*, t1.* from t1;
+select t1.*, a, t1.* from t1;
+
+# other fields without alias
+select a, t1.* from t1;
+select t1.*, a from t1;
+select a, t1.*, b from t1;
+select (select d from t2 where d > a), t1.* from t1;
+select t1.*, (select a from t2 where d > a) from t1;
+
+# other fields with alias
+select a as 'x', t1.* from t1;
+select t1.*, a as 'x' from t1;
+select a as 'x', t1.*, b as 'x' from t1;
+select (select d from t2 where d > a) as 'x', t1.* from t1;
+select t1.*, (select a from t2 where d > a) as 'x' from t1;
+
+# some more subquery
+select (select t2.* from t2) from t1;
+select a, (select t2.* from t2) from t1;
+select t1.*, (select t2.* from t2) from t1;
+

+# insert
+insert into t3 select t1.* from t1;
+insert into t3 select t2.*, 1, 2 from t2;
+insert into t3 select t2.*, d as 'x', d as 'z' from t2;
+insert into t3 select t2.*, t2.*, 3 from t2;
+
+# create
+create table t4 select t1.* from t1;
+drop table t4;
+create table t4 select t2.*, 1, 2 from t2;
+drop table t4;
+create table t4 select t2.*, d as 'x', d as 'z' from t2;
+drop table t4;
+
+# end
+drop table t1,t2,t3;
+
+# End of 5.2 tests

=== modified file 'mysql-test/t/delete.test'
--- a/mysql-test/t/delete.test	2009-09-28 10:48:52 +0000
+++ b/mysql-test/t/delete.test	2009-11-10 18:48:46 +0000
@@ -265,8 +265,8 @@ DELETE FROM t1, alias USING t1, t2 alias
 DELETE FROM t1, t2 USING t1, t2 alias WHERE t1.a = alias.a;
 --error ER_PARSE_ERROR
 DELETE FROM db1.t1 alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
---error ER_UNKNOWN_TABLE
 DELETE FROM alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
+--error ER_UNKNOWN_TABLE
 DELETE FROM db2.alias USING db1.t1, db2.t1 alias WHERE db1.t1.a = alias.a;
 DELETE FROM t1 USING t1 WHERE a = 1;
 SELECT * FROM t1;
@@ -293,6 +293,159 @@ DROP FUNCTION f1;
 
 --echo End of 5.0 tests
 
+#
+# Bug#27525: table not found when using multi-table-deletes with aliases over
+#            several databas
+# Bug#21148: MULTI-DELETE fails to resolve a table by alias if it's from a
+#            different database
+#
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP DATABASE IF EXISTS db2;
+DROP DATABASE IF EXISTS db3;
+DROP DATABASE IF EXISTS db4;
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS count;
+--enable_warnings
+USE test;
+CREATE DATABASE db1;
+CREATE DATABASE db2;
+
+CREATE TABLE db1.t1 (a INT, b INT);
+INSERT INTO db1.t1 VALUES (1,1),(2,2),(3,3);
+CREATE TABLE db1.t2 AS SELECT * FROM db1.t1;
+CREATE TABLE db2.t1 AS SELECT * FROM db1.t2;
+CREATE TABLE db2.t2 AS SELECT * FROM db2.t1;
+CREATE TABLE t1 AS SELECT * FROM db2.t2;
+CREATE TABLE t2 AS SELECT * FROM t1;
+
+delimiter |;
+CREATE PROCEDURE count_rows()
+BEGIN
+  SELECT COUNT(*) AS "COUNT(db1.t1)" FROM db1.t1;
+  SELECT COUNT(*) AS "COUNT(db1.t2)" FROM db1.t2;
+  SELECT COUNT(*) AS "COUNT(db2.t1)" FROM db2.t1;
+  SELECT COUNT(*) AS "COUNT(db2.t2)" FROM db2.t2;
+  SELECT COUNT(*) AS "COUNT(test.t1)" FROM test.t1;
+  SELECT COUNT(*) AS "COUNT(test.t2)" FROM test.t2;
+END|
+delimiter ;|
+
+#
+# Testing without a selected database
+#
+
+CREATE DATABASE db3;
+USE db3;
+DROP DATABASE db3;
+--error ER_NO_DB_ERROR
+SELECT * FROM t1;
+
+# Detect missing table references
+
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db1.t1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db1.t1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+--error ER_NO_DB_ERROR
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+--error ER_NO_DB_ERROR
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+
+# Ambiguous table references
+
+--error ER_NO_DB_ERROR
+DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
+--error ER_NO_DB_ERROR
+DELETE a1 FROM db1.a1, db2.t2 AS a1;
+--error ER_NO_DB_ERROR
+DELETE a1 FROM a1, db1.t1 AS a1;
+--error ER_NO_DB_ERROR
+DELETE t1 FROM db1.t1, db2.t1 AS a1;
+--error ER_NO_DB_ERROR
+DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
+--error ER_NO_DB_ERROR
+DELETE t1 FROM db1.t1, db2.t1;
+
+# Test all again, now with a selected database
+
+USE test;
+
+# Detect missing table references
+
+--error ER_UNKNOWN_TABLE
+DELETE a1,a2 FROM db1.t1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE a1,a2 FROM db1.t1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE a1,a2 FROM db1.t1 AS a1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE a1,a2 FROM db1.t1, db2.t2 AS a2;
+--error ER_NO_SUCH_TABLE
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+--error ER_NO_SUCH_TABLE
+DELETE a1,a2 FROM db3.t1 AS a1, db4.t2 AS a2;
+
+--error ER_UNKNOWN_TABLE
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE FROM a1,a2 USING db1.t1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE FROM a1,a2 USING db1.t1 AS a1, db2.t2;
+--error ER_UNKNOWN_TABLE
+DELETE FROM a1,a2 USING db1.t1, db2.t2 AS a2;
+--error ER_NO_SUCH_TABLE
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+--error ER_NO_SUCH_TABLE
+DELETE FROM a1,a2 USING db3.t1 AS a1, db4.t2 AS a2;
+
+# Ambiguous table references
+
+--error ER_NONUNIQ_TABLE
+DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1;
+--error ER_NO_SUCH_TABLE
+DELETE a1 FROM db1.a1, db2.t2 AS a1;
+--error ER_NONUNIQ_TABLE
+DELETE a1 FROM a1, db1.t1 AS a1;
+--error ER_UNKNOWN_TABLE
+DELETE t1 FROM db1.t1, db2.t1 AS a1;
+--error ER_UNKNOWN_TABLE
+DELETE t1 FROM db1.t1 AS a1, db2.t1 AS a2;
+--error ER_UNKNOWN_TABLE
+DELETE t1 FROM db1.t1, db2.t1;
+
+# Test multiple-table cross database deletes
+
+DELETE t1 FROM db1.t2 AS t1, db2.t2 AS t2 WHERE t2.a = 1 AND t1.a = t2.a;
+SELECT ROW_COUNT();
+CALL count_rows();
+DELETE a1, a2 FROM db2.t1 AS a1, t2 AS a2 WHERE a1.a = 2 AND a2.a = 2;
+SELECT ROW_COUNT();
+CALL count_rows();
+
+DROP DATABASE db1;
+DROP DATABASE db2;
+DROP PROCEDURE count_rows;
+DROP TABLE t1, t2;
+
 --echo #
 --echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger, 
 --echo # merge table

=== modified file 'mysql-test/t/derived.test'
--- a/mysql-test/t/derived.test	2009-07-11 18:44:29 +0000
+++ b/mysql-test/t/derived.test	2009-11-10 18:48:46 +0000
@@ -158,7 +158,7 @@ UPDATE `t1` AS P1 INNER JOIN (SELECT aaa
 delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
 select * from t1;
 --replace_result P2 p2
---error ER_UNKNOWN_TABLE 
+--error ER_NON_UPDATABLE_TABLE
 delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
 -- error 1054
 delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;

=== modified file 'mysql-test/t/dirty_close.test'
--- a/mysql-test/t/dirty_close.test	2009-03-03 20:34:18 +0000
+++ b/mysql-test/t/dirty_close.test	2009-11-13 12:56:38 +0000
@@ -1,3 +1,4 @@
+--source include/not_embedded.inc
 
 # Save the initial number of concurrent sessions
 --source include/count_sessions.inc
@@ -22,6 +23,38 @@ disconnect con2;
 
 # End of 4.1 tests
 
+#
+# Bug#10374 GET_LOCK does not let connection to close on the server side if it's aborted
+#
+
+connection default;
+SELECT GET_LOCK("dangling", 0);
+connect(con1, localhost, root,,);
+connection con1;
+--send SELECT GET_LOCK('dangling', 3600);
+connection default;
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
+  AND INFO = "SELECT GET_LOCK('dangling', 3600)";
+--source include/wait_condition.inc
+dirty_close con1;
+let $wait_condition=
+  SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
+  AND INFO = "SELECT GET_LOCK('dangling', 3600)";
+--source include/wait_condition.inc
+connect(con1, localhost, root,,);
+--send SELECT GET_LOCK('dangling', 3600);
+connection default;
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = "User lock"
+  AND INFO = "SELECT GET_LOCK('dangling', 3600)";
+--source include/wait_condition.inc
+SELECT RELEASE_LOCK('dangling');
+connection con1;
+--reap
+connection default;
+disconnect con1;
+
 # Wait till all disconnects are completed
 --source include/wait_until_count_sessions.inc
 

=== modified file 'mysql-test/t/func_sapdb.test'
--- a/mysql-test/t/func_sapdb.test	2009-02-07 15:50:31 +0000
+++ b/mysql-test/t/func_sapdb.test	2009-11-04 09:17:39 +0000
@@ -169,4 +169,26 @@ SELECT TIMEDIFF(TIME('17:00:00'),TIME('1
        TIMEDIFF(TIME('17:59:00'),TIME('17:00:00')),
        TIMEDIFF(TIME('17:00:00'),TIME('17:59:00'));
 
+#
+# Bug#42661 - sec_to_time() and signedness
+#
+
+SELECT sec_to_time(3020399)=TIME('838:59:59');
+SELECT sec_to_time(-3020399)=TIME('-838:59:59');
+SELECT sec_to_time(-3020399)='-838:59:59';
+SELECT time(sec_to_time(-3020399))=TIME('-838:59:59');
+SELECT time(sec_to_time(-3020399))=TIME('-838:59:58');
+
+#
+# Bug#42662 - maketime() and signedness
+#
+
+# TIME(...) and CAST(... AS TIME) go through the same code-path here,
+# but we'll explicitly show show that both work in case the ever changes.
+SELECT maketime(-1,0,1)='-01:00:01';
+SELECT TIME(maketime(-1,0,1))=CAST('-01:00:01' AS TIME);
+SELECT maketime(-1,0,1)=CAST('-01:00:01' AS TIME);
+SELECT maketime(1,0,1)=CAST('01:00:01' AS TIME);
+SELECT maketime(1,0,1)=CAST('01:00:02' AS TIME);
+
 # End of 5.0 tests

=== modified file 'mysql-test/t/func_time.test'
--- a/mysql-test/t/func_time.test	2009-01-23 12:22:05 +0000
+++ b/mysql-test/t/func_time.test	2009-11-03 22:29:16 +0000
@@ -819,6 +819,16 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 --error ER_PARSE_ERROR
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 
+#
+# Bug #36466:
+#   Adding days to day_microsecond changes interpretation of microseconds
+#
+
+# show that we treat fractions of seconds correctly (zerofill from right to
+# six places) even if we left out fields on the left.
+select date_add('1000-01-01 00:00:00', interval '1.03:02:01.05' day_microsecond);
+select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond);
+
 --echo End of 5.0 tests
 
 #

=== modified file 'mysql-test/t/lock_multi.test'
--- a/mysql-test/t/lock_multi.test	2009-07-10 23:12:13 +0000
+++ b/mysql-test/t/lock_multi.test	2009-11-10 14:23:55 +0000
@@ -1,5 +1,3 @@
--- source include/not_embedded.inc
-
 # Save the initial number of concurrent sessions
 --source include/count_sessions.inc
 

=== modified file 'mysql-test/t/mysql.test'
--- a/mysql-test/t/mysql.test	2009-10-15 12:23:43 +0000
+++ b/mysql-test/t/mysql.test	2009-11-04 12:20:02 +0000
@@ -367,6 +367,14 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug310
 --enable_query_log
 
 #
+# Bug#26780: patch to add auto vertical output option to the cli.
+#
+# Make this wide enough that it will wrap almost everywhere.
+--exec $MYSQL test --auto-vertical-output --table -e "SELECT 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0;"
+# Too short to wrap.
+--exec $MYSQL test --auto-vertical-output --table -e "SELECT 1;"
+
+#
 # Bug #25146: Some warnings/errors not shown when using --show-warnings
 #
 

=== added file 'mysql-test/t/partition_sync.test'
--- a/mysql-test/t/partition_sync.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/partition_sync.test	2009-11-04 11:59:46 +0000
@@ -0,0 +1,41 @@
+--source include/have_partition.inc
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+--echo #
+--echo # Bug #43867 ALTER TABLE on a partitioned table 
+--echo #            causes unnecessary deadlocks
+--echo #
+
+CREATE TABLE t1 (a int) PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (1),
+ PARTITION p1 VALUES LESS THAN (2));
+
+INSERT INTO t1 VALUES (0),(1);
+
+connect(con1,localhost,root);
+
+--echo # Connection 2
+connection con1;
+BEGIN;
+SELECT * FROM t1;
+
+--echo # Connection 1
+connection default;
+--error ER_DROP_PARTITION_NON_EXISTENT
+ALTER TABLE t1 DROP PARTITION p3;
+
+--echo # Connection 2
+connection con1;
+--echo # This failed with deadlock and should not do so.
+SELECT * FROM t1;
+
+--echo # Connection 1
+connection default;
+disconnect con1;
+DROP TABLE t1;
+
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc

=== added file 'mysql-test/t/rpl_mysqldump_slave.test'
--- a/mysql-test/t/rpl_mysqldump_slave.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/rpl_mysqldump_slave.test	2009-11-04 13:31:03 +0000
@@ -0,0 +1,25 @@
+source include/master-slave.inc;
+
+--echo #
+--echo # New --dump-slave, --apply-slave-statements functionality
+--echo #
+
+# There is a gap between when START SLAVE returns and when MASTER_LOG_FILE and
+# MASTER_LOG_POS are set.  Ensure that we don't call SHOW SLAVE STATUS during
+# that gap.
+--sync_slave_with_master
+
+connection master;
+use test;
+
+connection slave;
+
+# Execute mysqldump with --dump-slave
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave test
+
+# Execute mysqldump with --dump-slave and --apply-slave-statements 
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --apply-slave-statements test
+
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+# Execute mysqldump with --dump-slave ,--apply-slave-statements and --include-master-host-port
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --apply-slave-statements --include-master-host-port test

=== modified file 'mysql-test/t/shm.test'
--- a/mysql-test/t/shm.test	2009-03-26 23:17:27 +0000
+++ b/mysql-test/t/shm.test	2009-11-10 19:36:38 +0000
@@ -7,10 +7,17 @@ let $shm= query_get_value("SHOW VARIABLE
 if (`SELECT '$shm' != 'ON'`){
   skip No shm support;
 }
+let $shm_name= query_get_value("SHOW GLOBAL VARIABLES LIKE 'shared_memory_base_name'", Value, 1);
+
+# Connect using SHM for testing
+connect(shm_con,localhost,root,,,,$shm_name,SHM);
 
 # Source select test case
 -- source include/common-tests.inc
 
+connection default;
+disconnect shm_con;
+
 #
 # Bug #24924: shared-memory-base-name that is too long causes buffer overflow
 #
@@ -20,7 +27,6 @@ if (`SELECT '$shm' != 'ON'`){
 # Bug #33899: Deadlock in mysql_real_query with shared memory connections
 #
 
-let $name= query_get_value("SHOW GLOBAL VARIABLES LIKE 'shared_memory_base_name'", Value, 1);
 let $stmt= `SELECT REPEAT('a', 2048)`;
 
 SET @max_allowed_packet= @@global.max_allowed_packet;
@@ -30,7 +36,7 @@ SET GLOBAL max_allowed_packet= 1024;
 SET GLOBAL net_buffer_length= 1024;
 
 --error 1
---exec echo SELECT '$stmt'| $MYSQL --protocol=memory --shared-memory-base-name=$name 2>&1
+--exec echo SELECT '$stmt'| $MYSQL --protocol=memory --shared-memory-base-name=$shm_name 2>&1
 
 SET GLOBAL max_allowed_packet= @max_allowed_packet;
 SET GLOBAL net_buffer_length= @net_buffer_length;

=== modified file 'mysql-test/t/sp-error.test'
--- a/mysql-test/t/sp-error.test	2009-10-19 13:55:04 +0000
+++ b/mysql-test/t/sp-error.test	2009-11-19 23:48:08 +0000
@@ -2419,6 +2419,27 @@ end$$
 
 delimiter ;$$
 
+#
+# Bug#15192: "fatal errors" are caught by handlers in stored procedures
+#
+
+--disable_warnings
+drop procedure if exists p1;
+--enable_warnings
+set @old_recursion_depth = @@max_sp_recursion_depth;
+set @@max_sp_recursion_depth = 255;
+delimiter |;
+create procedure p1(a int)
+begin
+  declare continue handler for 1436 -- ER_STACK_OVERRUN_NEED_MORE
+    select 'exception';
+  call p1(a+1);
+end|
+delimiter ;|
+--error 0,ER_STACK_OVERRUN_NEED_MORE,ER_SP_RECURSION_LIMIT
+call p1(1);
+set @@max_sp_recursion_depth = @old_recursion_depth;
+drop procedure p1;
 
 #
 # BUG#NNNN: New bug synopsis

=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test	2009-11-06 14:20:27 +0000
+++ b/mysql-test/t/sp.test	2009-11-19 23:48:08 +0000
@@ -8295,6 +8295,119 @@ SELECT * FROM t1 WHERE a = f1();
 DROP FUNCTION f1;
 DROP TABLE t1;
 
+#
+# Bug#36649: Condition area is not properly cleaned up after stored routine invocation
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+delimiter |;
+CREATE PROCEDURE p1(a INT, b CHAR)
+BEGIN
+  IF a > 0 THEN
+    CALL p1(a-1, 'ab');
+  ELSE
+    SELECT 1;
+  END IF;
+END|
+delimiter ;|
+
+SET @save_max_sp_recursion= @@max_sp_recursion_depth;
+SET @@max_sp_recursion_depth= 5;
+CALL p1(4, 'a');
+SET @@max_sp_recursion_depth= @save_max_sp_recursion;
+
+DROP PROCEDURE p1;
+
+#
+# Ensure that rules for message list clean up are being respected.
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+delimiter |;
+CREATE PROCEDURE p1(a CHAR)
+BEGIN
+  SELECT 1;
+  SELECT CAST('10 ' as UNSIGNED INTEGER);
+  SELECT 1;
+END|
+delimiter ;|
+
+CALL p1('data truncated parameter');
+
+DROP PROCEDURE p1;
+
+#
+# Cascading stored procedure/function calls.
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+--enable_warnings
+
+delimiter |;
+CREATE PROCEDURE p1()
+  CALL p2()|
+CREATE PROCEDURE p2()
+  CALL p3()|
+CREATE PROCEDURE p3()
+  CALL p4()|
+CREATE PROCEDURE p4()
+BEGIN
+  SELECT 1;
+  SELECT CAST('10 ' as UNSIGNED INTEGER);
+  SELECT 2;
+END|
+delimiter ;|
+
+CALL p1();
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+
+--disable_warnings
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a CHAR(2));
+
+INSERT INTO t1 VALUES ('aa');
+
+delimiter |;
+CREATE FUNCTION f1() RETURNS CHAR
+  RETURN (SELECT f2())|
+CREATE FUNCTION f2() RETURNS CHAR
+  RETURN (SELECT f3())|
+CREATE FUNCTION f3() RETURNS CHAR
+  RETURN (SELECT f4())|
+CREATE FUNCTION f4() RETURNS CHAR
+BEGIN
+  RETURN (SELECT a FROM t1);
+END|
+delimiter ;|
+
+SELECT f1();
+
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP FUNCTION f3;
+DROP FUNCTION f4;
+DROP TABLE t1;
+
 --echo #
 --echo # Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non 
 --echo #            strict SQL mode

=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test	2009-10-12 10:59:55 +0000
+++ b/mysql-test/t/trigger.test	2009-11-10 18:11:27 +0000
@@ -2425,3 +2425,67 @@ DELETE FROM t1;
 
 DROP TABLE t1;
 DROP TEMPORARY TABLE t2;
+
+#
+# Bug#36649: Condition area is not properly cleaned up after stored routine invocation
+#
+
+--disable_warnings
+DROP TRIGGER IF EXISTS trg1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT);
+
+delimiter |;
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+  DECLARE a CHAR;
+  SELECT 'ab' INTO a;
+  SELECT 'ab' INTO a;
+  SELECT 'a' INTO a;
+END|
+delimiter ;|
+
+INSERT INTO t1 VALUES (1);
+
+DROP TRIGGER trg1;
+DROP TABLE t1;
+
+#
+# Successive trigger actuations
+#
+
+--disable_warnings
+DROP TRIGGER IF EXISTS trg1;
+DROP TRIGGER IF EXISTS trg2;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT);
+
+delimiter |;
+
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+  DECLARE trg1 CHAR;
+  SELECT 'ab' INTO trg1;
+END|
+
+CREATE TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
+BEGIN
+  DECLARE trg2 CHAR;
+  SELECT 'ab' INTO trg2;
+END|
+
+delimiter ;|
+
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t1;
+SHOW WARNINGS;
+INSERT INTO t1 VALUES (1),(2);
+
+DROP TRIGGER trg1;
+DROP TRIGGER trg2;
+DROP TABLE t1;
+

=== modified file 'mysql-test/t/type_time.test'
--- a/mysql-test/t/type_time.test	2009-05-15 08:16:00 +0000
+++ b/mysql-test/t/type_time.test	2009-11-04 10:28:50 +0000
@@ -39,7 +39,7 @@ drop table t1;
 # SELECT CAST(0.2359591234567e+30 AS TIME);
 # ##########################################################
 
-# End of 4.1 tests
+--echo End of 4.1 tests
 
 #
 # Bug#29555: Comparing time values as strings may lead to a wrong result.
@@ -90,3 +90,22 @@ DROP TABLE t1;
 
 
 --echo End of 5.0 tests
+
+
+#
+# Bug#42664 - Sign ignored for TIME types when not comparing as longlong
+#
+
+CREATE TABLE t1 (f1 TIME);
+INSERT INTO t1 VALUES ('24:00:00');
+SELECT      '24:00:00' = (SELECT f1 FROM t1);
+SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
+SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
+TRUNCATE t1;
+INSERT INTO t1 VALUES ('-24:00:00');
+SELECT CAST('24:00:00' AS TIME) = (SELECT f1 FROM t1);
+SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
+SELECT '-24:00:00' = (SELECT f1 FROM t1);
+DROP TABLE t1;
+
+--echo End of 6.0 tests

=== modified file 'mysys/my_alloc.c'
--- a/mysys/my_alloc.c	2009-01-15 18:11:25 +0000
+++ b/mysys/my_alloc.c	2009-11-10 20:31:28 +0000
@@ -155,7 +155,7 @@ void *alloc_root(MEM_ROOT *mem_root, siz
   DBUG_ASSERT(alloc_root_inited(mem_root));
 
   length+=ALIGN_SIZE(sizeof(USED_MEM));
-  if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
+  if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
   {
     if (mem_root->error_handler)
       (*mem_root->error_handler)();
@@ -198,7 +198,7 @@ void *alloc_root(MEM_ROOT *mem_root, siz
     get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
     get_size= max(get_size, block_size);
 
-    if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+    if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
     {
       if (mem_root->error_handler)
 	(*mem_root->error_handler)();

=== modified file 'mysys/my_getopt.c'
--- a/mysys/my_getopt.c	2009-11-06 14:20:27 +0000
+++ b/mysys/my_getopt.c	2009-11-19 23:48:08 +0000
@@ -1222,6 +1222,14 @@ void my_print_help(const struct my_optio
       printf("%s", comment);
     }
     putchar('\n');
+    if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
+             (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
+    {
+      if (optp->def_value != 0)
+      {
+        printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
+      }
+    }
   }
 }
 

=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc	2009-11-05 20:28:35 +0000
+++ b/sql/event_data_objects.cc	2009-11-19 23:48:08 +0000
@@ -196,7 +196,7 @@ Event_basic::Event_basic()
 {
   DBUG_ENTER("Event_basic::Event_basic");
   /* init memory root */
-  init_alloc_root(&mem_root, 256, 512);
+  init_sql_alloc(&mem_root, 256, 512);
   dbname.str= name.str= NULL;
   dbname.length= name.length= 0;
   time_zone= NULL;

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2009-11-10 07:31:33 +0000
+++ b/sql/field.cc	2009-11-19 23:48:08 +0000
@@ -6819,86 +6819,6 @@ int Field_string::do_save_field_metadata
 }
 
 
-/*
-  Compare two packed keys
-
-  SYNOPSIS
-    pack_cmp()
-     a			New key
-     b			Original key
-     length		Key length
-     insert_or_update	1 if this is an insert or update
-
-  RETURN
-    < 0	  a < b
-    0	  a = b
-    > 0   a > b
-*/
-
-int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length,
-                           my_bool insert_or_update)
-{
-  uint a_length, b_length;
-  if (length > 255)
-  {
-    a_length= uint2korr(a);
-    b_length= uint2korr(b);
-    a+= 2;
-    b+= 2;
-  }
-  else
-  {
-    a_length= (uint) *a++;
-    b_length= (uint) *b++;
-  }
-  return field_charset->coll->strnncollsp(field_charset,
-                                          a, a_length,
-                                          b, b_length,
-                                          insert_or_update);
-}
-
-
-/**
-  Compare a packed key against row.
-
-  @param key		        Original key
-  @param length		Key length. (May be less than field length)
-  @param insert_or_update	1 if this is an insert or update
-
-  @return
-    < 0	  row < key
-  @return
-    0	  row = key
-  @return
-    > 0   row > key
-*/
-
-int Field_string::pack_cmp(const uchar *key, uint length,
-                           my_bool insert_or_update)
-{
-  uint row_length, local_key_length;
-  uchar *end;
-  if (length > 255)
-  {
-    local_key_length= uint2korr(key);
-    key+= 2;
-  }
-  else
-    local_key_length= (uint) *key++;
-  
-  /* Only use 'length' of key, not field_length */
-  end= ptr + length;
-  while (end > ptr && end[-1] == ' ')
-    end--;
-  row_length= (uint) (end - ptr);
-
-  return field_charset->coll->strnncollsp(field_charset,
-                                          ptr, row_length,
-                                          key, local_key_length,
-                                          insert_or_update);
-}
-
-
 uint Field_string::packed_col_length(const uchar *data_ptr, uint length)
 {
   if (length > 255)
@@ -7258,90 +7178,6 @@ uchar *Field_varstring::pack(uchar *to, 
 }
 
 
-uchar *
-Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
-                          bool low_byte_first __attribute__((unused)))
-{
-  uint length=  length_bytes == 1 ? (uint) *key : uint2korr(key);
-  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
-                     max_length/field_charset->mbmaxlen : max_length);
-  key+= length_bytes;
-  if (length > local_char_length)
-  {
-    local_char_length= my_charpos(field_charset, key, key+length,
-                                  local_char_length);
-    set_if_smaller(length, local_char_length);
-  }
-  *to++= (char) (length & 255);
-  if (max_length > 255)
-    *to++= (char) (length >> 8);
-  if (length)
-    memcpy(to, key, length);
-  return to+length;
-}
-
-
-/**
-  Unpack a key into a record buffer.
-
-  A VARCHAR key has a maximum size of 64K-1.
-  In its packed form, the length field is one or two bytes long,
-  depending on 'max_length'.
-
-  @param to                          Pointer into the record buffer.
-  @param key                         Pointer to the packed key.
-  @param max_length                  Key length limit from key description.
-
-  @return
-    Pointer to end of 'key' (To the next key part if multi-segment key)
-*/
-
-const uchar *
-Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
-                            bool low_byte_first __attribute__((unused)))
-{
-  /* get length of the blob key */
-  uint32 length= *key++;
-  if (max_length > 255)
-    length+= (*key++) << 8;
-
-  /* put the length into the record buffer */
-  if (length_bytes == 1)
-    *ptr= (uchar) length;
-  else
-    int2store(ptr, length);
-  memcpy(ptr + length_bytes, key, length);
-  return key + length;
-}
-
-/**
-  Create a packed key that will be used for storage in the index tree.
-
-  @param to		Store packed key segment here
-  @param from		Key segment (as given to index_read())
-  @param max_length  	Max length of key
-
-  @return
-    end of key storage
-*/
-
-uchar *
-Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
-                                         bool low_byte_first __attribute__((unused)))
-{
-  /* Key length is always stored as 2 bytes */
-  uint length= uint2korr(from);
-  if (length > max_length)
-    length= max_length;
-  *to++= (char) (length & 255);
-  if (max_length > 255)
-    *to++= (char) (length >> 8);
-  if (length)
-    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
-  return to+length;
-}
-
-
 /**
    Unpack a varstring field from row data.
 
@@ -7384,59 +7220,6 @@ Field_varstring::unpack(uchar *to, const
 }
 
 
-int Field_varstring::pack_cmp(const uchar *a, const uchar *b,
-                              uint key_length_arg,
-                              my_bool insert_or_update)
-{
-  uint a_length, b_length;
-  if (key_length_arg > 255)
-  {
-    a_length=uint2korr(a); a+= 2;
-    b_length=uint2korr(b); b+= 2;
-  }
-  else
-  {
-    a_length= (uint) *a++;
-    b_length= (uint) *b++;
-  }
-  return field_charset->coll->strnncollsp(field_charset,
-                                          a, a_length,
-                                          b, b_length,
-                                          insert_or_update);
-}
-
-
-int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg,
-                              my_bool insert_or_update)
-{
-  uchar *a= ptr+ length_bytes;
-  uint a_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
-  uint b_length;
-  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
-                           key_length_arg / field_charset->mbmaxlen :
-                           key_length_arg);
-
-  if (key_length_arg > 255)
-  {
-    b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
-  }
-  else
-    b_length= (uint) *b++;
-
-  if (a_length > local_char_length)
-  {
-    local_char_length= my_charpos(field_charset, a, a+a_length,
-                                  local_char_length);
-    set_if_smaller(a_length, local_char_length);
-  }
-
-  return field_charset->coll->strnncollsp(field_charset,
-                                          a, a_length,
-                                          b, b_length,
-                                          insert_or_update);
-}
-
-
 uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
 {
   if (length > 255)
@@ -8135,139 +7918,6 @@ const uchar *Field_blob::unpack(uchar *t
   DBUG_RETURN(from + master_packlength + length);
 }
 
-/* Keys for blobs are like keys on varchars */
-
-int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
-                         my_bool insert_or_update)
-{
-  uint a_length, b_length;
-  if (key_length_arg > 255)
-  {
-    a_length=uint2korr(a); a+=2;
-    b_length=uint2korr(b); b+=2;
-  }
-  else
-  {
-    a_length= (uint) *a++;
-    b_length= (uint) *b++;
-  }
-  return field_charset->coll->strnncollsp(field_charset,
-                                          a, a_length,
-                                          b, b_length,
-                                          insert_or_update);
-}
-
-
-int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
-                         my_bool insert_or_update)
-{
-  uchar *a;
-  uint a_length, b_length;
-  memcpy_fixed(&a,ptr+packlength,sizeof(char*));
-  if (!a)
-    return key_length_arg > 0 ? -1 : 0;
-
-  a_length= get_length(ptr);
-  if (key_length_arg > 255)
-  {
-    b_length= uint2korr(b); b+=2;
-  }
-  else
-    b_length= (uint) *b++;
-  return field_charset->coll->strnncollsp(field_charset,
-                                          a, a_length,
-                                          b, b_length,
-                                          insert_or_update);
-}
-
-/** Create a packed key that will be used for storage from a MySQL row. */
-
-uchar *
-Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
-                     bool low_byte_first __attribute__((unused)))
-{
-  uchar *save= ptr;
-  ptr= (uchar*) from;
-  uint32 length=get_length();        // Length of from string
-  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
-                           max_length/field_charset->mbmaxlen : max_length);
-  if (length)
-    get_ptr((uchar**) &from);
-  if (length > local_char_length)
-    local_char_length= my_charpos(field_charset, from, from+length,
-                                  local_char_length);
-  set_if_smaller(length, local_char_length);
-  *to++= (uchar) length;
-  if (max_length > 255)				// 2 byte length
-    *to++= (uchar) (length >> 8);
-  memcpy(to, from, length);
-  ptr=save;					// Restore org row pointer
-  return to+length;
-}
-
-
-/**
-  Unpack a blob key into a record buffer.
-
-  A blob key has a maximum size of 64K-1.
-  In its packed form, the length field is one or two bytes long,
-  depending on 'max_length'.
-  Depending on the maximum length of a blob, its length field is
-  put into 1 to 4 bytes. This is a property of the blob object,
-  described by 'packlength'.
-  Blobs are internally stored apart from the record buffer, which
-  contains a pointer to the blob buffer.
-
-
-  @param to                          Pointer into the record buffer.
-  @param from                        Pointer to the packed key.
-  @param max_length                  Key length limit from key description.
-
-  @return
-    Pointer into 'from' past the last byte copied from packed key.
-*/
-
-const uchar *
-Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
-                       bool low_byte_first __attribute__((unused)))
-{
-  /* get length of the blob key */
-  uint32 length= *from++;
-  if (max_length > 255)
-    length+= *from++ << 8;
-
-  /* put the length into the record buffer */
-  put_length(to, length);
-
-  /* put the address of the blob buffer or NULL */
-  if (length)
-    memcpy_fixed(to + packlength, &from, sizeof(from));
-  else
-    bzero(to + packlength, sizeof(from));
-
-  /* point to first byte of next field in 'from' */
-  return from + length;
-}
-
-
-/** Create a packed key that will be used for storage from a MySQL key. */
-
-uchar *
-Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
-                                    bool low_byte_first __attribute__((unused)))
-{
-  uint length=uint2korr(from);
-  if (length > max_length)
-    length=max_length;
-  *to++= (char) (length & 255);
-  if (max_length > 255)
-    *to++= (char) (length >> 8);
-  if (length)
-    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
-  return to+length;
-}
-
-
 uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
 {
   if (length > 255)

=== modified file 'sql/field.h'
--- a/sql/field.h	2009-11-06 14:20:27 +0000
+++ b/sql/field.h	2009-11-19 23:48:08 +0000
@@ -25,7 +25,6 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
-#define NOT_FIXED_DEC			31
 #define DATETIME_DEC                     6
 const uint32 max_field_size= (uint32) 4294967295U;
 
@@ -410,32 +409,11 @@ public:
     DBUG_RETURN(result);
   }
 
-  virtual uchar *pack_key(uchar* to, const uchar *from,
-                          uint max_length, bool low_byte_first)
-  {
-    return pack(to, from, max_length, low_byte_first);
-  }
-  virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from,
-					uint max_length, bool low_byte_first)
-  {
-    return pack(to, from, max_length, low_byte_first);
-  }
-  virtual const uchar *unpack_key(uchar* to, const uchar *from,
-                                  uint max_length, bool low_byte_first)
-  {
-    return unpack(to, from, max_length, low_byte_first);
-  }
   virtual uint packed_col_length(const uchar *to, uint length)
   { return length;}
   virtual uint max_packed_col_length(uint max_length)
   { return max_length;}
 
-  virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg,
-                       my_bool insert_or_update)
-  { return cmp(a,b); }
-  virtual int pack_cmp(const uchar *b, uint key_length_arg,
-                       my_bool insert_or_update)
-  { return cmp(ptr,b); }
   uint offset(uchar *record)
   {
     return (uint) (ptr - record);
@@ -1503,9 +1481,6 @@ public:
   int compatible_field_size(uint field_metadata,
                             const Relay_log_info *rli);
   uint row_pack_length() { return (field_length + 1); }
-  int pack_cmp(const uchar *a,const uchar *b,uint key_length,
-               my_bool insert_or_update);
-  int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update);
   uint packed_col_length(const uchar *to, uint length);
   uint max_packed_col_length(uint max_length);
   uint size_of() const { return sizeof(*this); }
@@ -1579,16 +1554,8 @@ public:
   void sql_type(String &str) const;
   virtual uchar *pack(uchar *to, const uchar *from,
                       uint max_length, bool low_byte_first);
-  uchar *pack_key(uchar *to, const uchar *from, uint max_length, bool low_byte_first);
-  uchar *pack_key_from_key_image(uchar* to, const uchar *from,
-                                 uint max_length, bool low_byte_first);
   virtual const uchar *unpack(uchar* to, const uchar *from,
                               uint param_data, bool low_byte_first);
-  const uchar *unpack_key(uchar* to, const uchar *from,
-                          uint max_length, bool low_byte_first);
-  int pack_cmp(const uchar *a, const uchar *b, uint key_length,
-               my_bool insert_or_update);
-  int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
   int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
   int key_cmp(const uchar *,const uchar*);
   int key_cmp(const uchar *str, uint length);
@@ -1764,17 +1731,8 @@ public:
   }
   virtual uchar *pack(uchar *to, const uchar *from,
                       uint max_length, bool low_byte_first);
-  uchar *pack_key(uchar *to, const uchar *from,
-                  uint max_length, bool low_byte_first);
-  uchar *pack_key_from_key_image(uchar* to, const uchar *from,
-                                 uint max_length, bool low_byte_first);
   virtual const uchar *unpack(uchar *to, const uchar *from,
                               uint param_data, bool low_byte_first);
-  const uchar *unpack_key(uchar* to, const uchar *from,
-                          uint max_length, bool low_byte_first);
-  int pack_cmp(const uchar *a, const uchar *b, uint key_length,
-               my_bool insert_or_update);
-  int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
   uint packed_col_length(const uchar *col_ptr, uint length);
   uint max_packed_col_length(uint max_length);
   void free() { value.free(); }

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2009-11-03 11:37:02 +0000
+++ b/sql/ha_partition.cc	2009-11-19 23:48:08 +0000
@@ -1980,8 +1980,7 @@ partition_element *ha_partition::find_pa
       return part_elem;
   }
   DBUG_ASSERT(0);
-  my_error(ER_OUT_OF_RESOURCES, MYF(0));
-  current_thd->fatal_error();                   // Abort
+  my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
   return NULL;
 }
 

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2009-11-03 12:48:59 +0000
+++ b/sql/item_cmpfunc.cc	2009-11-19 23:48:08 +0000
@@ -855,7 +855,8 @@ get_time_value(THD *thd, Item ***item_ar
   else
   {
     *is_null= item->get_time(&ltime);
-    value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) : 0;
+    value= !*is_null ? (longlong) TIME_to_ulonglong_datetime(&ltime) *
+                                  (ltime.neg ? -1 : 1) : 0;
   }
   /*
     Do not cache GET_USER_VAR() function as its const_item() may return TRUE

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2009-11-06 14:20:27 +0000
+++ b/sql/item_func.cc	2009-11-19 23:48:08 +0000
@@ -3474,6 +3474,48 @@ void debug_sync_point(const char* lock_n
 
 #endif
 
+
+/**
+  Wait for a given condition to be signaled within the specified timeout.
+
+  @param cond the condition variable to wait on
+  @param lock the associated mutex
+  @param abstime the amount of time in seconds to wait
+
+  @retval return value from pthread_cond_timedwait
+*/
+
+#define INTERRUPT_INTERVAL (5 * ULL(1000000000))
+
+static int interruptible_wait(THD *thd, pthread_cond_t *cond,
+                              pthread_mutex_t *lock, double time)
+{
+  int error;
+  struct timespec abstime;
+  ulonglong slice, timeout= (ulonglong) (time * 1000000000.0);
+
+  do
+  {
+    /* Wait for a fixed interval. */
+    if (timeout > INTERRUPT_INTERVAL)
+      slice= INTERRUPT_INTERVAL;
+    else
+      slice= timeout;
+
+    timeout-= slice;
+    set_timespec_nsec(abstime, slice);
+    error= pthread_cond_timedwait(cond, lock, &abstime);
+    if (error == ETIMEDOUT || error == ETIME)
+    {
+      /* Return error if timed out or connection is broken. */
+      if (!timeout || !thd->is_connected())
+        break;
+    }
+  } while (error && timeout);
+
+  return error;
+}
+
 /**
   Get a user level lock.  If the thread has an old lock this is first released.
 
@@ -3489,8 +3531,7 @@ longlong Item_func_get_lock::val_int()
 {
   DBUG_ASSERT(fixed == 1);
   String *res=args[0]->val_str(&value);
-  longlong timeout=args[1]->val_int();
-  struct timespec abstime;
+  double timeout= args[1]->val_real();
   THD *thd=current_thd;
   User_level_lock *ull;
   int error;
@@ -3554,12 +3595,11 @@ longlong Item_func_get_lock::val_int()
   thd->mysys_var->current_mutex= &LOCK_user_locks;
   thd->mysys_var->current_cond=  &ull->cond;
 
-  set_timespec(abstime,timeout);
   error= 0;
   while (ull->locked && !thd->killed)
   {
     DBUG_PRINT("info", ("waiting on lock"));
-    error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
+    error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout);
     if (error == ETIMEDOUT || error == ETIME)
     {
       DBUG_PRINT("info", ("lock wait timeout"));
@@ -3754,13 +3794,13 @@ void Item_func_benchmark::print(String *
 longlong Item_func_sleep::val_int()
 {
   THD *thd= current_thd;
-  struct timespec abstime;
   pthread_cond_t cond;
+  double timeout;
   int error;
 
   DBUG_ASSERT(fixed == 1);
 
-  double time= args[0]->val_real();
+  timeout= args[0]->val_real();
   /*
     On 64-bit OSX pthread_cond_timedwait() waits forever
     if passed abstime time has already been exceeded by 
@@ -3770,10 +3810,8 @@ longlong Item_func_sleep::val_int()
     We assume that the lines between this test and the call 
     to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
   */
-  if (time < 0.00001)
+  if (timeout < 0.00001)
     return 0;
-    
-  set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000)));
 
   pthread_cond_init(&cond, NULL);
   pthread_mutex_lock(&LOCK_user_locks);
@@ -3785,7 +3823,7 @@ longlong Item_func_sleep::val_int()
   error= 0;
   while (!thd->killed)
   {
-    error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
+    error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout);
     if (error == ETIMEDOUT || error == ETIME)
       break;
     error= 0;
@@ -3817,7 +3855,7 @@ static user_var_entry *get_variable(HASH
     uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
     if (!my_hash_inited(hash))
       return 0;
-    if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME))))
+    if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
       return 0;
     entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
       extra_size;
@@ -3955,6 +3993,8 @@ bool Item_func_set_user_var::register_fi
   @param dv             derivation for new value
   @param unsigned_arg   indiates if a value of type INT_RESULT is unsigned
 
+  @note Sets error and fatal error if allocation fails.
+
   @retval
     false   success
   @retval
@@ -3998,7 +4038,8 @@ update_hash(user_var_entry *entry, bool 
 	if (entry->value == pos)
 	  entry->value=0;
         entry->value= (char*) my_realloc(entry->value, length,
-                                         MYF(MY_ALLOW_ZERO_PTR | MY_WME));
+                                         MYF(MY_ALLOW_ZERO_PTR | MY_WME |
+                                             ME_FATALERROR));
         if (!entry->value)
 	  return 1;
       }
@@ -4035,7 +4076,6 @@ Item_func_set_user_var::update_hash(void
   if (::update_hash(entry, (null_value= args[0]->null_value),
                     ptr, length, res_type, cs, dv, unsigned_arg))
   {
-    current_thd->fatal_error();     // Probably end of memory
     null_value= 1;
     return 1;
   }
@@ -4768,11 +4808,6 @@ void Item_func_get_user_var::fix_length_
     m_cached_result_type= STRING_RESULT;
     max_length= MAX_BLOB_WIDTH;
   }
-
-  if (error)
-    thd->fatal_error();
-
-  return;
 }
 
 
@@ -4843,18 +4878,16 @@ bool Item_user_var_as_out_param::fix_fie
 
 void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
 {
-  if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
-                    DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
-    current_thd->fatal_error();			// Probably end of memory
+  ::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
+                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
 }
 
 
 void Item_user_var_as_out_param::set_value(const char *str, uint length,
                                            CHARSET_INFO* cs)
 {
-  if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
-                    DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
-    current_thd->fatal_error();			// Probably end of memory
+  ::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
+                DERIVATION_IMPLICIT, 0 /* unsigned_arg */);
 }
 
 

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2009-11-06 16:13:33 +0000
+++ b/sql/item_subselect.cc	2009-11-19 23:48:08 +0000
@@ -1740,8 +1740,6 @@ subselect_union_engine::subselect_union_
   :subselect_engine(item_arg, result_arg)
 {
   unit= u;
-  if (!result_arg)				//out of memory
-    current_thd->fatal_error();
   unit->item= item_arg;
 }
 
@@ -1753,10 +1751,7 @@ int subselect_single_select_engine::prep
   join= new JOIN(thd, select_lex->item_list,
 		 select_lex->options | SELECT_NO_UNLOCK, result);
   if (!join || !result)
-  {
-    thd->fatal_error();				//out of memory
-    return 1;
-  }
+    return 1; /* Fatal error is set already. */
   prepared= 1;
   SELECT_LEX *save_select= thd->lex->current_select;
   thd->lex->current_select= select_lex;

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2009-10-28 17:22:36 +0000
+++ b/sql/item_timefunc.cc	2009-11-19 23:48:08 +0000
@@ -865,6 +865,8 @@ static bool get_interval_info(const char
 {
   const char *end=str+length;
   uint i;
+  long msec_length= 0;
+
   while (str != end && !my_isdigit(cs,*str))
     str++;
 
@@ -874,12 +876,7 @@ static bool get_interval_info(const char
     const char *start= str;
     for (value=0; str != end && my_isdigit(cs,*str) ; str++)
       value= value*LL(10) + (longlong) (*str - '0');
-    if (transform_msec && i == count - 1) // microseconds always last
-    {
-      long msec_length= 6 - (uint) (str - start);
-      if (msec_length > 0)
-	value*= (long) log_10_int[msec_length];
-    }
+    msec_length= 6 - (str - start);
     values[i]= value;
     while (str != end && !my_isdigit(cs,*str))
       str++;
@@ -893,6 +890,10 @@ static bool get_interval_info(const char
       break;
     }
   }
+
+  if (transform_msec && msec_length > 0)
+    values[count - 1] *= (long) log_10_int[msec_length];
+
   return (str != end);
 }
 
@@ -1854,7 +1855,7 @@ longlong Item_func_sec_to_time::val_int(
   sec_to_time(arg_val, args[0]->unsigned_flag, &ltime);
 
   return (ltime.neg ? -1 : 1) *
-    ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
+    (longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
 }
 
 
@@ -2666,7 +2667,8 @@ longlong Item_time_typecast::val_int()
     null_value= 1;
     return 0;
   }
-  return ltime.hour * 10000L + ltime.minute * 100 + ltime.second;
+  return (ltime.neg ? -1 : 1) *
+    (longlong) ((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
 }
 
 String *Item_time_typecast::val_str(String *str)

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-11-10 07:31:33 +0000
+++ b/sql/mysql_priv.h	2009-11-19 23:48:08 +0000
@@ -1074,9 +1074,9 @@ inline bool check_access(THD *thd, ulong
   return false;
 }
 inline bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables,
-                               bool no_errors,
                                bool any_combination_of_privileges_will_do,
-                               uint number)
+                               uint number,
+                               bool no_errors)
 { return false; }
 #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
 

=== modified file 'sql/opt_sum.cc'
--- a/sql/opt_sum.cc	2009-10-28 10:07:30 +0000
+++ b/sql/opt_sum.cc	2009-11-10 20:31:28 +0000
@@ -175,8 +175,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
       error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
       if(error)
       {
-        tl->table->file->print_error(error, MYF(0));
-        tl->table->in_use->fatal_error();
+        tl->table->file->print_error(error, MYF(ME_FATALERROR));
         return error;
       }
       count*= tl->table->file->stats.records;
@@ -427,8 +426,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
 	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
 	      return HA_ERR_KEY_NOT_FOUND;	     // No rows matching WHERE
 	    /* HA_ERR_LOCK_DEADLOCK or some other error */
- 	    table->file->print_error(error, MYF(0));
-            table->in_use->fatal_error();
+            table->file->print_error(error, MYF(ME_FATALERROR));
             return(error);
 	  }
           removed_tables|= table->map;

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2009-10-28 17:22:36 +0000
+++ b/sql/share/errmsg.txt	2009-11-19 23:48:08 +0000
@@ -4880,6 +4880,7 @@ ER_ZLIB_Z_DATA_ERROR  
         spa "ZLIB: Dato de entrada fu�orrompido para zlib"
 ER_CUT_VALUE_GROUP_CONCAT  
         eng "Row %u was cut by GROUP_CONCAT()"
+        por "Linha %u foi cortada por GROUP_CONCAT()"
 ER_WARN_TOO_FEW_RECORDS 01000 
         eng "Row %ld doesn't contain data for all columns"
         ger "Zeile %ld enth� nicht f�e Felder Daten"

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2009-11-05 20:28:35 +0000
+++ b/sql/sp.cc	2009-11-19 23:48:08 +0000
@@ -1711,6 +1711,9 @@ sp_cache_routines_and_add_tables_aux(THD
         ret= SP_OK;
         break;
       default:
+        /* Query might have been killed, don't set error. */
+        if (thd->killed)
+          break;
         /*
           Any error when loading an existing routine is either some problem
           with the mysql.proc table, or a parse error because the contents

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2009-11-06 15:28:25 +0000
+++ b/sql/sp_head.cc	2009-11-19 23:48:08 +0000
@@ -1086,7 +1086,6 @@ sp_head::execute(THD *thd)
   Item_change_list old_change_list;
   String old_packet;
   Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
-
   Object_creation_ctx *saved_creation_ctx;
   Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id());
 
@@ -4017,10 +4016,7 @@ sp_add_to_query_tables(THD *thd, LEX *le
   TABLE_LIST *table;
 
   if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
-  {
-    thd->fatal_error();
     return NULL;
-  }
   table->db_length= strlen(db);
   table->db= thd->strmake(db, table->db_length);
   table->table_name_length= strlen(name);

=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc	2009-11-06 15:28:25 +0000

+++ b/sql/sql_cache.cc	2009-11-19 23:48:08 +0000
@@ -1331,12 +1331,12 @@ end:
   @param thd Pointer to the thread handler
   @param sql A pointer to the sql statement *
   @param query_length Length of the statement in characters
- 
+
   @return status code
-  @retval 1  Query was not cached.
-  @retval 0  The query was cached and user was sent the result.
-  @retval -1 The query was cached but we didn't have rights to use it. 
-  
+  @retval 0  Query was not cached.
+  @retval 1  The query was cached and user was sent the result.
+  @retval -1 The query was cached but we didn't have rights to use it.
+
   In case of -1, no error is sent to the client.
 
   *) The buffer must be allocated memory of size:

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-11-10 07:31:33 +0000
+++ b/sql/sql_class.h	2009-11-19 23:48:08 +0000
@@ -1982,9 +1982,15 @@ public:
     DBUG_VOID_RETURN;
   }
   inline bool vio_ok() const { return net.vio != 0; }
+  /** Return FALSE if connection to client is broken. */
+  bool is_connected()
+  {
+    return vio_ok() ? vio_is_connected(net.vio) : FALSE;
+  }
 #else
   void clear_error();
-  inline bool vio_ok() const { return true; }
+  inline bool vio_ok() const { return TRUE; }
+  inline bool is_connected() { return TRUE; }
 #endif
   /**
     Mark the current error as fatal. Warning: this does not
@@ -1993,6 +1999,7 @@ public:
   */
   inline void fatal_error()
   {
+    DBUG_ASSERT(main_da.is_error());
     is_fatal_error= 1;
     DBUG_PRINT("error",("Fatal error set"));
   }
@@ -2158,7 +2165,10 @@ public:
     else
     {
       x_free(db);
-      db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL;
+      if (new_db)
+        db= my_strndup(new_db, new_db_len, MYF(MY_WME | ME_FATALERROR));
+      else
+        db= NULL;
     }
     db_length= db ? new_db_len : 0;
     return new_db && !db;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-11-05 20:28:35 +0000
+++ b/sql/sql_insert.cc	2009-11-19 23:48:08 +0000
@@ -1922,20 +1922,17 @@ bool delayed_get_table(THD *thd, TABLE_L
     if (! (di= find_handler(thd, table_list)))
     {
       if (!(di= new Delayed_insert()))
-      {
-        thd->fatal_error();
         goto end_create;
-      }
       pthread_mutex_lock(&LOCK_thread_count);
       thread_count++;
       pthread_mutex_unlock(&LOCK_thread_count);
       di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
-      di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
+      di->thd.set_query(my_strdup(table_list->table_name,
+                                  MYF(MY_WME | ME_FATALERROR)), 0);
       if (di->thd.db == NULL || di->thd.query() == NULL)
       {
         /* The error is reported */
 	delete di;
-        thd->fatal_error();
         goto end_create;
       }
       di->table_list= *table_list;			// Needed to open table
@@ -1953,8 +1950,7 @@ bool delayed_get_table(THD *thd, TABLE_L
 	pthread_mutex_unlock(&di->mutex);
 	di->unlock();
 	delete di;
-	my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
-        thd->fatal_error();
+	my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error);
         goto end_create;
       }
 
@@ -2331,8 +2327,8 @@ static void handle_delayed_insert_impl(T
   }
   if (!(di->table->file->ha_table_flags() & HA_CAN_INSERT_DELAYED))
   {
-    thd->fatal_error();
-    my_error(ER_DELAYED_NOT_SUPPORTED, MYF(0), di->table_list.table_name);
+    my_error(ER_DELAYED_NOT_SUPPORTED, MYF(ME_FATALERROR),
+             di->table_list.table_name);
     goto err;
   }
   if (di->table->triggers)

=== modified file 'sql/sql_list.h'
--- a/sql/sql_list.h	2009-10-22 19:31:06 +0000
+++ b/sql/sql_list.h	2009-11-10 20:31:28 +0000
@@ -458,7 +458,7 @@ struct ilink
   struct ilink **prev,*next;
   static void *operator new(size_t size) throw ()
   {
-    return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE));
+    return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR));
   }
   static void operator delete(void* ptr_arg, size_t size)
   {

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-11-06 15:28:25 +0000
+++ b/sql/sql_parse.cc	2009-11-19 23:48:08 +0000
@@ -1369,54 +1369,6 @@ bool dispatch_command(enum enum_server_c
     thd->stmt_da->disable_status();              // Don't send anything back
     error=TRUE;					// End server
     break;
-
-#ifdef REMOVED
-  case COM_CREATE_DB:				// QQ: To be removed
-    {
-      LEX_STRING db, alias;
-      HA_CREATE_INFO create_info;
-
-      status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
-      if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
-          thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
-          check_db_name(&db))
-      {
-	my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
-	break;
-      }
-      if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
-                       is_schema_db(db.str)))
-	break;
-      general_log_print(thd, command, "%.*s", db.length, db.str);
-      bzero(&create_info, sizeof(create_info));
-      mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
-                      &create_info, 0);
-      break;
-    }
-  case COM_DROP_DB:				// QQ: To be removed
-    {
-      status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
-      LEX_STRING db;
-
-      if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
-          check_db_name(&db))
-      {
-	my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
-	break;
-      }
-      if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
-	break;
-      if (thd->locked_tables || thd->active_transaction())
-      {
-	my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-                   ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-	break;
-      }
-      general_log_write(thd, command, "%.*s", db.length, db.str);
-      mysql_rm_db(thd, db.str, 0, 0);
-      break;
-    }
-#endif
 #ifndef EMBEDDED_LIBRARY
   case COM_BINLOG_DUMP:
     {
@@ -2073,7 +2025,6 @@ mysql_execute_command(THD *thd)
     A better approach would be to reset this for any commands
     that is not a SHOW command or a select that only access local
     variables, but for now this is probably good enough.
-    Don't reset warnings when executing a stored routine.
   */
   if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0)
     thd->warning_info->set_read_only(TRUE);
@@ -2276,7 +2227,7 @@ mysql_execute_command(THD *thd)
                               privileges_requested,
                               all_tables, FALSE, UINT_MAX, FALSE);
     else
-      res= check_access(thd, privileges_requested, any_db, 0, 0, 0, UINT_MAX);
+      res= check_access(thd, privileges_requested, any_db, 0, 0, 0, 0);
 
     if (res)
       break;
@@ -5830,7 +5781,6 @@ bool check_stack_overrun(THD *thd, long 
     my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
                 stack_used, my_thread_stack_size, margin);
     my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
-    thd->fatal_error();
     return 1;
   }
 #ifndef DBUG_OFF
@@ -6494,13 +6444,17 @@ TABLE_LIST *st_select_lex::add_table_to_
     DBUG_RETURN(0);				/* purecov: inspected */
   if (table->db.str)
   {
+    ptr->is_fqtn= TRUE;
     ptr->db= table->db.str;
     ptr->db_length= table->db.length;
   }
   else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
     DBUG_RETURN(0);
+  else
+    ptr->is_fqtn= FALSE;
 
   ptr->alias= alias_str;
+  ptr->is_alias= alias ? TRUE : FALSE;
   if (lower_case_table_names && table->table.length)
     table->table.length= my_casedn_str(files_charset_info, table->table.str);
   ptr->table_name=table->table.str;
@@ -7547,6 +7501,63 @@ bool multi_delete_precheck(THD *thd, TAB
 }
 
 
+/*
+  Given a table in the source list, find a correspondent table in the
+  table references list.
+
+  @param lex Pointer to LEX representing multi-delete.
+  @param src Source table to match.
+  @param ref Table references list.
+
+  @remark The source table list (tables listed before the FROM clause
+  or tables listed in the FROM clause before the USING clause) may
+  contain table names or aliases that must match unambiguously one,
+  and only one, table in the target table list (table references list,
+  after FROM/USING clause).
+
+  @return Matching table, NULL otherwise.
+*/
+
+static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
+                                            TABLE_LIST *tables)
+{
+  TABLE_LIST *match= NULL;
+  DBUG_ENTER("multi_delete_table_match");
+
+  for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
+  {
+    int cmp;
+
+    if (tbl->is_fqtn && elem->is_alias)
+      continue; /* no match */
+    if (tbl->is_fqtn && elem->is_fqtn)
+      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
+           strcmp(tbl->db, elem->db);
+    else if (elem->is_alias)
+      cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
+    else
+      cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
+           strcmp(tbl->db, elem->db);
+
+    if (cmp)
+      continue;
+
+    if (match)
+    {
+      my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
+      DBUG_RETURN(NULL);
+    }
+
+    match= elem;
+  }
+
+  if (!match)
+    my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
+
+  DBUG_RETURN(match);
+}
+
+
 /**
   Link tables in auxilary table list of multi-delete with corresponding
   elements in main table list, and set proper locks for them.
@@ -7572,20 +7583,9 @@ bool multi_delete_set_locks_and_link_aux
   {
     lex->table_count++;
     /* All tables in aux_tables must be found in FROM PART */
-    TABLE_LIST *walk;
-    for (walk= tables; walk; walk= walk->next_local)
-    {
-      if (!my_strcasecmp(table_alias_charset,
-			 target_tbl->alias, walk->alias) &&
-	  !strcmp(walk->db, target_tbl->db))
-	break;
-    }
+    TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
     if (!walk)
-    {
-      my_error(ER_UNKNOWN_TABLE, MYF(0),
-               target_tbl->table_name, "MULTI DELETE");
       DBUG_RETURN(TRUE);
-    }
     if (!walk->derived)
     {
       target_tbl->table_name= walk->table_name;

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2009-11-05 20:28:35 +0000
+++ b/sql/sql_partition.cc	2009-11-19 23:48:08 +0000
@@ -2407,8 +2407,7 @@ char *generate_partition_syntax(partitio
     default:
       DBUG_ASSERT(0);
       /* We really shouldn't get here, no use in continuing from here */
-      my_error(ER_OUT_OF_RESOURCES, MYF(0));
-      current_thd->fatal_error();
+      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
       DBUG_RETURN(NULL);
   }
   if (part_info->part_expr)
@@ -5483,10 +5482,7 @@ static bool mysql_change_partitions(ALTE
                                          &lpt->deleted, lpt->pack_frm_data,
                                          lpt->pack_frm_len)))
   {
-    if (error != ER_OUTOFMEMORY)
-      file->print_error(error, MYF(0));
-    else
-      lpt->thd->fatal_error();
+    file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR));
     DBUG_RETURN(TRUE);
   }
   DBUG_RETURN(FALSE);

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2009-11-10 07:31:33 +0000

+++ b/sql/sql_select.cc	2009-11-19 23:48:08 +0000
@@ -9708,7 +9708,7 @@ Field *create_tmp_field(THD *thd, TABLE 
     Item_sum *item_sum=(Item_sum*) item;
     result= item_sum->create_tmp_field(group, table, convert_blob_length);
     if (!result)
-      thd->fatal_error();
+      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
     return result;
   }
   case Item::FIELD_ITEM:
@@ -10852,8 +10852,7 @@ bool create_myisam_from_heap(THD *thd, T
       We don't want this error to be converted to a warning, e.g. in case of
       INSERT IGNORE ... SELECT.
     */
-    thd->fatal_error();
-    table->file->print_error(error,MYF(0));
+    table->file->print_error(error, MYF(ME_FATALERROR));
     DBUG_RETURN(1);
   }
 
@@ -15059,8 +15058,7 @@ calc_group_buffer(JOIN *join,ORDER *grou
       default:
         /* This case should never be choosen */
         DBUG_ASSERT(0);
-        my_error(ER_OUT_OF_RESOURCES, MYF(0));
-        join->thd->fatal_error();
+        my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
       }
     }
     parts++;

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2009-10-14 16:37:38 +0000
+++ b/sql/sql_servers.cc	2009-11-10 20:31:28 +0000
@@ -128,7 +128,7 @@ bool servers_init(bool dont_read_servers
   }
 
   /* Initialize the mem root for data */
-  init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
+  init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
 
   if (dont_read_servers_table)
     goto end;
@@ -180,7 +180,7 @@ static bool servers_load(THD *thd, TABLE
 
   my_hash_reset(&servers_cache);
   free_root(&mem, MYF(0));
-  init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
+  init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
 
   init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, 
                    FALSE);

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-11-10 09:32:29 +0000
+++ b/sql/sql_show.cc	2009-11-19 23:48:08 +0000
@@ -1705,6 +1705,32 @@ public:
 template class I_List<thread_info>;
 #endif
 
+static const char *thread_state_info(THD *tmp)
+{
+  if (tmp->locked)
+    return "Locked";
+#ifndef EMBEDDED_LIBRARY
+  if (tmp->net.reading_or_writing)
+  {
+    if (tmp->net.reading_or_writing == 2)
+      return "Writing to net";
+    else if (tmp->command == COM_SLEEP)
+      return "";
+    else
+      return "Reading from net";
+  }
+  else
+#endif
+  {
+    if (tmp->proc_info)
+      return tmp->proc_info;
+    else if (tmp->mysys_var && tmp->mysys_var->current_cond)
+      return "Waiting on cond";
+    else
+      return NULL;
+  }
+}
+
 void mysqld_list_processes(THD *thd,const char *user, bool verbose)
 {
   Item *field;
@@ -1766,20 +1792,7 @@ void mysqld_list_processes(THD *thd,cons
         if ((mysys_var= tmp->mysys_var))
           pthread_mutex_lock(&mysys_var->mutex);
         thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
-#ifndef EMBEDDED_LIBRARY
-        thd_info->state_info= (char*) (tmp->locked ? "Locked" :

-                                       tmp->net.reading_or_writing ?
-                                       (tmp->net.reading_or_writing == 2 ?
-                                        "Writing to net" :
-                                        thd_info->command == COM_SLEEP ? "" :
-                                        "Reading from net") :
-                                       tmp->proc_info ? tmp->proc_info :
-                                       tmp->mysys_var &&
-                                       tmp->mysys_var->current_cond ?
-                                       "Waiting on cond" : NullS);
-#else
-        thd_info->state_info= (char*)"Writing to net";
-#endif
+        thd_info->state_info= thread_state_info(tmp);
         if (mysys_var)
           pthread_mutex_unlock(&mysys_var->mutex);
 
@@ -1891,21 +1904,7 @@ int fill_schema_processlist(THD* thd, TA
       table->field[5]->store((longlong)(tmp->start_time ?
                                       now - tmp->start_time : 0), FALSE);
       /* STATE */
-#ifndef EMBEDDED_LIBRARY
-      val= (char*) (tmp->locked ? "Locked" :
-                    tmp->net.reading_or_writing ?
-                    (tmp->net.reading_or_writing == 2 ?
-                     "Writing to net" :
-                     tmp->command == COM_SLEEP ? "" :
-                     "Reading from net") :
-                    tmp->proc_info ? tmp->proc_info :
-                    tmp->mysys_var &&
-                    tmp->mysys_var->current_cond ?
-                    "Waiting on cond" : NullS);
-#else
-      val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
-#endif
-      if (val)
+      if ((val= thread_state_info(tmp)))
       {
         table->field[6]->store(val, strlen(val), cs);
         table->field[6]->set_notnull();
@@ -5071,8 +5070,7 @@ static int get_schema_partitions_record(
       break;
     default:
       DBUG_ASSERT(0);
-      my_error(ER_OUT_OF_RESOURCES, MYF(0));
-      current_thd->fatal_error();
+      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
       DBUG_RETURN(1);
     }
     table->field[7]->set_notnull();

=== modified file 'sql/sql_string.cc'
--- a/sql/sql_string.cc	2009-09-30 05:09:28 +0000
+++ b/sql/sql_string.cc	2009-11-11 20:19:41 +0000
@@ -23,6 +23,7 @@
 #include <my_sys.h>
 #include <m_string.h>
 #include <m_ctype.h>
+#include <mysql_com.h>
 #ifdef HAVE_FCONVERT
 #include <floatingpoint.h>
 #endif
@@ -499,22 +500,6 @@ bool String::append(const char *s,uint32
   return FALSE;
 }
 
-
-#ifdef TO_BE_REMOVED
-bool String::append(FILE* file, uint32 arg_length, myf my_flags)
-{
-  if (realloc(str_length+arg_length))
-    return TRUE;
-  if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags))
-  {
-    shrink(str_length);
-    return TRUE;
-  }
-  str_length+=arg_length;
-  return FALSE;
-}
-#endif
-
 bool String::append(IO_CACHE* file, uint32 arg_length)
 {
   if (realloc(str_length+arg_length))

=== modified file 'sql/sql_string.h'
--- a/sql/sql_string.h	2009-10-28 07:55:44 +0000
+++ b/sql/sql_string.h	2009-11-11 20:19:41 +0000
@@ -22,10 +22,6 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
-#ifndef NOT_FIXED_DEC
-#define NOT_FIXED_DEC			31
-#endif
-
 class String;
 int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
 String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2009-11-05 20:28:35 +0000
+++ b/sql/sql_trigger.cc	2009-11-19 23:48:08 +0000
@@ -1660,7 +1660,7 @@ bool Table_triggers_list::drop_all_trigg
   DBUG_ENTER("drop_all_triggers");
 
   bzero(&table, sizeof(table));
-  init_alloc_root(&table.mem_root, 8192, 0);
+  init_sql_alloc(&table.mem_root, 8192, 0);
 
   if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
   {
@@ -1871,7 +1871,7 @@ bool Table_triggers_list::change_table_n
   DBUG_ENTER("change_table_name");
 
   bzero(&table, sizeof(table));
-  init_alloc_root(&table.mem_root, 8192, 0);
+  init_sql_alloc(&table.mem_root, 8192, 0);
 
   /*
     This method interfaces the mysql server code protected by

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2009-11-06 14:20:27 +0000
+++ b/sql/sql_update.cc	2009-11-19 23:48:08 +0000
@@ -662,11 +662,13 @@ int mysql_update(THD *thd,
             If (ignore && error is ignorable) we don't have to
             do anything; otherwise...
           */
+          myf flags= 0;
+
           if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
-            thd->fatal_error(); /* Other handler errors are fatal */
+            flags|= ME_FATALERROR; /* Other handler errors are fatal */
 
           prepare_record_for_error_message(error, table);
-	  table->file->print_error(error,MYF(0));
+	  table->file->print_error(error,MYF(flags));
 	  error= 1;
 	  break;
 	}
@@ -763,9 +765,8 @@ int mysql_update(THD *thd,
     */
   {
     /* purecov: begin inspected */
-    thd->fatal_error();
     prepare_record_for_error_message(loc_error, table);
-    table->file->print_error(loc_error,MYF(0));
+    table->file->print_error(loc_error,MYF(ME_FATALERROR));
     error= 1;
     /* purecov: end */
   }
@@ -1742,11 +1743,13 @@ bool multi_update::send_data(List<Item> 
               If (ignore && error == is ignorable) we don't have to
               do anything; otherwise...
             */
+            myf flags= 0;
+
             if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
-              thd->fatal_error(); /* Other handler errors are fatal */
+              flags|= ME_FATALERROR; /* Other handler errors are fatal */
 
             prepare_record_for_error_message(error, table);
-            table->file->print_error(error,MYF(0));
+            table->file->print_error(error,MYF(flags));
             DBUG_RETURN(1);
           }
         }
@@ -2029,9 +2032,8 @@ int multi_update::do_updates()
 
 err:
   {
-    thd->fatal_error();
     prepare_record_for_error_message(local_error, table);
-    table->file->print_error(local_error,MYF(0));
+    table->file->print_error(local_error,MYF(ME_FATALERROR));
   }
 
 err2:

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2009-11-06 14:20:27 +0000
+++ b/sql/sql_yacc.yy	2009-11-19 23:48:08 +0000
@@ -1190,7 +1190,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %type <item>
         literal text_literal insert_ident order_ident
-        simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
+        simple_ident expr opt_expr opt_else sum_expr in_sum_expr
         variable variable_aux bool_pri
         predicate bit_expr
         table_wild simple_expr udf_expr
@@ -1350,7 +1350,7 @@ END_OF_INPUT
 %type <NONE>
         '-' '+' '*' '/' '%' '(' ')'
         ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
-        THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM
+        THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
 %%
 
 /*
@@ -6946,7 +6946,14 @@ select_item_list:
         ;
 
 select_item:
-          remember_name select_item2 remember_end select_alias
+          remember_name table_wild remember_end
+          {
+            THD *thd= YYTHD;
+
+            if (add_item_to_list(thd, $2))
+              MYSQL_YYABORT;
+          }
+        | remember_name expr remember_end select_alias
           {
             THD *thd= YYTHD;
             DBUG_ASSERT($1 < $3);
@@ -6983,11 +6990,6 @@ remember_end:
           }
         ;
 
-select_item2:
-          table_wild { $$=$1; /* table.* */ }
-        | expr { $$=$1; }
-        ;
-
 select_alias:
           /* empty */ { $$=null_lex_str;}
         | AS ident { $$=$2; }
@@ -10048,7 +10050,7 @@ delete:
             lex->ignore= 0;
             lex->select_lex.init_order();
           }
-          opt_delete_options single_multi {}
+          opt_delete_options single_multi
         ;
 
 single_multi:
@@ -10063,45 +10065,45 @@ single_multi:
         | table_wild_list
           { mysql_init_multi_delete(Lex); }
           FROM join_table_list where_clause
-          { 
+          {
             if (multi_delete_set_locks_and_link_aux_tables(Lex))
               MYSQL_YYABORT;
           }
         | FROM table_alias_ref_list
           { mysql_init_multi_delete(Lex); }
           USING join_table_list where_clause
-          { 
+          {
             if (multi_delete_set_locks_and_link_aux_tables(Lex))
               MYSQL_YYABORT;
           }
         ;
 
 table_wild_list:
-          table_wild_one {}
-        | table_wild_list ',' table_wild_one {}
+          table_wild_one
+        | table_wild_list ',' table_wild_one
         ;
 
 table_wild_one:
-          ident opt_wild opt_table_alias
+          ident opt_wild
           {
             Table_ident *ti= new Table_ident($1);
             if (ti == NULL)
               MYSQL_YYABORT;
             if (!Select->add_table_to_list(YYTHD,
                                            ti,
-                                           $3,
+                                           NULL,
                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
                                            Lex->lock_option))
               MYSQL_YYABORT;
           }
-        | ident '.' ident opt_wild opt_table_alias
+        | ident '.' ident opt_wild
           {
             Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
             if (ti == NULL)
               MYSQL_YYABORT;
             if (!Select->add_table_to_list(YYTHD,
                                            ti,
-                                           $5, 
+                                           NULL,
                                            TL_OPTION_UPDATING | TL_OPTION_ALIAS,
                                            Lex->lock_option))
               MYSQL_YYABORT;

=== modified file 'sql/table.h'
--- a/sql/table.h	2009-11-02 11:10:04 +0000
+++ b/sql/table.h	2009-11-10 18:48:46 +0000
@@ -1332,6 +1332,12 @@ struct TABLE_LIST
   */
   bool          create;
   bool          internal_tmp_table;
+  /** TRUE if an alias for this table was specified in the SQL. */
+  bool          is_alias;
+  /** TRUE if the table is referred to in the statement using a fully
+      qualified name (<db_name>.<table_name>).
+  */
+  bool          is_fqtn;
 
 
   /* View creation context. */

=== modified file 'sql/tztime.cc'
--- a/sql/tztime.cc	2009-10-14 16:37:38 +0000
+++ b/sql/tztime.cc	2009-11-10 20:31:28 +0000
@@ -1594,7 +1594,7 @@ my_tz_init(THD *org_thd, const char *def
     my_hash_free(&tz_names);
     goto end;
   }
-  init_alloc_root(&tz_storage, 32 * 1024, 0);
+  init_sql_alloc(&tz_storage, 32 * 1024, 0);
   VOID(pthread_mutex_init(&tz_LOCK, MY_MUTEX_INIT_FAST));
   tz_inited= 1;
 

=== modified file 'storage/ndb/include/kernel/signaldata/DictTabInfo.hpp'
--- a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2007-04-26 11:50:04 +0000
+++ b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp	2008-03-05 14:27:35 +0000
@@ -30,10 +30,6 @@
 
 #define DECIMAL_MAX_LENGTH ((8 * 9) - 8)
 
-#ifndef NOT_FIXED_DEC
-#define NOT_FIXED_DEC                   31
-#endif
-
 C_MODE_START
 extern int decimal_bin_size(int, int);
 C_MODE_END

=== modified file 'strings/ctype-bin.c'
--- a/strings/ctype-bin.c	2007-06-05 22:22:35 +0000
+++ b/strings/ctype-bin.c	2009-11-11 16:03:02 +0000
@@ -278,14 +278,11 @@ void my_hash_sort_8bit_bin(CHARSET_INFO 
 {
   const uchar *pos = key;
   
-  key+= len;
-  
   /*
      Remove trailing spaces. We have to do this to be able to compare
     'A ' and 'A' as identical
   */
-  while (key > pos && key[-1] == ' ')
-    key--;
+  key= skip_trailing_space(key, len);
 
   for (; pos < (uchar*) key ; pos++)
   {

=== modified file 'strings/ctype-latin1.c'
--- a/strings/ctype-latin1.c	2007-05-10 09:59:39 +0000
+++ b/strings/ctype-latin1.c	2009-11-11 16:03:02 +0000
@@ -678,13 +678,12 @@ void my_hash_sort_latin1_de(CHARSET_INFO
 			    const uchar *key, size_t len,
 			    ulong *nr1, ulong *nr2)
 {
-  const uchar *end= key+len;
+  const uchar *end;
   /*
     Remove end space. We have to do this to be able to compare
     'AE' and '� as identical
   */
-  while (end > key && end[-1] == ' ')
-    end--;
+  end= skip_trailing_space(key, len);
 
   for (; key < end ; key++)
   {

=== modified file 'strings/ctype-mb.c'
--- a/strings/ctype-mb.c	2009-02-13 16:41:47 +0000
+++ b/strings/ctype-mb.c	2009-11-11 16:03:02 +0000
@@ -469,14 +469,11 @@ static void my_hash_sort_mb_bin(CHARSET_
 {
   const uchar *pos = key;
   
-  key+= len;
-  
   /*
      Remove trailing spaces. We have to do this to be able to compare
     'A ' and 'A' as identical
   */
-  while (key > pos && key[-1] == ' ')
-    key--;
+  key= skip_trailing_space(key, len);
   
   for (; pos < (uchar*) key ; pos++)
   {

=== modified file 'strings/ctype-simple.c'
--- a/strings/ctype-simple.c	2009-10-12 07:43:15 +0000
+++ b/strings/ctype-simple.c	2009-11-11 16:03:02 +0000
@@ -304,14 +304,13 @@ void my_hash_sort_simple(CHARSET_INFO *c
 			 ulong *nr1, ulong *nr2)
 {
   register uchar *sort_order=cs->sort_order;
-  const uchar *end= key + len;
+  const uchar *end;
   
   /*
     Remove end space. We have to do this to be able to compare
     'A ' and 'A' as identical
   */
-  while (end > key && end[-1] == ' ')
-    end--;
+  end= skip_trailing_space(key, len);
   
   for (; key < (uchar*) end ; key++)
   {
@@ -1165,9 +1164,8 @@ size_t my_well_formed_len_8bit(CHARSET_I
 size_t my_lengthsp_8bit(CHARSET_INFO *cs __attribute__((unused)),
                         const char *ptr, size_t length)
 {
-  const char *end= ptr+length;
-  while (end > ptr && end[-1] == ' ')
-    end--;
+  const char *end;
+  end= (const char *) skip_trailing_space((const uchar *)ptr, length);
   return (size_t) (end-ptr);
 }
 

=== modified file 'vio/vio.c'
--- a/vio/vio.c	2009-11-02 22:19:58 +0000
+++ b/vio/vio.c	2009-11-19 23:48:08 +0000
@@ -22,6 +22,28 @@
 
 #include "vio_priv.h"
 
+#if defined(__WIN__) || defined(HAVE_SMEM)
+
+/**
+  Stub poll_read method that defaults to indicate that there
+  is data to read.
+
+  Used for named pipe and shared memory VIO types.
+
+  @param vio      Unused.
+  @param timeout  Unused.
+
+  @retval FALSE   There is data to read.
+*/
+
+static my_bool no_poll_read(Vio *vio __attribute__((unused)),
+                            uint timeout __attribute__((unused)))
+{
+  return FALSE;
+}
+
+#endif
+
 /*
  * Helper to fill most of the Vio* with defaults.
  */
@@ -60,6 +82,9 @@ static void vio_init(Vio* vio, enum enum
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
 
+    vio->poll_read      =no_poll_read;
+    vio->is_connected   =vio_is_connected_pipe;
+
     vio->timeout=vio_win32_timeout;
     /* Set default timeout */
     vio->read_timeout_millis = INFINITE;
@@ -87,6 +112,9 @@ static void vio_init(Vio* vio, enum enum
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
 
+    vio->poll_read      =no_poll_read;
+    vio->is_connected   =vio_is_connected_shared_memory;
+
     /* Currently, shared memory is on Windows only, hence the below is ok*/
     vio->timeout= vio_win32_timeout; 
     /* Set default timeout */
@@ -112,6 +140,8 @@ static void vio_init(Vio* vio, enum enum
     vio->vioblocking	=vio_ssl_blocking;
     vio->is_blocking	=vio_is_blocking;
     vio->timeout	=vio_timeout;
+    vio->poll_read      =vio_poll_read;
+    vio->is_connected   =vio_is_connected;
     DBUG_VOID_RETURN;
   }
 #endif /* HAVE_OPENSSL */
@@ -130,6 +160,8 @@ static void vio_init(Vio* vio, enum enum
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
     vio->timeout	=vio_timeout;
+    vio->poll_read      =vio_poll_read;
+    vio->is_connected   =vio_is_connected;
   }
   DBUG_VOID_RETURN;
 }

=== modified file 'vio/vio_priv.h'
--- a/vio/vio_priv.h	2009-11-06 14:20:27 +0000
+++ b/vio/vio_priv.h	2009-11-19 23:48:08 +0000
@@ -29,6 +29,20 @@
 void	vio_win32_timeout(Vio *vio, uint which, uint timeout);
 #endif
 
+#ifdef __WIN__
+size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
+size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
+my_bool vio_is_connected_pipe(Vio *vio);
+int vio_close_pipe(Vio * vio);
+#endif
+
+#ifdef HAVE_SMEM
+size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
+size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
+my_bool vio_is_connected_shared_memory(Vio *vio);
+int vio_close_shared_memory(Vio * vio);
+#endif
+
 void	vio_timeout(Vio *vio,uint which, uint timeout);
 
 #ifdef HAVE_OPENSSL

=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c	2009-11-06 14:20:27 +0000
+++ b/vio/viosocket.c	2009-11-19 23:48:08 +0000
@@ -350,25 +350,160 @@ void vio_in_addr(Vio *vio, struct in_add
 }
 
 
-/* Return 0 if there is data to be read */
+/**
+  Indicate whether there is data to read on a given socket.
+
+  @note An exceptional condition event and/or errors are
+        interpreted as if there is data to read.
+
+  @param sd       A connected socket.
+  @param timeout  Maximum time in seconds to poll.
+
+  @retval FALSE   There is data to read.
+  @retval TRUE    There is no data to read.
+*/
 
-my_bool vio_poll_read(Vio *vio,uint timeout)
+static my_bool socket_poll_read(my_socket sd, uint timeout)
 {
-#ifndef HAVE_POLL
-  return 0;
-#else
+#ifdef __WIN__
+  int res;
+  my_socket fd= sd;
+  fd_set readfds, errorfds;
+  struct timeval tm;
+  DBUG_ENTER("socket_poll_read");
+  tm.tv_sec= timeout;
+  tm.tv_usec= 0;
+  FD_ZERO(&readfds);
+  FD_ZERO(&errorfds);
+  FD_SET(fd, &readfds);
+  FD_SET(fd, &errorfds);
+  if ((res= select(fd, &readfds, NULL, &errorfds, &tm) <= 0))
+  {
+    DBUG_RETURN(res < 0 ? 0 : 1);
+  }
+  res= FD_ISSET(fd, &readfds) || FD_ISSET(fd, &errorfds);
+  DBUG_RETURN(!res);
+#elif defined(HAVE_POLL)
   struct pollfd fds;
   int res;
-  DBUG_ENTER("vio_poll");
-  fds.fd=vio->sd;
+  DBUG_ENTER("socket_poll_read");
+  fds.fd=sd;
   fds.events=POLLIN;
   fds.revents=0;
   if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
   {
     DBUG_RETURN(res < 0 ? 0 : 1);		/* Don't return 1 on errors */
   }
-  DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+  DBUG_RETURN(fds.revents & (POLLIN | POLLERR | POLLHUP) ? 0 : 1);
+#else
+  return 0;
+#endif
+}
+
+
+/**
+  Retrieve the amount of data that can be read from a socket.
+
+  @param vio          A VIO object.
+  @param bytes[out]   The amount of bytes available.
+
+  @retval FALSE   Success.
+  @retval TRUE    Failure.
+*/
+
+static my_bool socket_peek_read(Vio *vio, uint *bytes)
+{
+#ifdef __WIN__
+  int len;
+  if (ioctlsocket(vio->sd, FIONREAD, &len))
+    return TRUE;
+  *bytes= len;
+  return FALSE;
+#elif FIONREAD_IN_SYS_IOCTL
+  int len;
+  if (ioctl(vio->sd, FIONREAD, &len) < 0)
+    return TRUE;
+  *bytes= len;
+  return FALSE;
+#else
+  char buf[1024];
+  ssize_t res= recv(vio->sd, &buf, sizeof(buf), MSG_PEEK);
+  if (res < 0)
+    return TRUE;
+  *bytes= res;
+  return FALSE;
+#endif
+}
+
+
+/**
+  Indicate whether there is data to read on a given socket.
+
+  @remark Errors are interpreted as if there is data to read.
+
+  @param sd       A connected socket.
+  @param timeout  Maximum time in seconds to wait.
+
+  @retval FALSE   There is data (or EOF) to read. Also FALSE if error.
+  @retval TRUE    There is _NO_ data to read or timed out.
+*/
+
+my_bool vio_poll_read(Vio *vio, uint timeout)
+{
+  my_socket sd= vio->sd;
+  DBUG_ENTER("vio_poll_read");
+#ifdef HAVE_OPENSSL
+  if (vio->type == VIO_TYPE_SSL)
+    sd= SSL_get_fd((SSL*) vio->ssl_arg);
+#endif
+  DBUG_RETURN(socket_poll_read(sd, timeout));
+}
+
+
+/**
+  Determine if the endpoint of a connection is still available.
+
+  @remark The socket is assumed to be disconnected if an EOF
+          condition is encountered.
+
+  @param vio      The VIO object.
+
+  @retval TRUE    EOF condition not found.
+  @retval FALSE   EOF condition is signaled.
+*/
+
+my_bool vio_is_connected(Vio *vio)
+{
+  uint bytes= 0;
+  DBUG_ENTER("vio_is_connected");
+
+  /* In the presence of errors the socket is assumed to be connected. */
+
+  /*
+    The first step of detecting a EOF condition is veryfing
+    whether there is data to read. Data in this case would
+    be the EOF.
+  */
+  if (vio_poll_read(vio, 0))
+    DBUG_RETURN(TRUE);
+
+  /*
+    The second step is read() or recv() from the socket returning
+    0 (EOF). Unfortunelly, it's not possible to call read directly
+    as we could inadvertently read meaningful connection data.
+    Simulate a read by retrieving the number of bytes available to
+    read -- 0 meaning EOF.
+  */
+  if (socket_peek_read(vio, &bytes))
+    DBUG_RETURN(TRUE);
+
+#ifdef HAVE_OPENSSL
+  /* There might be buffered data at the SSL layer. */
+  if (!bytes && vio->type == VIO_TYPE_SSL)
+    bytes= SSL_pending((SSL*) vio->ssl_arg);
 #endif
+
+  DBUG_RETURN(bytes ? TRUE : FALSE);
 }
 
 
@@ -494,6 +629,15 @@ size_t vio_write_pipe(Vio * vio, const u
 }
 
 
+my_bool vio_is_connected_pipe(Vio *vio)
+{
+  if (PeekNamedPipe(vio->hPipe, NULL, 0, NULL, NULL, NULL))
+    return TRUE;
+  else
+    return (GetLastError() != ERROR_BROKEN_PIPE);
+}
+
+
 int vio_close_pipe(Vio * vio)
 {
   int r;
@@ -644,6 +788,12 @@ size_t vio_write_shared_memory(Vio * vio
 }
 
 
+my_bool vio_is_connected_shared_memory(Vio *vio)
+{
+  return (WaitForSingleObject(vio->event_conn_closed, 0) != WAIT_OBJECT_0);
+}
+
+
 /**
  Close shared memory and DBUG_PRINT any errors that happen on closing.
  @return Zero if all closing functions succeed, and nonzero otherwise.

Attachment: [text/bzr-bundle] bzr/davi.arnaut@sun.com-20091119234808-xbjpkwaxjt5x5c0b.bundle
Thread
bzr push into mysql-5.6-next-mr branch (kostja:2922 to 2923)Konstantin Osipov20 Nov