List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:July 22 2008 2:42pm
Subject:bzr commit into mysql-5.1 branch (serg:2672)
View as plain text  
#At file:///usr/home/serg/Abk/mysql/5.1/

 2672 Sergei Golubchik	2008-07-22 [merge]
      merge
added:
  mysql-test/r/parser_stack.result
  mysql-test/t/parser_stack.test
modified:
  client/mysql.cc
  client/mysqltest.c
  mysql-test/include/mix1.inc
  mysql-test/include/query_prealloc_size_basic.inc
  mysql-test/r/client_xml.result
  mysql-test/r/func_in.result
  mysql-test/r/innodb_mysql.result
  mysql-test/r/mysql.result
  mysql-test/r/mysqltest.result
  mysql-test/r/query_prealloc_size_basic_32.result
  mysql-test/r/query_prealloc_size_basic_64.result
  mysql-test/suite/rpl/r/rpl_server_id1.result
  mysql-test/suite/rpl/r/rpl_temporary.result
  mysql-test/suite/rpl/t/disabled.def
  mysql-test/suite/rpl/t/rpl_server_id1.test
  mysql-test/suite/rpl/t/rpl_temporary.test
  mysql-test/t/client_xml.test
  mysql-test/t/disabled.def
  mysql-test/t/func_in.test
  mysql-test/t/mysql_delimiter.sql
  mysql-test/t/mysqltest.test
  sql/event_data_objects.cc
  sql/event_db_repository.cc
  sql/events.cc
  sql/filesort.cc
  sql/item_cmpfunc.cc
  sql/log.cc
  sql/mysql_priv.h
  sql/opt_range.cc
  sql/opt_range.h
  sql/records.cc
  sql/sp.cc
  sql/sp_head.cc
  sql/sql_acl.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_delete.cc
  sql/sql_help.cc
  sql/sql_lex.cc
  sql/sql_lex.h
  sql/sql_parse.cc
  sql/sql_partition.cc
  sql/sql_plugin.cc
  sql/sql_prepare.cc
  sql/sql_select.cc
  sql/sql_servers.cc
  sql/sql_table.cc
  sql/sql_trigger.cc
  sql/sql_udf.cc
  sql/sql_update.cc
  sql/sql_view.cc
  sql/sql_yacc.yy

=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2008-06-26 16:46:45 +0000
+++ b/client/mysql.cc	2008-07-22 10:56:36 +0000
@@ -2101,6 +2101,37 @@ static bool add_line(String &buffer,char
 	continue;
       }
     }
+    else if (!*ml_comment && !*in_string &&
+             (end_of_line - pos) >= 10 &&
+             !my_strnncoll(charset_info, (uchar*) pos, 10,
+                           (const uchar*) "delimiter ", 10))
+    {
+      // Flush previously accepted characters
+      if (out != line)
+      {
+        buffer.append(line, (uint32) (out - line));
+        out= line;
+      }
+
+      // Flush possible comments in the buffer
+      if (!buffer.is_empty())
+      {
+        if (com_go(&buffer, 0) > 0) // < 0 is not fatal
+          DBUG_RETURN(1);
+        buffer.length(0);
+      }
+
+      /*
+        Delimiter wants the get rest of the given line as argument to
+        allow one to change ';' to ';;' and back
+      */
+      buffer.append(pos);
+      if (com_delimiter(&buffer, pos) > 0)
+        DBUG_RETURN(1);
+
+      buffer.length(0);
+      break;
+    }
     else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
     {
       // Found a statement. Continue parsing after the delimiter

=== modified file 'client/mysqltest.c'
--- a/client/mysqltest.c	2008-07-09 11:19:04 +0000
+++ b/client/mysqltest.c	2008-07-21 09:20:03 +0000
@@ -171,6 +171,8 @@ static ulonglong timer_now(void);
 
 static ulonglong progress_start= 0;
 
+static ulong connection_retry_sleep= 100000; /* Microseconds */
+
 /* Precompiled re's */
 static my_regex_t ps_re;     /* the query can be run using PS protocol */
 static my_regex_t sp_re;     /* the query can be run as a SP */
@@ -495,6 +497,9 @@ void replace_dynstr_append(DYNAMIC_STRIN
 void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
 void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
 
+static int match_expected_error(struct st_command *command,
+                                unsigned int err_errno,
+                                const char *err_sqlstate);
 void handle_error(struct st_command*,
                   unsigned int err_errno, const char *err_error,
                   const char *err_sqlstate, DYNAMIC_STRING *ds);
@@ -848,29 +853,25 @@ void check_command_args(struct st_comman
   DBUG_VOID_RETURN;
 }
 
-
 void handle_command_error(struct st_command *command, uint error)
 {
   DBUG_ENTER("handle_command_error");
   DBUG_PRINT("enter", ("error: %d", error));
   if (error != 0)
   {
-    uint i;
+    int i;
 
     if (command->abort_on_error)
       die("command \"%.*s\" failed with error %d",
           command->first_word_len, command->query, error);
-    for (i= 0; i < command->expected_errors.count; i++)
+
+    i= match_expected_error(command, error, NULL);
+
+    if (i >= 0)
     {
-      DBUG_PRINT("info", ("expected error: %d",
-                          command->expected_errors.err[i].code.errnum));
-      if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
-          (command->expected_errors.err[i].code.errnum == error))
-      {
-        DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
-                            command->first_word_len, command->query, error));
-        DBUG_VOID_RETURN;
-      }
+      DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
+                          command->first_word_len, command->query, error));
+      DBUG_VOID_RETURN;
     }
     die("command \"%.*s\" failed with wrong error: %d",
         command->first_word_len, command->query, error);
@@ -2465,8 +2466,8 @@ void do_exec(struct st_command *command)
   error= pclose(res_file);
   if (error > 0)
   {
-    uint status= WEXITSTATUS(error), i;
-    my_bool ok= 0;
+    uint status= WEXITSTATUS(error);
+    int i;
 
     if (command->abort_on_error)
     {
@@ -2478,19 +2479,13 @@ void do_exec(struct st_command *command)
 
     DBUG_PRINT("info",
                ("error: %d, status: %d", error, status));
-    for (i= 0; i < command->expected_errors.count; i++)
-    {
-      DBUG_PRINT("info", ("expected error: %d",
-                          command->expected_errors.err[i].code.errnum));
-      if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
-          (command->expected_errors.err[i].code.errnum == status))
-      {
-        ok= 1;
-        DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
-                            command->first_argument, status));
-      }
-    }
-    if (!ok)
+
+    i= match_expected_error(command, status, NULL);
+
+    if (i >= 0)
+      DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
+                          command->first_argument, status));
+    else
     {
       dynstr_free(&ds_cmd);
       die("command \"%s\" failed with wrong error: %d",
@@ -4290,7 +4285,6 @@ void safe_connect(MYSQL* mysql, const ch
                   int port, const char *sock)
 {
   int failed_attempts= 0;
-  static ulong connection_retry_sleep= 100000; /* Microseconds */
 
   DBUG_ENTER("safe_connect");
   while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
@@ -4357,6 +4351,7 @@ int connect_n_handle_errors(struct st_co
                             const char* db, int port, const char* sock)
 {
   DYNAMIC_STRING *ds;
+  int failed_attempts= 0;
 
   ds= &ds_res;
 
@@ -4385,9 +4380,41 @@ int connect_n_handle_errors(struct st_co
     dynstr_append_mem(ds, delimiter, delimiter_length);
     dynstr_append_mem(ds, "\n", 1);
   }
-  if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
+  while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
                           CLIENT_MULTI_STATEMENTS))
   {
+    /*
+      If we have used up all our connections check whether this
+      is expected (by --error). If so, handle the error right away.
+      Otherwise, give it some extra time to rule out race-conditions.
+      If extra-time doesn't help, we have an unexpected error and
+      must abort -- just proceeding to handle_error() when second
+      and third chances are used up will handle that for us.
+
+      There are various user-limits of which only max_user_connections
+      and max_connections_per_hour apply at connect time. For the
+      the second to create a race in our logic, we'd need a limits
+      test that runs without a FLUSH for longer than an hour, so we'll
+      stay clear of trying to work out which exact user-limit was
+      exceeded.
+    */
+
+    if (((mysql_errno(con) == ER_TOO_MANY_USER_CONNECTIONS) ||
+         (mysql_errno(con) == ER_USER_LIMIT_REACHED)) &&
+        (failed_attempts++ < opt_max_connect_retries))
+    {
+      int i;
+
+      i= match_expected_error(command, mysql_errno(con), mysql_sqlstate(con));
+
+      if (i >= 0)
+        goto do_handle_error;                 /* expected error, handle */
+
+      my_sleep(connection_retry_sleep);       /* unexpected error, wait */
+      continue;                               /* and give it 1 more chance */
+    }
+
+do_handle_error:
     var_set_errno(mysql_errno(con));
     handle_error(command, mysql_errno(con), mysql_error(con),
 		 mysql_sqlstate(con), ds);
@@ -6150,6 +6177,56 @@ end:
 
 
 /*
+  Check whether given error is in list of expected errors
+
+  SYNOPSIS
+    match_expected_error()
+
+  PARAMETERS
+    command        the current command (and its expect-list)
+    err_errno      error number of the error that actually occurred
+    err_sqlstate   SQL-state that was thrown, or NULL for impossible
+                   (file-ops, diff, etc.)
+
+  RETURNS
+    -1 for not in list, index in list of expected errors otherwise
+
+  NOTE
+    If caller needs to know whether the list was empty, they should
+    check command->expected_errors.count.
+*/
+
+static int match_expected_error(struct st_command *command,
+                                unsigned int err_errno,
+                                const char *err_sqlstate)
+{
+  uint i;
+
+  for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
+  {
+    if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
+        (command->expected_errors.err[i].code.errnum == err_errno))
+      return i;
+
+    if (command->expected_errors.err[i].type == ERR_SQLSTATE)
+    {
+      /*
+        NULL is quite likely, but not in conjunction with a SQL-state expect!
+      */
+      if (unlikely(err_sqlstate == NULL))
+        die("expecting a SQL-state (%s) from query '%s' which cannot produce one...",
+            command->expected_errors.err[i].code.sqlstate, command->query);
+
+      if (strncmp(command->expected_errors.err[i].code.sqlstate,
+                  err_sqlstate, SQLSTATE_LENGTH) == 0)
+        return i;
+    }
+  }
+  return -1;
+}
+
+
+/*
   Handle errors which occurred during execution
 
   SYNOPSIS
@@ -6169,7 +6246,7 @@ void handle_error(struct st_command *com
                   unsigned int err_errno, const char *err_error,
                   const char *err_sqlstate, DYNAMIC_STRING *ds)
 {
-  uint i;
+  int i;
 
   DBUG_ENTER("handle_error");
 
@@ -6195,34 +6272,30 @@ void handle_error(struct st_command *com
 
   DBUG_PRINT("info", ("expected_errors.count: %d",
                       command->expected_errors.count));
-  for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
+
+  i= match_expected_error(command, err_errno, err_sqlstate);
+
+  if (i >= 0)
   {
-    if (((command->expected_errors.err[i].type == ERR_ERRNO) &&
-         (command->expected_errors.err[i].code.errnum == err_errno)) ||
-        ((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
-         (strncmp(command->expected_errors.err[i].code.sqlstate,
-                  err_sqlstate, SQLSTATE_LENGTH) == 0)))
+    if (!disable_result_log)
     {
-      if (!disable_result_log)
+      if (command->expected_errors.count == 1)
       {
-        if (command->expected_errors.count == 1)
-        {
-          /* Only log error if there is one possible error */
-          dynstr_append_mem(ds, "ERROR ", 6);
-          replace_dynstr_append(ds, err_sqlstate);
-          dynstr_append_mem(ds, ": ", 2);
-          replace_dynstr_append(ds, err_error);
-          dynstr_append_mem(ds,"\n",1);
-        }
-        /* Don't log error if we may not get an error */
-        else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
-                 (command->expected_errors.err[0].type == ERR_ERRNO &&
-                  command->expected_errors.err[0].code.errnum != 0))
-          dynstr_append(ds,"Got one of the listed errors\n");
-      }
-      /* OK */
-      DBUG_VOID_RETURN;
+        /* Only log error if there is one possible error */
+        dynstr_append_mem(ds, "ERROR ", 6);
+        replace_dynstr_append(ds, err_sqlstate);
+        dynstr_append_mem(ds, ": ", 2);
+        replace_dynstr_append(ds, err_error);
+        dynstr_append_mem(ds,"\n",1);
+      }
+      /* Don't log error if we may not get an error */
+      else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
+               (command->expected_errors.err[0].type == ERR_ERRNO &&
+                command->expected_errors.err[0].code.errnum != 0))
+        dynstr_append(ds,"Got one of the listed errors\n");
     }
+    /* OK */
+    DBUG_VOID_RETURN;
   }
 
   DBUG_PRINT("info",("i: %d  expected_errors: %d", i,
@@ -6237,7 +6310,7 @@ void handle_error(struct st_command *com
     dynstr_append_mem(ds, "\n", 1);
   }
 
-  if (i)
+  if (command->expected_errors.count > 0)
   {
     if (command->expected_errors.err[0].type == ERR_ERRNO)
       die("query '%s' failed with wrong errno %d: '%s', instead of %d...",

=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc	2008-06-17 14:12:21 +0000
+++ b/mysql-test/include/mix1.inc	2008-07-17 15:51:24 +0000
@@ -1103,6 +1103,24 @@ set @my_innodb_commit_concurrency=@@glob
 set global innodb_commit_concurrency=0;
 set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
 
+#
+# Bug #37830: ORDER BY ASC/DESC - no difference
+#
+
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ ENGINE=InnoDB;
+
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+
+# should be range access
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+# should produce '8 7 6 5 4' for a
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+DROP TABLE t1;
+
 --echo End of 5.0 tests
 
 # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY

=== modified file 'mysql-test/include/query_prealloc_size_basic.inc'
--- a/mysql-test/include/query_prealloc_size_basic.inc	2008-05-08 18:13:39 +0000
+++ b/mysql-test/include/query_prealloc_size_basic.inc	2008-07-17 09:03:17 +0000
@@ -1,32 +1,35 @@
-############## mysql-test\t\query_prealloc_size_basic.test ###############
-#                                                                             #
-# Variable Name: query_prealloc_size                                          #
-# Scope: GLOBAL | SESSION                                                     #
-# Access Type: Dynamic                                                        #
-# Data Type: numeric                                                          #
-# Default Value:  8192                                                        #
-# Range:  8192-4294967295                                                     #
-#                                                                             #
-#                                                                             #
-# Creation Date: 2008-02-07                                                   #
-# Author:  Rizwan                                                             #
-#                                                                             #
-# Description: Test Cases of Dynamic System Variable query_prealloc_size      #
-#              that checks the behavior of this variable in the following ways#
-#              * Default Value                                                #
-#              * Valid & Invalid values                                       #
-#              * Scope & Access method                                        #
-#              * Data Integrity                                               #
-#                                                                             #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/                          #
-#  server-system-variables.html                                               #
-#                                                                             #
-###############################################################################
+################# mysql-test\t\query_prealloc_size_basic.test ##################
+#                                                                              #
+# Variable Name: query_prealloc_size                                           #
+# Scope: GLOBAL | SESSION                                                      #
+# Access Type: Dynamic                                                         #
+# Data Type: numeric                                                           #
+# Default Value:  8192                                                         #
+# Range:  8192-4294967295                                                      #
+#                                                                              #
+#                                                                              #
+# Creation Date: 2008-02-07                                                    #
+# Author:  Rizwan                                                              #
+#                                                                              #
+# Description: Test Cases of Dynamic System Variable query_prealloc_size       #
+#              that checks the behavior of this variable in the following ways #
+#              * Default Value                                                 #
+#              * Valid & Invalid values                                        #
+#              * Scope & Access method                                         #
+#              * Data Integrity                                                #
+#                                                                              #
+# Reference:                                                                   #
+#      http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html     #
+#                                                                              #
+# Last Modification:                                                           #
+# 2008-07-14 hhunger removed values for 64 bit platforms.                      #
+#                                                                              #
+################################################################################
 
 --source include/load_sysvars.inc
 
 ########################################################################
-#           START OF query_prealloc_size   TESTS                    #
+#              START OF query_prealloc_size   TESTS                    #
 ########################################################################
 
 
@@ -42,7 +45,7 @@ SELECT @start_session_value;
 
 --echo '#--------------------FN_DYNVARS_005_01-------------------------#'
 ########################################################################
-#     Display the DEFAULT value of myisam_block_size            #
+#            Display the DEFAULT value of myisam_block_size            #
 ########################################################################
 
 SET @@global.query_prealloc_size   = 100;
@@ -56,7 +59,7 @@ SELECT @@session.query_prealloc_size  ;
 
 --echo '#--------------------FN_DYNVARS_005_02-------------------------#'
 ########################################################################
-#     Check the DEFAULT value of query_prealloc_size                #
+#        Check the DEFAULT value of query_prealloc_size                #
 ########################################################################
 
 SET @@global.query_prealloc_size   = DEFAULT;
@@ -67,30 +70,32 @@ SELECT @@session.query_prealloc_size   =
 
 
 --echo '#--------------------FN_DYNVARS_005_03-------------------------#'
-##################################################################################
-# Change the value of query_prealloc_size   to a valid value for GLOBAL Scope #
-##################################################################################
+################################################################################
+# Change the value of query_prealloc_size   to a valid value for GLOBAL Scope  #
+################################################################################
 
 SET @@global.query_prealloc_size   = 8192;
 SELECT @@global.query_prealloc_size  ;
 
-SET @@global.query_prealloc_size   = 4294967295;
-SELECT @@global.query_prealloc_size  ;
+# Due to problems with 64 bit machines having less than 6 GB main memory.
+#SET @@global.query_prealloc_size   = 4294967295;
+#SELECT @@global.query_prealloc_size  ;
 
 SET @@global.query_prealloc_size   = 655354;
 SELECT @@global.query_prealloc_size  ;
 
 
 --echo '#--------------------FN_DYNVARS_005_04-------------------------#'
-###################################################################################
-# Change the value of query_prealloc_size   to a valid value for SESSION Scope #
-###################################################################################
- 
+##################################################################################
+# Change the value of query_prealloc_size   to a valid value for SESSION Scope   #
+##################################################################################
+
 SET @@session.query_prealloc_size   = 8192;
 SELECT @@session.query_prealloc_size  ;
 
-SET @@session.query_prealloc_size   = 4294967295;
-SELECT @@session.query_prealloc_size  ;
+# Due to problems with 64 bit machines having less than 6 GB main memory.
+#SET @@session.query_prealloc_size   = 4294967295;
+#SELECT @@session.query_prealloc_size  ;
 
 SET @@session.query_prealloc_size   = 655345;
 SELECT @@session.query_prealloc_size  ;
@@ -100,7 +105,7 @@ SELECT @@session.query_prealloc_size  ;
 
 --echo '#------------------FN_DYNVARS_005_05-----------------------#'
 ####################################################################
-# Change the value of query_prealloc_size   to an invalid value #
+#  Change the value of query_prealloc_size   to an invalid value   #
 ####################################################################
 
 SET @@global.query_prealloc_size   = 0;
@@ -109,8 +114,9 @@ SELECT @@global.query_prealloc_size  ;
 SET @@global.query_prealloc_size   = -1024;
 SELECT @@global.query_prealloc_size  ;
 
-SET @@global.query_prealloc_size   = 429496729533;
-SELECT @@global.query_prealloc_size  ;
+# Due to problems with 64 bit machines having less than 6 GB main memory.
+#SET @@global.query_prealloc_size   = 429496729533;
+#SELECT @@global.query_prealloc_size  ;
 
 
 --Error ER_PARSE_ERROR
@@ -161,8 +167,8 @@ SELECT @@session.query_prealloc_size  ;
 ####################################################################
 
 
-SELECT @@global.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+SELECT @@global.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 
 --echo '#------------------FN_DYNVARS_005_07-----------------------#'
@@ -170,8 +176,8 @@ WHERE VARIABLE_NAME='query_prealloc_size
 #  Check if the value in SESSION Table matches value in variable   #
 ####################################################################
 
-SELECT @@session.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.SESSION_VARIABLES 
+SELECT @@session.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 
 
@@ -188,18 +194,19 @@ SELECT @@global.query_prealloc_size  ;
 
 
 --echo '#---------------------FN_DYNVARS_001_09----------------------#'
-#################################################################################### 
-#  Check if accessing variable with and without GLOBAL point to same variable   #
-#################################################################################### 
+################################################################################
+# Check if accessing variable with and without GLOBAL point to same variable   #
+################################################################################
 
 SET @@global.query_prealloc_size   = 10;
 SELECT @@query_prealloc_size   = @@global.query_prealloc_size  ;
 
 
 --echo '#---------------------FN_DYNVARS_001_10----------------------#'
-########################################################################################################
-#    Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable  #
-########################################################################################################
+##############################################################################
+# Check if accessing variable with SESSION,LOCAL and without SCOPE points to #
+# to the same session variable                                               #
+##############################################################################
 
 SET @@query_prealloc_size   = 100;
 SELECT @@query_prealloc_size   = @@local.query_prealloc_size  ;
@@ -207,9 +214,9 @@ SELECT @@local.query_prealloc_size   = @
 
 
 --echo '#---------------------FN_DYNVARS_001_11----------------------#'
-###################################################################################  
-#   Check if query_prealloc_size   can be accessed with and without @@ sign    #
-###################################################################################
+################################################################################
+#    Check if query_prealloc_size   can be accessed with and without @@ sign   #
+################################################################################
 
 SET query_prealloc_size   = 1;
 SELECT @@query_prealloc_size  ;
@@ -235,5 +242,6 @@ SELECT @@session.query_prealloc_size  ;
 
 
 #############################################################
-#                 END OF query_prealloc_size   TESTS     #
+#                 END OF query_prealloc_size   TESTS        #
 #############################################################
+

=== modified file 'mysql-test/r/client_xml.result'
--- a/mysql-test/r/client_xml.result	2008-04-30 13:28:19 +0000
+++ b/mysql-test/r/client_xml.result	2008-07-18 12:00:45 +0000
@@ -1,5 +1,6 @@
 set @old_concurrent_insert= @@global.concurrent_insert;
 set @@global.concurrent_insert= 0;
+drop table if exists t1;
 create table t1 (
 `a&b` int,
 `a<b` int,

=== modified file 'mysql-test/r/func_in.result'
--- a/mysql-test/r/func_in.result	2008-02-12 19:09:16 +0000
+++ b/mysql-test/r/func_in.result	2008-07-14 09:06:49 +0000
@@ -569,4 +569,10 @@ insert into t1 values (),(),(),(),(),(),
 select a from t1 where a not in (a,a,a) group by a;
 a
 drop table t1;
+create table t1 (id int);
+select * from t1 where NOT id in (select null union all select 1);
+id
+select * from t1 where NOT id in (null, 1);
+id
+drop table t1;
 End of 5.1 tests

=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result	2008-06-17 14:12:21 +0000
+++ b/mysql-test/r/innodb_mysql.result	2008-07-17 15:51:24 +0000
@@ -1362,6 +1362,21 @@ set global innodb_autoextend_increment=@
 set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
 set global innodb_commit_concurrency=0;
 set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ENGINE=InnoDB;
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	t1_b	PRIMARY	4	NULL	8	Using where
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+a	b	c
+8	1	1
+7	1	1
+6	1	1
+5	1	1
+4	1	1
+DROP TABLE t1;
 End of 5.0 tests
 CREATE TABLE `t2` (
 `k` int(11) NOT NULL auto_increment,

=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result	2008-06-26 16:46:45 +0000
+++ b/mysql-test/r/mysql.result	2008-07-22 10:56:36 +0000
@@ -38,8 +38,6 @@ t2
 t3
 Tables_in_test
 t1
-delimiter
-1
 _
 Test delimiter : from command line
 a

=== modified file 'mysql-test/r/mysqltest.result'
--- a/mysql-test/r/mysqltest.result	2008-07-09 11:19:04 +0000
+++ b/mysql-test/r/mysqltest.result	2008-07-21 09:20:03 +0000
@@ -14,6 +14,7 @@ select otto from (select 1 as otto) as t
 otto
 1
 mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22...
+mysqltest: At line 1: expecting a SQL-state (00000) from query 'remove_file MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp' which cannot produce one...
 select friedrich from (select 1 as otto) as t1;
 ERROR 42S22: Unknown column 'friedrich' in 'field list'
 mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000...

=== added file 'mysql-test/r/parser_stack.result'
--- a/mysql-test/r/parser_stack.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/parser_stack.result	2008-07-14 21:41:30 +0000
@@ -0,0 +1,306 @@
+use test;
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+1
+1
+prepare stmt from
+"
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+"
+;
+execute stmt;
+1
+1
+drop view if exists view_overflow;
+CREATE VIEW view_overflow AS
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+SELECT * from view_overflow;
+1
+1
+drop view view_overflow;
+drop procedure if exists proc_overflow;
+CREATE PROCEDURE proc_overflow()
+BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+select 1;
+select 2;
+select 3;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END $$
+call proc_overflow();
+1
+1
+2
+2
+3
+3
+drop procedure proc_overflow;
+drop function if exists func_overflow;
+create function func_overflow() returns int
+BEGIN
+DECLARE x int default 0;
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+SET x=x+1;
+SET x=x+2;
+SET x=x+3;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+return x;
+END $$
+select func_overflow();
+func_overflow()
+6
+drop function func_overflow;
+drop table if exists table_overflow;
+create table table_overflow(a int, b int);
+create trigger trigger_overflow before insert on table_overflow
+for each row
+BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+SET NEW.b := NEW.a;
+SET NEW.b := NEW.b + 1;
+SET NEW.b := NEW.b + 2;
+SET NEW.b := NEW.b + 3;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+END $$
+insert into table_overflow set a=10;
+insert into table_overflow set a=20;
+select * from table_overflow;
+a	b
+10	16
+20	26
+drop table table_overflow;
+drop procedure if exists proc_35577;
+CREATE PROCEDURE proc_35577()
+BEGIN
+DECLARE z_done INT DEFAULT 0;
+DECLARE t_done VARCHAR(5000);
+outer_loop: LOOP
+IF t_done=1  THEN
+LEAVE outer_loop;
+END IF;
+inner_block:BEGIN
+DECLARE z_done INT DEFAULT  0;
+SET z_done = 0;
+inner_loop: LOOP
+IF z_done=1  THEN
+LEAVE inner_loop;
+END IF;
+IF (t_done = 'a') THEN
+IF (t_done <> 0) THEN
+IF ( t_done > 0) THEN
+IF (t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF (t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+ELSEIF(t_done = 'a') THEN
+SET t_done = 'a';
+END IF;
+END IF;
+END IF;
+END IF;
+END LOOP inner_loop;
+END inner_block;
+END LOOP outer_loop;
+END $$
+drop procedure proc_35577;
+drop procedure if exists p_37269;
+create procedure p_37269()
+begin
+declare done int default 0;
+declare varb int default 0;
+declare vara int default 0;
+repeat
+select now();
+until done end repeat;
+while varb do
+select now();
+begin
+select now();
+repeat
+select now();
+until done end repeat;
+if vara then 
+select now();
+repeat
+select now();
+loop
+select now();
+end loop;
+repeat
+select now();
+label1: while varb do
+select now();
+end while label1;
+if vara then 
+select now();
+repeat
+select now();
+until done end repeat;
+begin
+select now();
+while varb do
+select now();
+label1: while varb do
+select now();
+end while label1;
+if vara then 
+select now();
+while varb do
+select now();
+loop
+select now();
+end loop;
+repeat
+select now();
+loop
+select now();
+while varb do
+select now();
+end while;
+repeat
+select now();
+label1: loop
+select now();
+if vara then 
+select now();
+end if;
+end loop label1;
+until done end repeat;
+end loop;
+until done end repeat;
+end while;
+end if;
+end while;
+end;
+end if;
+until done end repeat;
+until done end repeat;
+end if;
+end;
+end while;
+end $$
+drop procedure p_37269;
+drop procedure if exists p_37228;
+create procedure p_37228 ()
+BEGIN
+DECLARE v INT DEFAULT 123;
+IF (v > 1) THEN SET v = 1; 
+ELSEIF (v < 10) THEN SET v = 10;
+ELSEIF (v < 11) THEN SET v = 11;
+ELSEIF (v < 12) THEN SET v = 12;
+ELSEIF (v < 13) THEN SET v = 13;
+ELSEIF (v < 14) THEN SET v = 14;
+ELSEIF (v < 15) THEN SET v = 15;
+ELSEIF (v < 16) THEN SET v = 16;
+ELSEIF (v < 17) THEN SET v = 17;
+ELSEIF (v < 18) THEN SET v = 18;
+ELSEIF (v < 19) THEN SET v = 19;
+ELSEIF (v < 20) THEN SET v = 20;
+ELSEIF (v < 21) THEN SET v = 21;
+ELSEIF (v < 22) THEN SET v = 22;
+ELSEIF (v < 23) THEN SET v = 23;
+ELSEIF (v < 24) THEN SET v = 24;
+ELSEIF (v < 25) THEN SET v = 25;
+ELSEIF (v < 26) THEN SET v = 26;
+ELSEIF (v < 27) THEN SET v = 27;
+ELSEIF (v < 28) THEN SET v = 28;
+ELSEIF (v < 29) THEN SET v = 29;
+ELSEIF (v < 30) THEN SET v = 30;
+ELSEIF (v < 31) THEN SET v = 31;
+ELSEIF (v < 32) THEN SET v = 32;
+ELSEIF (v < 33) THEN SET v = 33;
+ELSEIF (v < 34) THEN SET v = 34;
+ELSEIF (v < 35) THEN SET v = 35;
+ELSEIF (v < 36) THEN SET v = 36;
+ELSEIF (v < 37) THEN SET v = 37;
+ELSEIF (v < 38) THEN SET v = 38;
+ELSEIF (v < 39) THEN SET v = 39;
+END IF;
+END $$
+drop procedure p_37228;

=== modified file 'mysql-test/r/query_prealloc_size_basic_32.result'
--- a/mysql-test/r/query_prealloc_size_basic_32.result	2008-05-08 18:13:39 +0000
+++ b/mysql-test/r/query_prealloc_size_basic_32.result	2008-07-17 09:03:17 +0000
@@ -35,10 +35,6 @@ SET @@global.query_prealloc_size   = 819
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
 8192
-SET @@global.query_prealloc_size   = 4294967295;
-SELECT @@global.query_prealloc_size  ;
-@@global.query_prealloc_size
-4294966272
 SET @@global.query_prealloc_size   = 655354;
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
@@ -48,10 +44,6 @@ SET @@session.query_prealloc_size   = 81
 SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
 8192
-SET @@session.query_prealloc_size   = 4294967295;
-SELECT @@session.query_prealloc_size  ;
-@@session.query_prealloc_size
-4294966272
 SET @@session.query_prealloc_size   = 655345;
 SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
@@ -69,37 +61,31 @@ Warning	1292	Truncated incorrect query_p
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
 8192
-SET @@global.query_prealloc_size   = 429496729533;
-Warnings:
-Warning	1292	Truncated incorrect query_prealloc_size value: '429496729533'
-SELECT @@global.query_prealloc_size  ;
-@@global.query_prealloc_size
-4294966272
 SET @@global.query_prealloc_size   = 65530.34.;
 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 '.' at line 1
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-4294966272
+8192
 SET @@global.query_prealloc_size   = test;
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-4294966272
+8192
 SET @@global.query_prealloc_size   = "test";
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-4294966272
+8192
 SET @@global.query_prealloc_size   = 'test';
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-4294966272
+8192
 SET @@global.query_prealloc_size   = ON;
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-4294966272
+8192
 SET @@session.query_prealloc_size   = 0;
 Warnings:
 Warning	1292	Truncated incorrect query_prealloc_size value: '0'
@@ -128,14 +114,14 @@ SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
 8192
 '#------------------FN_DYNVARS_005_06-----------------------#'
-SELECT @@global.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+SELECT @@global.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 @@global.query_prealloc_size   = VARIABLE_VALUE
 1
 '#------------------FN_DYNVARS_005_07-----------------------#'
-SELECT @@session.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.SESSION_VARIABLES 
+SELECT @@session.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 @@session.query_prealloc_size   = VARIABLE_VALUE
 1

=== modified file 'mysql-test/r/query_prealloc_size_basic_64.result'
--- a/mysql-test/r/query_prealloc_size_basic_64.result	2008-05-08 18:13:39 +0000
+++ b/mysql-test/r/query_prealloc_size_basic_64.result	2008-07-17 09:03:17 +0000
@@ -35,10 +35,6 @@ SET @@global.query_prealloc_size   = 819
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
 8192
-SET @@global.query_prealloc_size   = 4294967295;
-SELECT @@global.query_prealloc_size  ;
-@@global.query_prealloc_size
-4294966272
 SET @@global.query_prealloc_size   = 655354;
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
@@ -48,10 +44,6 @@ SET @@session.query_prealloc_size   = 81
 SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
 8192
-SET @@session.query_prealloc_size   = 4294967295;
-SELECT @@session.query_prealloc_size  ;
-@@session.query_prealloc_size
-4294966272
 SET @@session.query_prealloc_size   = 655345;
 SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
@@ -69,35 +61,31 @@ Warning	1292	Truncated incorrect query_p
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
 8192
-SET @@global.query_prealloc_size   = 429496729533;
-SELECT @@global.query_prealloc_size  ;
-@@global.query_prealloc_size
-429496728576
 SET @@global.query_prealloc_size   = 65530.34.;
 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 '.' at line 1
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-429496728576
+8192
 SET @@global.query_prealloc_size   = test;
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-429496728576
+8192
 SET @@global.query_prealloc_size   = "test";
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-429496728576
+8192
 SET @@global.query_prealloc_size   = 'test';
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-429496728576
+8192
 SET @@global.query_prealloc_size   = ON;
 ERROR 42000: Incorrect argument type to variable 'query_prealloc_size'
 SELECT @@global.query_prealloc_size  ;
 @@global.query_prealloc_size
-429496728576
+8192
 SET @@session.query_prealloc_size   = 0;
 Warnings:
 Warning	1292	Truncated incorrect query_prealloc_size value: '0'
@@ -126,14 +114,14 @@ SELECT @@session.query_prealloc_size  ;
 @@session.query_prealloc_size
 8192
 '#------------------FN_DYNVARS_005_06-----------------------#'
-SELECT @@global.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+SELECT @@global.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 @@global.query_prealloc_size   = VARIABLE_VALUE
 1
 '#------------------FN_DYNVARS_005_07-----------------------#'
-SELECT @@session.query_prealloc_size   = VARIABLE_VALUE 
-FROM INFORMATION_SCHEMA.SESSION_VARIABLES 
+SELECT @@session.query_prealloc_size   = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
 WHERE VARIABLE_NAME='query_prealloc_size  ';
 @@session.query_prealloc_size   = VARIABLE_VALUE
 1

=== modified file 'mysql-test/suite/rpl/r/rpl_server_id1.result'
--- a/mysql-test/suite/rpl/r/rpl_server_id1.result	2008-02-20 21:18:01 +0000
+++ b/mysql-test/suite/rpl/r/rpl_server_id1.result	2008-07-18 11:53:16 +0000
@@ -9,42 +9,5 @@ stop slave;
 change master to master_port=SLAVE_PORT;
 start slave;
 *** must be having the replicate-same-server-id IO thread error ***
-show slave status;
-Slave_IO_State	
-Master_Host	127.0.0.1
-Master_User	root
-Master_Port	SLAVE_PORT
-Connect_Retry	1
-Master_Log_File	
-Read_Master_Log_Pos	4
-Relay_Log_File	slave-relay-bin.000001
-Relay_Log_Pos	4
-Relay_Master_Log_File	
-Slave_IO_Running	No
-Slave_SQL_Running	#
-Replicate_Do_DB	
-Replicate_Ignore_DB	
-Replicate_Do_Table	
-Replicate_Ignore_Table	#
-Replicate_Wild_Do_Table	
-Replicate_Wild_Ignore_Table	#
-Last_Errno	#
-Last_Error	#
-Skip_Counter	0
-Exec_Master_Log_Pos	0
-Relay_Log_Space	106
-Until_Condition	None
-Until_Log_File	
-Until_Log_Pos	0
-Master_SSL_Allowed	No
-Master_SSL_CA_File	
-Master_SSL_CA_Path	
-Master_SSL_Cert	
-Master_SSL_Cipher	
-Master_SSL_Key	
-Seconds_Behind_Master	NULL
-Master_SSL_Verify_Server_Cert	No
-Last_IO_Errno	1593
-Last_IO_Error	Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
-Last_SQL_Errno	#
-Last_SQL_Error	#
+Slave_IO_Errno= 1593
+Slave_IO_Error= Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

=== modified file 'mysql-test/suite/rpl/r/rpl_temporary.result'
--- a/mysql-test/suite/rpl/r/rpl_temporary.result	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_temporary.result	2008-07-18 08:20:55 +0000
@@ -76,9 +76,9 @@ drop table t1,t2;
 create temporary table t3 (f int);
 create temporary table t4 (f int);
 create table t5 (f int);
-select id from information_schema.processlist where command='Binlog Dump' into @id;
-kill @id;
+stop slave;
 insert into t5 select * from t4;
+start slave;
 select * from t5 /* must be 1 after reconnection */;
 f
 drop temporary table t4;

=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def	2008-06-19 10:39:48 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def	2008-07-21 19:05:06 +0000
@@ -12,4 +12,4 @@
 
 rpl_redirect               : Failure is sporadic and and the test is superfluous (mats)
 rpl_innodb_bug28430        : Failure on Solaris Bug #36793
-rpl_server_id1             : Bug #36818 rpl_server_id1 fails expecting slave has stopped (azundris)
+rpl_temporary              : BUG#38269 2008-07-21 Sven valgrind error in pushbuild

=== modified file 'mysql-test/suite/rpl/t/rpl_server_id1.test'
--- a/mysql-test/suite/rpl/t/rpl_server_id1.test	2008-05-20 15:14:03 +0000
+++ b/mysql-test/suite/rpl/t/rpl_server_id1.test	2008-07-18 11:53:16 +0000
@@ -10,17 +10,15 @@ reset master;
 
 # replicate ourselves
 stop slave;
-source include/wait_for_slave_to_stop.inc;
 --replace_result $SLAVE_MYPORT SLAVE_PORT
 eval change master to master_port=$SLAVE_MYPORT;
 start slave;
 
+let $slave_param= Last_IO_Errno;                                          
+let $slave_param_value= 1593;
+source include/wait_for_slave_param.inc; 
 --echo *** must be having the replicate-same-server-id IO thread error ***
-
-source include/wait_for_slave_io_to_stop.inc;
-
---replace_result $SLAVE_MYPORT SLAVE_PORT
---replace_column 12 # 16 # 19 # 20 # 18 # 37 # 38 #
-query_vertical show slave status;
-
-# End of 4.1 tests
+let $last_io_errno= query_get_value("show slave status", Last_IO_Errno, 1);
+let $last_io_error= query_get_value("show slave status", Last_IO_Error, 1);
+echo Slave_IO_Errno= $last_io_errno;
+echo Slave_IO_Error= $last_io_error;

=== modified file 'mysql-test/suite/rpl/t/rpl_temporary.test'
--- a/mysql-test/suite/rpl/t/rpl_temporary.test	2008-03-12 12:07:35 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temporary.test	2008-07-18 08:20:55 +0000
@@ -138,20 +138,21 @@ sync_slave_with_master;
 
 #
 # Bug#17284 erroneous temp table cleanup on slave
+# The test targets at verifying that reconnected slave
+# retained the former session's temporary tables
 #
-
 connection master;
 create temporary table t4 (f int);
 create table t5 (f int);
 sync_slave_with_master;
+# connection slave
+stop slave;  # to prepare for reconnecting w/o waiting for timeout
 connection master;
-# find dumper's $id
-select id from information_schema.processlist where command='Binlog Dump' into @id;
-kill @id; # to stimulate reconnection by slave w/o timeout
 insert into t5 select * from t4;
 save_master_pos;
 
 connection slave;
+start slave;
 sync_with_master;
 select * from t5 /* must be 1 after reconnection */;
 

=== modified file 'mysql-test/t/client_xml.test'
--- a/mysql-test/t/client_xml.test	2008-04-30 13:28:19 +0000
+++ b/mysql-test/t/client_xml.test	2008-07-18 12:00:45 +0000
@@ -6,6 +6,9 @@
 # the data is actually in the table).
 set @old_concurrent_insert= @@global.concurrent_insert;
 set @@global.concurrent_insert= 0;
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
 
 # Test of the xml output of the 'mysql' and 'mysqldump' clients -- makes
 # sure that basic encoding issues are handled properly

=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def	2008-05-23 16:42:54 +0000
+++ b/mysql-test/t/disabled.def	2008-07-22 11:04:32 +0000
@@ -11,7 +11,6 @@
 ##############################################################################
 federated_transactions   : Bug#29523 Transactions do not work
 csv_alter_table      : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables
-user_limits     : Bug#23921 random failure of user_limits.test
 thread_cache_size_func : Bug#36733 main.thread_cache_size_func fails randomly
 binlog_cache_size_basic_32            : Bug #36522: Some tests of system variables have diffs on 64bit platorms
 bulk_insert_buffer_size_basic_32      : Bug #36522: Some tests of system variables have diffs on 64bit platorms
@@ -95,3 +94,6 @@ tmp_table_size_basic_64               : 
 transaction_alloc_block_size_basic_64 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
 transaction_prealloc_size_basic_64    : Bug #36522: Some tests of system variables have diffs on 64bit platorms
 wait_timeout_basic_64                 : Bug #36522: Some tests of system variables have diffs on 64bit platorms
+log_tables.test                       : Bug #37798: main.log_tables fails randomly on powermacg5 and windows
+slow_query_log_func.test              : Bug #37962: *_func tests containing sleeps/race conditions
+

=== modified file 'mysql-test/t/func_in.test'
--- a/mysql-test/t/func_in.test	2007-10-31 21:24:32 +0000
+++ b/mysql-test/t/func_in.test	2008-07-14 09:06:49 +0000
@@ -417,4 +417,13 @@ insert into t1 values (),(),(),(),(),(),
 select a from t1 where a not in (a,a,a) group by a;
 drop table t1;
 
+#
+# Bug #37761: IN handles NULL differently for table-subquery and value-list
+#
+
+create table t1 (id int);
+select * from t1 where NOT id in (select null union all select 1);
+select * from t1 where NOT id in (null, 1);
+drop table t1;
+
 --echo End of 5.1 tests

=== modified file 'mysql-test/t/mysql_delimiter.sql'
--- a/mysql-test/t/mysql_delimiter.sql	2008-06-26 16:46:45 +0000
+++ b/mysql-test/t/mysql_delimiter.sql	2008-07-22 10:56:36 +0000
@@ -61,12 +61,6 @@ show tables//
 delimiter ; # Reset delimiter
 
 #
-# Bug #33812: mysql client incorrectly parsing DELIMITER
-#
-select a as delimiter from t1
-delimiter ; # Reset delimiter
-
-#
 # Bug #36244: MySQL CLI doesn't recognize standalone -- as comment
 #             before DELIMITER statement
 #

=== modified file 'mysql-test/t/mysqltest.test'
--- a/mysql-test/t/mysqltest.test	2008-07-09 11:19:04 +0000
+++ b/mysql-test/t/mysqltest.test	2008-07-21 09:20:03 +0000
@@ -91,6 +91,10 @@ select otto from (select 1 as otto) as t
 --error 1
 --exec echo "error S42S22; select otto from (select 1 as otto) as t1;" | $MYSQL_TEST  2>&1
 
+# expecting a SQL-state for a command that can't give one should fail
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--error 1
+--exec echo "error S00000; remove_file $MYSQLTEST_VARDIR/tmp/test_nonexistent.tmp;" | $MYSQL_TEST  2>&1
 
 
 # ----------------------------------------------------------------------------

=== added file 'mysql-test/t/parser_stack.test'
--- a/mysql-test/t/parser_stack.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/parser_stack.test	2008-07-14 21:41:30 +0000
@@ -0,0 +1,402 @@
+# Copyright (C) 2008 Sun Microsystems, Inc
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# These tests are designed to cause an internal parser stack overflow,
+# and trigger my_yyoverflow().
+#
+
+use test;
+
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+
+prepare stmt from
+"
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+"
+;
+
+execute stmt;
+
+--disable_warnings
+drop view if exists view_overflow;
+--enable_warnings
+
+CREATE VIEW view_overflow AS
+SELECT
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
+1
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
+;
+
+SELECT * from view_overflow;
+
+drop view view_overflow;
+
+--disable_warnings
+drop procedure if exists proc_overflow;
+--enable_warnings
+
+delimiter $$;
+
+CREATE PROCEDURE proc_overflow()
+BEGIN
+
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+  select 1;
+  select 2;
+  select 3;
+
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+
+END $$
+
+delimiter ;$$
+
+call proc_overflow();
+
+drop procedure proc_overflow;
+
+--disable_warnings
+drop function if exists func_overflow;
+--enable_warnings
+
+delimiter $$;
+
+create function func_overflow() returns int
+BEGIN
+  DECLARE x int default 0;
+
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+  SET x=x+1;
+  SET x=x+2;
+  SET x=x+3;
+
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+
+  return x;
+END $$
+
+delimiter ;$$
+
+select func_overflow();
+
+drop function func_overflow;
+
+--disable_warnings
+drop table if exists table_overflow;
+--enable_warnings
+
+create table table_overflow(a int, b int);
+
+delimiter $$;
+
+create trigger trigger_overflow before insert on table_overflow
+for each row
+BEGIN
+
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+  BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN BEGIN
+
+  SET NEW.b := NEW.a;
+  SET NEW.b := NEW.b + 1;
+  SET NEW.b := NEW.b + 2;
+  SET NEW.b := NEW.b + 3;
+
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;  END;
+
+END $$
+
+delimiter ;$$
+
+insert into table_overflow set a=10;
+insert into table_overflow set a=20;
+select * from table_overflow;
+
+drop table table_overflow;
+
+--disable_warnings
+drop procedure if exists proc_35577;
+--enable_warnings
+
+delimiter $$;
+
+CREATE PROCEDURE proc_35577()
+BEGIN
+  DECLARE z_done INT DEFAULT 0;
+  DECLARE t_done VARCHAR(5000);
+  outer_loop: LOOP
+    IF t_done=1  THEN
+      LEAVE outer_loop;
+    END IF;
+
+    inner_block:BEGIN
+      DECLARE z_done INT DEFAULT  0;
+      SET z_done = 0;
+      inner_loop: LOOP
+        IF z_done=1  THEN
+          LEAVE inner_loop;
+        END IF;
+        IF (t_done = 'a') THEN
+          IF (t_done <> 0) THEN
+            IF ( t_done > 0) THEN
+              IF (t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF (t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              ELSEIF(t_done = 'a') THEN
+                SET t_done = 'a';
+              END IF;
+            END IF;
+          END IF;
+        END IF;
+      END LOOP inner_loop;
+    END inner_block;
+  END LOOP outer_loop;
+END $$
+
+delimiter ;$$
+
+drop procedure proc_35577;
+
+#
+# Bug#37269 (parser crash when creating stored procedure)
+#
+
+--disable_warnings
+drop procedure if exists p_37269;
+--enable_warnings
+
+delimiter $$;
+
+create procedure p_37269()
+begin
+  declare done int default 0;
+  declare varb int default 0;
+  declare vara int default 0;
+
+  repeat
+    select now();
+  until done end repeat;
+  while varb do
+    select now();
+    begin
+      select now();
+      repeat
+        select now();
+      until done end repeat;
+      if vara then 
+        select now();
+        repeat
+          select now();
+          loop
+            select now();
+          end loop;
+          repeat
+            select now();
+            label1: while varb do
+              select now();
+            end while label1;
+            if vara then 
+              select now();
+              repeat
+                select now();
+              until done end repeat;
+              begin
+                select now();
+                while varb do
+                  select now();
+                  label1: while varb do
+                    select now();
+                  end while label1;
+                  if vara then 
+                    select now();
+                    while varb do
+                      select now();
+                      loop
+                        select now();
+                      end loop;
+                      repeat
+                        select now();
+                        loop
+                          select now();
+                          while varb do
+                            select now();
+                          end while;
+                          repeat
+                            select now();
+                            label1: loop
+                              select now();
+                              if vara then 
+                                select now();
+                              end if;
+                            end loop label1;
+                          until done end repeat;
+                        end loop;
+                      until done end repeat;
+                    end while;
+                  end if;
+                end while;
+              end;
+            end if;
+          until done end repeat;
+        until done end repeat;
+      end if;
+    end;
+  end while;
+end $$
+
+delimiter ;$$
+
+drop procedure p_37269;
+
+#
+# Bug#37228 (Sever crashes when creating stored procedure with more than
+#            10 IF/ELSEIF)
+#
+
+--disable_warnings
+drop procedure if exists p_37228;
+--enable_warnings
+
+delimiter $$;
+
+create procedure p_37228 ()
+BEGIN
+  DECLARE v INT DEFAULT 123;
+
+  IF (v > 1) THEN SET v = 1; 
+  ELSEIF (v < 10) THEN SET v = 10;
+  ELSEIF (v < 11) THEN SET v = 11;
+  ELSEIF (v < 12) THEN SET v = 12;
+  ELSEIF (v < 13) THEN SET v = 13;
+  ELSEIF (v < 14) THEN SET v = 14;
+  ELSEIF (v < 15) THEN SET v = 15;
+  ELSEIF (v < 16) THEN SET v = 16;
+  ELSEIF (v < 17) THEN SET v = 17;
+  ELSEIF (v < 18) THEN SET v = 18;
+  ELSEIF (v < 19) THEN SET v = 19;
+  ELSEIF (v < 20) THEN SET v = 20;
+  ELSEIF (v < 21) THEN SET v = 21;
+  ELSEIF (v < 22) THEN SET v = 22;
+  ELSEIF (v < 23) THEN SET v = 23;
+  ELSEIF (v < 24) THEN SET v = 24;
+  ELSEIF (v < 25) THEN SET v = 25;
+  ELSEIF (v < 26) THEN SET v = 26;
+  ELSEIF (v < 27) THEN SET v = 27;
+  ELSEIF (v < 28) THEN SET v = 28;
+  ELSEIF (v < 29) THEN SET v = 29;
+  ELSEIF (v < 30) THEN SET v = 30;
+  ELSEIF (v < 31) THEN SET v = 31;
+  ELSEIF (v < 32) THEN SET v = 32;
+  ELSEIF (v < 33) THEN SET v = 33;
+  ELSEIF (v < 34) THEN SET v = 34;
+  ELSEIF (v < 35) THEN SET v = 35;
+  ELSEIF (v < 36) THEN SET v = 36;
+  ELSEIF (v < 37) THEN SET v = 37;
+  ELSEIF (v < 38) THEN SET v = 38;
+  ELSEIF (v < 39) THEN SET v = 39;
+  END IF;
+END $$
+
+delimiter ;$$
+
+drop procedure p_37228;
+
+

=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc	2008-05-09 07:43:02 +0000
+++ b/sql/event_data_objects.cc	2008-07-15 01:43:12 +0000
@@ -1439,10 +1439,10 @@ Event_job_data::execute(THD *thd, bool d
   thd->query_length= sp_sql.length();
 
   {
-    Lex_input_stream lip(thd, thd->query, thd->query_length);
+    Parser_state parser_state(thd, thd->query, thd->query_length);
     lex_start(thd);
 
-    if (parse_sql(thd, &lip, creation_ctx))
+    if (parse_sql(thd, & parser_state, creation_ctx))
     {
       sql_print_error("Event Scheduler: "
                       "%serror during compilation of %s.%s",

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2008-02-07 10:47:39 +0000
+++ b/sql/event_db_repository.cc	2008-07-15 17:46:02 +0000
@@ -452,7 +452,7 @@ Event_db_repository::table_scan_all_for_
   READ_RECORD read_record_info;
   DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
 
-  init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
+  init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE);
 
   /*
     rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@@ -925,7 +925,7 @@ Event_db_repository::drop_events_by_fiel
     DBUG_VOID_RETURN;
 
   /* only enabled events are in memory, so we go now and delete the rest */
-  init_read_record(&read_record_info, thd, table, NULL, 1, 0);
+  init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE);
   while (!ret && !(read_record_info.read_record(&read_record_info)) )
   {
     char *et_field= get_field(thd->mem_root, table->field[field]);

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2008-05-09 07:43:02 +0000
+++ b/sql/events.cc	2008-07-15 17:46:02 +0000
@@ -1149,7 +1149,7 @@ Events::load_events_from_db(THD *thd)
     DBUG_RETURN(TRUE);
   }
 
-  init_read_record(&read_record_info, thd, table, NULL, 0, 1);
+  init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE);
   while (!(read_record_info.read_record(&read_record_info)))
   {
     Event_queue_element *et;

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2008-03-12 08:21:12 +0000
+++ b/sql/filesort.cc	2008-07-17 18:26:55 +0000
@@ -410,6 +410,56 @@ static uchar *read_buffpek_from_file(IO_
   DBUG_RETURN(tmp);
 }
 
+#ifndef DBUG_OFF
+/*
+  Print a text, SQL-like record representation into dbug trace.
+
+  Note: this function is a work in progress: at the moment
+   - column read bitmap is ignored (can print garbage for unused columns)
+   - there is no quoting
+*/
+static void dbug_print_record(TABLE *table, bool print_rowid)
+{
+  char buff[1024];
+  Field **pfield;
+  String tmp(buff,sizeof(buff),&my_charset_bin);
+  DBUG_LOCK_FILE;
+  
+  fprintf(DBUG_FILE, "record (");
+  for (pfield= table->field; *pfield ; pfield++)
+    fprintf(DBUG_FILE, "%s%s", (*pfield)->field_name, (pfield[1])? ", ":"");
+  fprintf(DBUG_FILE, ") = ");
+
+  fprintf(DBUG_FILE, "(");
+  for (pfield= table->field; *pfield ; pfield++)
+  {
+    Field *field=  *pfield;
+
+    if (field->is_null())
+      fwrite("NULL", sizeof(char), 4, DBUG_FILE);
+   
+    if (field->type() == MYSQL_TYPE_BIT)
+      (void) field->val_int_as_str(&tmp, 1);
+    else
+      field->val_str(&tmp);
+
+    fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
+    if (pfield[1])
+      fwrite(", ", sizeof(char), 2, DBUG_FILE);
+  }
+  fprintf(DBUG_FILE, ")");
+  if (print_rowid)
+  {
+    fprintf(DBUG_FILE, " rowid ");
+    for (uint i=0; i < table->file->ref_length; i++)
+    {
+      fprintf(DBUG_FILE, "%x", (uchar)table->file->ref[i]);
+    }
+  }
+  fprintf(DBUG_FILE, "\n");
+  DBUG_UNLOCK_FILE;
+}
+#endif 
 
 /**
   Search after sort_keys and write them into tempfile.
@@ -488,13 +538,10 @@ static ha_rows find_all_keys(SORTPARAM *
 		    current_thd->variables.read_buff_size);
   }
 
-  READ_RECORD read_record_info;
   if (quick_select)
   {
     if (select->quick->reset())
       DBUG_RETURN(HA_POS_ERROR);
-    init_read_record(&read_record_info, current_thd, select->quick->head,
-                     select, 1, 1);
   }
 
   /* Remember original bitmaps */
@@ -514,12 +561,13 @@ static ha_rows find_all_keys(SORTPARAM *
   {
     if (quick_select)
     {
-      if ((error= read_record_info.read_record(&read_record_info)))
+      if ((error= select->quick->get_next()))
       {
         error= HA_ERR_END_OF_FILE;
         break;
       }
       file->position(sort_form->record[0]);
+      DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
     }
     else					/* Not quick-select */
     {
@@ -576,15 +624,7 @@ static ha_rows find_all_keys(SORTPARAM *
     if (thd->is_error())
       break;
   }
-  if (quick_select)
-  {
-    /*
-      index_merge quick select uses table->sort when retrieving rows, so free
-      resoures it has allocated.
-    */
-    end_read_record(&read_record_info);
-  }
-  else
+  if (!quick_select)
   {
     (void) file->extra(HA_EXTRA_NO_CACHE);	/* End cacheing of records */
     if (!next_pos)

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2008-03-28 18:20:21 +0000
+++ b/sql/item_cmpfunc.cc	2008-07-15 12:12:08 +0000
@@ -3758,6 +3758,7 @@ longlong Item_func_in::val_int()
     return (longlong) (!null_value && tmp != negated);
   }
 
+  have_null= 0;
   for (uint i= 1 ; i < arg_count ; i++)
   {
     Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
@@ -3766,9 +3767,8 @@ longlong Item_func_in::val_int()
     if (!(value_added_map & (1 << (uint)cmp_type)))
     {
       in_item->store_value(args[0]);
-      if ((null_value=args[0]->null_value))
+      if ((null_value= args[0]->null_value))
         return 0;
-      have_null= 0;
       value_added_map|= 1 << (uint)cmp_type;
     }
     if (!in_item->cmp(args[i]) && !args[i]->null_value)

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2008-05-21 12:44:30 +0000
+++ b/sql/log.cc	2008-07-22 10:41:55 +0000
@@ -3070,6 +3070,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
   int ret = 0;
   bool exit_loop= 0;
   LOG_INFO log_info;
+  THD *thd= current_thd;
   DBUG_ENTER("purge_logs");
   DBUG_PRINT("info",("to_log= %s",to_log));
 
@@ -3095,10 +3096,13 @@ int MYSQL_BIN_LOG::purge_logs(const char
         /*
           It's not fatal if we can't stat a log file that does not exist;
           If we could not stat, we won't delete.
-        */     
-        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
-                            log_info.log_file_name);
+        */
+        if (thd)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+                              log_info.log_file_name);
+        }
         sql_print_information("Failed to execute my_stat on file '%s'",
 			      log_info.log_file_name);
         my_errno= 0;
@@ -3108,13 +3112,24 @@ int MYSQL_BIN_LOG::purge_logs(const char
         /*
           Other than ENOENT are fatal
         */
-        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-                            ER_BINLOG_PURGE_FATAL_ERR,
-                            "a problem with getting info on being purged %s; "
-                            "consider examining correspondence "
-                            "of your binlog index file "
-                            "to the actual binlog files",
-                            log_info.log_file_name);
+        if (thd)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+                              ER_BINLOG_PURGE_FATAL_ERR,
+                              "a problem with getting info on being purged %s; "
+                              "consider examining correspondence "
+                              "of your binlog index file "
+                              "to the actual binlog files",
+                              log_info.log_file_name);
+        }
+        else
+        {
+          sql_print_information("Failed to delete log file '%s'; "
+                                "consider examining correspondence "
+                                "of your binlog index file "
+                                "to the actual binlog files",
+                                log_info.log_file_name);
+        }
         error= LOG_INFO_FATAL;
         goto err;
       }
@@ -3131,27 +3146,42 @@ int MYSQL_BIN_LOG::purge_logs(const char
       {
         if (my_errno == ENOENT) 
         {
-          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
-                              log_info.log_file_name);
+          if (thd)
+          {
+            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                                ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+                                log_info.log_file_name);
+          }
           sql_print_information("Failed to delete file '%s'",
                                 log_info.log_file_name);
           my_errno= 0;
         }
         else
         {
-          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-                              ER_BINLOG_PURGE_FATAL_ERR,
-                              "a problem with deleting %s; "
-                              "consider examining correspondence "
-                              "of your binlog index file "
-                              "to the actual binlog files",
-                              log_info.log_file_name);
+          if (thd)
+          {
+            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+                                ER_BINLOG_PURGE_FATAL_ERR,
+                                "a problem with deleting %s; "
+                                "consider examining correspondence "
+                                "of your binlog index file "
+                                "to the actual binlog files",
+                                log_info.log_file_name);
+          }
+          else
+          {
+            sql_print_information("Failed to delete file '%s'; "
+                                  "consider examining correspondence "
+                                  "of your binlog index file "
+                                  "to the actual binlog files",
+                                  log_info.log_file_name);
+          }
           if (my_errno == EMFILE)
           {
             DBUG_PRINT("info",
                        ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
             error= LOG_INFO_EMFILE;
+            goto err;
           }
           error= LOG_INFO_FATAL;
           goto err;
@@ -3204,7 +3234,8 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
   int error;
   LOG_INFO log_info;
   MY_STAT stat_area;
-
+  THD *thd= current_thd;
+  
   DBUG_ENTER("purge_logs_before_date");
 
   pthread_mutex_lock(&LOCK_index);
@@ -3226,12 +3257,15 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
       {
         /*
           It's not fatal if we can't stat a log file that does not exist.
-        */     
-        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
-                            log_info.log_file_name);
-	sql_print_information("Failed to execute my_stat on file '%s'",
-			      log_info.log_file_name);
+        */
+        if (thd)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+                              log_info.log_file_name);
+        }
+        sql_print_information("Failed to execute my_stat on file '%s'",
+                              log_info.log_file_name);
         my_errno= 0;
       }
       else
@@ -3239,13 +3273,21 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
         /*
           Other than ENOENT are fatal
         */
-        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-                            ER_BINLOG_PURGE_FATAL_ERR,
-                            "a problem with getting info on being purged %s; "
-                            "consider examining correspondence "
-                            "of your binlog index file "
-                            "to the actual binlog files",
-                            log_info.log_file_name);
+        if (thd)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+                              ER_BINLOG_PURGE_FATAL_ERR,
+                              "a problem with getting info on being purged %s; "
+                              "consider examining correspondence "
+                              "of your binlog index file "
+                              "to the actual binlog files",
+                              log_info.log_file_name);
+        }
+        else
+        {
+          sql_print_information("Failed to delete log file '%s'",
+                                log_info.log_file_name);
+        }
         error= LOG_INFO_FATAL;
         goto err;
       }
@@ -3259,22 +3301,33 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
         if (my_errno == ENOENT) 
         {
           /* It's not fatal even if we can't delete a log file */
-          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
-                              log_info.log_file_name);
+          if (thd)
+          {
+            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                                ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
+                                log_info.log_file_name);
+          }
           sql_print_information("Failed to delete file '%s'",
                                 log_info.log_file_name);
           my_errno= 0;
         }
         else
         {
-          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-                              ER_BINLOG_PURGE_FATAL_ERR,
-                              "a problem with deleting %s; "
-                              "consider examining correspondence "
-                              "of your binlog index file "
-                              "to the actual binlog files",
-                              log_info.log_file_name);
+          if (thd)
+          {
+            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+                                ER_BINLOG_PURGE_FATAL_ERR,
+                                "a problem with deleting %s; "
+                                "consider examining correspondence "
+                                "of your binlog index file "
+                                "to the actual binlog files",
+                                log_info.log_file_name);
+          }
+          else
+          {
+            sql_print_information("Failed to delete log file '%s'",
+                                  log_info.log_file_name); 
+          }
           error= LOG_INFO_FATAL;
           goto err;
         }

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-05-20 07:29:16 +0000
+++ b/sql/mysql_priv.h	2008-07-17 18:26:55 +0000
@@ -44,6 +44,8 @@
 #include "sql_plugin.h"
 #include "scheduler.h"
 
+class Parser_state;
+
 /**
   Query type constants.
 
@@ -804,8 +806,8 @@ bool check_string_char_length(LEX_STRING
 bool test_if_data_home_dir(const char *dir);
 
 bool parse_sql(THD *thd,
-               class Lex_input_stream *lip,
-               class Object_creation_ctx *creation_ctx);
+               Parser_state *parser_state,
+               Object_creation_ctx *creation_ctx);
 
 enum enum_mysql_completiontype {
   ROLLBACK_RELEASE=-2, ROLLBACK=1,  ROLLBACK_AND_CHAIN=7,
@@ -2173,8 +2175,8 @@ ulonglong get_datetime_value(THD *thd, I
 int test_if_number(char *str,int *res,bool allow_wildcards);
 void change_byte(uchar *,uint,char,char);
 void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
-		      SQL_SELECT *select,
-		      int use_record_cache, bool print_errors);
+		      SQL_SELECT *select, int use_record_cache, 
+                      bool print_errors, bool disable_rr_cache);
 void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, 
                           bool print_error, uint idx);
 void end_read_record(READ_RECORD *info);

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2008-04-14 10:58:53 +0000
+++ b/sql/opt_range.cc	2008-07-17 18:28:42 +0000
@@ -7936,6 +7936,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
   handler *file= head->file;
   DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
 
+  /* We're going to just read rowids. */
   file->extra(HA_EXTRA_KEYREAD);
   head->prepare_for_position();
 
@@ -7994,15 +7995,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
 
   }
 
-  DBUG_PRINT("info", ("ok"));
-  /* ok, all row ids are in Unique */
+  /*
+    Ok all rowids are in the Unique now. The next call will initialize
+    head->sort structure so it can be used to iterate through the rowids
+    sequence.
+  */
   result= unique->get(head);
   delete unique;
   doing_pk_scan= FALSE;
   /* index_merge currently doesn't support "using index" at all */
   file->extra(HA_EXTRA_NO_KEYREAD);
-  /* start table scan */
-  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
+  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
   DBUG_RETURN(result);
 }
 
@@ -8028,6 +8031,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
   {
     result= HA_ERR_END_OF_FILE;
     end_read_record(&read_record);
+    free_io_cache(head);
     /* All rows from Unique have been retrieved, do a clustered PK scan */
     if (pk_quick_select)
     {
@@ -8556,7 +8560,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
 
 QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
                                      uint used_key_parts_arg)
- :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
+ :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
+  used_key_parts (used_key_parts_arg)
 {
   QUICK_RANGE *r;
 
@@ -8598,10 +8603,11 @@ int QUICK_SELECT_DESC::get_next()
     int result;
     if (last_range)
     {						// Already read through key
-      result = ((last_range->flag & EQ_RANGE)
-		? file->index_next_same(record, last_range->min_key,
-					last_range->min_length) :
-		file->index_prev(record));
+      result = ((last_range->flag & EQ_RANGE && 
+                 used_key_parts <= head->key_info[index].key_parts) ? 
+                file->index_next_same(record, last_range->min_key,
+                                      last_range->min_length) :
+                file->index_prev(record));
       if (!result)
       {
 	if (cmp_prev(*rev_it.ref()) == 0)
@@ -8625,7 +8631,9 @@ int QUICK_SELECT_DESC::get_next()
       continue;
     }
 
-    if (last_range->flag & EQ_RANGE)
+    if (last_range->flag & EQ_RANGE &&
+        used_key_parts <= head->key_info[index].key_parts)
+
     {
       result = file->index_read_map(record, last_range->max_key,
                                     last_range->max_keypart_map,
@@ -8634,6 +8642,8 @@ int QUICK_SELECT_DESC::get_next()
     else
     {
       DBUG_ASSERT(last_range->flag & NEAR_MAX ||
+                  (last_range->flag & EQ_RANGE && 
+                   used_key_parts > head->key_info[index].key_parts) ||
                   range_reads_after_key(last_range));
       result=file->index_read_map(record, last_range->max_key,
                                   last_range->max_keypart_map,
@@ -8731,54 +8741,6 @@ bool QUICK_SELECT_DESC::range_reads_afte
 }
 
 
-/* TRUE if we are reading over a key that may have a NULL value */
-
-#ifdef NOT_USED
-bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
-					   uint used_key_parts)
-{
-  uint offset, end;
-  KEY_PART *key_part = key_parts,
-           *key_part_end= key_part+used_key_parts;
-
-  for (offset= 0,  end = min(range_arg->min_length, range_arg->max_length) ;
-       offset < end && key_part != key_part_end ;
-       offset+= key_part++->store_length)
-  {
-    if (!memcmp((char*) range_arg->min_key+offset,
-		(char*) range_arg->max_key+offset,
-		key_part->store_length))
-      continue;
-
-    if (key_part->null_bit && range_arg->min_key[offset])
-      return 1;				// min_key is null and max_key isn't
-    // Range doesn't cover NULL. This is ok if there is no more null parts
-    break;
-  }
-  /*
-    If the next min_range is > NULL, then we can use this, even if
-    it's a NULL key
-    Example:  SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
-
-  */
-  if (key_part != key_part_end && key_part->null_bit)
-  {
-    if (offset >= range_arg->min_length || range_arg->min_key[offset])
-      return 1;					// Could be null
-    key_part++;
-  }
-  /*
-    If any of the key parts used in the ORDER BY could be NULL, we can't
-    use the key to sort the data.
-  */
-  for (; key_part != key_part_end ; key_part++)
-    if (key_part->null_bit)
-      return 1;					// Covers null part
-  return 0;
-}
-#endif
-
-
 void QUICK_RANGE_SELECT::add_info_string(String *str)
 {
   KEY *key_info= head->key_info + index;

=== modified file 'sql/opt_range.h'
--- a/sql/opt_range.h	2007-11-06 18:57:51 +0000
+++ b/sql/opt_range.h	2008-07-17 15:51:24 +0000
@@ -686,12 +686,10 @@ public:
   int get_type() { return QS_TYPE_RANGE_DESC; }
 private:
   bool range_reads_after_key(QUICK_RANGE *range);
-#ifdef NOT_USED
-  bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
-#endif
   int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
   List<QUICK_RANGE> rev_ranges;
   List_iterator<QUICK_RANGE> rev_it;
+  uint used_key_parts;
 };
 
 

=== modified file 'sql/records.cc'
--- a/sql/records.cc	2007-12-14 15:52:10 +0000
+++ b/sql/records.cc	2008-07-17 18:26:55 +0000
@@ -86,6 +86,23 @@ void init_read_record_idx(READ_RECORD *i
   The temporary file is normally used when the references doesn't fit into
   a properly sized memory buffer. For most small queries the references
   are stored in the memory buffer.
+  SYNOPSIS
+    init_read_record()
+      info              OUT read structure
+      thd               Thread handle
+      table             Table the data [originally] comes from.
+      select            SQL_SELECT structure. We may select->quick or 
+                        select->file as data source
+      use_record_cache  Call file->extra_opt(HA_EXTRA_CACHE,...)
+                        if we're going to do sequential read and some
+                        additional conditions are satisfied.
+      print_error       Copy this to info->print_error
+      disable_rr_cache  Don't use rr_from_cache (used by sort-union
+                        index-merge which produces rowid sequences that 
+                        are already ordered)
+
+  DESCRIPTION
+    This function sets up reading data via one of the methods:
 
   The temporary file is also used when performing an update where a key is
   modified.
@@ -140,7 +157,8 @@ void init_read_record_idx(READ_RECORD *i
 */
 void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
 		      SQL_SELECT *select,
-		      int use_record_cache, bool print_error)
+		      int use_record_cache, bool print_error, 
+                      bool disable_rr_cache)
 {
   IO_CACHE *tempfile;
   DBUG_ENTER("init_read_record");
@@ -191,7 +209,8 @@ void init_read_record(READ_RECORD *info,
       it doesn't make sense to use cache - we don't read from the table
       and table->sort.io_cache is read sequentially
     */
-    if (!table->sort.addon_field &&
+    if (!disable_rr_cache &&
+        !table->sort.addon_field &&
         ! (specialflag & SPECIAL_SAFE_MODE) &&
 	thd->variables.read_rnd_buff_size &&
 	!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2008-05-20 07:38:17 +0000
+++ b/sql/sp.cc	2008-07-15 01:43:12 +0000
@@ -617,12 +617,12 @@ db_load_routine(THD *thd, int type, sp_n
   thd->spcont= NULL;
 
   {
-    Lex_input_stream lip(thd, defstr.c_ptr(), defstr.length());
+    Parser_state parser_state(thd, defstr.c_ptr(), defstr.length());
 
     lex_start(thd);
 
     thd->push_internal_handler(&warning_handler);
-    ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL;
+    ret= parse_sql(thd, & parser_state, creation_ctx) || newlex.sphead == NULL;
     thd->pop_internal_handler();
 
     /*

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2008-05-20 07:38:17 +0000
+++ b/sql/sp_head.cc	2008-07-15 01:43:12 +0000
@@ -627,14 +627,14 @@ void
 sp_head::set_body_start(THD *thd, const char *begin_ptr)
 {
   m_body_begin= begin_ptr;
-  thd->m_lip->body_utf8_start(thd, begin_ptr);
+  thd->m_parser_state->m_lip.body_utf8_start(thd, begin_ptr);
 }
 
 
 void
 sp_head::set_stmt_end(THD *thd)
 {
-  Lex_input_stream *lip= thd->m_lip; /* shortcut */
+  Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
   const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
 
   /* Make the string of parameters. */

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2008-04-19 10:58:37 +0000
+++ b/sql/sql_acl.cc	2008-07-17 18:26:55 +0000
@@ -324,7 +324,8 @@ static my_bool acl_load(THD *thd, TABLE_
   acl_cache->clear(1);				// Clear locked hostname cache
 
   init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
-  init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, 
+                   FALSE);
   table->use_all_columns();
   VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
   while (!(read_record_info.read_record(&read_record_info)))
@@ -373,7 +374,7 @@ static my_bool acl_load(THD *thd, TABLE_
   end_read_record(&read_record_info);
   freeze_size(&acl_hosts);
 
-  init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE);
   table->use_all_columns();
   VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100));
   password_length= table->field[2]->field_length /
@@ -561,7 +562,7 @@ static my_bool acl_load(THD *thd, TABLE_
   end_read_record(&read_record_info);
   freeze_size(&acl_users);
 
-  init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE);
   table->use_all_columns();
   VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
   while (!(read_record_info.read_record(&read_record_info)))

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-06-19 18:47:59 +0000
+++ b/sql/sql_class.cc	2008-07-15 01:43:12 +0000
@@ -529,7 +529,7 @@ THD::THD()
    bootstrap(0),
    derived_tables_processing(FALSE),
    spcont(NULL),
-   m_lip(NULL)
+   m_parser_state(NULL)
 {
   ulong tmp;
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2008-05-20 07:38:17 +0000
+++ b/sql/sql_class.h	2008-07-15 01:43:12 +0000
@@ -75,7 +75,7 @@ class Load_log_event;
 class Slave_log_event;
 class sp_rcontext;
 class sp_cache;
-class Lex_input_stream;
+class Parser_state;
 class Rows_log_event;
 
 enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
@@ -1771,13 +1771,11 @@ public:
   } binlog_evt_union;
 
   /**
-    Character input stream consumed by the lexical analyser,
-    used during parsing.
-    Note that since the parser is not re-entrant, we keep only one input
-    stream here. This member is valid only when executing code during parsing,
-    and may point to invalid memory after that.
+    Internal parser state.
+    Note that since the parser is not re-entrant, we keep only one parser
+    state here. This member is valid only when executing code during parsing.
   */
-  Lex_input_stream *m_lip;
+  Parser_state *m_parser_state;
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   partition_info *work_part_info;

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2008-03-27 12:07:01 +0000
+++ b/sql/sql_delete.cc	2008-07-17 18:26:55 +0000
@@ -245,7 +245,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     DBUG_RETURN(TRUE);
   }
   if (usable_index==MAX_KEY)
-    init_read_record(&info,thd,table,select,1,1);
+    init_read_record(&info, thd, table, select, 1, 1, FALSE);
   else
     init_read_record_idx(&info, thd, table, 1, usable_index);
 
@@ -834,7 +834,7 @@ int multi_delete::do_deletes()
     }
 
     READ_RECORD	info;
-    init_read_record(&info,thd,table,NULL,0,1);
+    init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
     /*
       Ignore any rows not found in reference tables as they may already have
       been deleted by foreign key handling

=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc	2008-02-19 12:58:08 +0000
+++ b/sql/sql_help.cc	2008-07-17 18:26:55 +0000
@@ -186,7 +186,7 @@ int search_topics(THD *thd, TABLE *topic
   int count= 0;
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, topics, select,1,0);
+  init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (!select->cond->val_int())		// Doesn't match like
@@ -226,7 +226,7 @@ int search_keyword(THD *thd, TABLE *keyw
   int count= 0;
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, keywords, select,1,0);
+  init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE);
   while (!read_record_info.read_record(&read_record_info) && count<2)
   {
     if (!select->cond->val_int())		// Dosn't match like
@@ -350,7 +350,7 @@ int search_categories(THD *thd, TABLE *c
 
   DBUG_ENTER("search_categories");
 
-  init_read_record(&read_record_info, thd, categories, select,1,0);
+  init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (select && !select->cond->val_int())
@@ -384,7 +384,7 @@ void get_all_items_for_category(THD *thd
   DBUG_ENTER("get_all_items_for_category");
 
   READ_RECORD read_record_info;
-  init_read_record(&read_record_info, thd, items, select,1,0);
+  init_read_record(&read_record_info, thd, items, select,1,0,FALSE);
   while (!read_record_info.read_record(&read_record_info))
   {
     if (!select->cond->val_int())

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2008-07-07 21:53:20 +0000
+++ b/sql/sql_lex.cc	2008-07-15 01:43:12 +0000
@@ -371,13 +371,6 @@ void lex_end(LEX *lex)
 {
   DBUG_ENTER("lex_end");
   DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
-  if (lex->yacc_yyss)
-  {
-    my_free(lex->yacc_yyss, MYF(0));
-    my_free(lex->yacc_yyvs, MYF(0));
-    lex->yacc_yyss= 0;
-    lex->yacc_yyvs= 0;
-  }
 
   /* release used plugins */
   plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, 
@@ -387,6 +380,14 @@ void lex_end(LEX *lex)
   DBUG_VOID_RETURN;
 }
 
+Yacc_state::~Yacc_state()
+{
+  if (yacc_yyss)
+  {
+    my_free(yacc_yyss, MYF(0));
+    my_free(yacc_yyvs, MYF(0));
+  }
+}
 
 static int find_keyword(Lex_input_stream *lip, uint len, bool function)
 {
@@ -726,7 +727,7 @@ int MYSQLlex(void *arg, void *yythd)
   uint length;
   enum my_lex_states state;
   THD *thd= (THD *)yythd;
-  Lex_input_stream *lip= thd->m_lip;
+  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
   LEX *lex= thd->lex;
   YYSTYPE *yylval=(YYSTYPE*) arg;
   CHARSET_INFO *cs= thd->charset();
@@ -2128,7 +2129,7 @@ void Query_tables_list::destroy_query_ta
 */
 
 st_lex::st_lex()
-  :result(0), yacc_yyss(0), yacc_yyvs(0),
+  :result(0),
    sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
 {
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2008-03-28 15:09:14 +0000
+++ b/sql/sql_lex.h	2008-07-15 01:43:12 +0000
@@ -1513,7 +1513,6 @@ typedef struct st_lex : public Query_tab
   LEX_STRING comment, ident;
   LEX_USER *grant_user;
   XID *xid;
-  uchar* yacc_yyss, *yacc_yyvs;
   THD *thd;
 
   /* maintain a list of used plugins for this LEX */
@@ -1847,6 +1846,59 @@ typedef struct st_lex : public Query_tab
   }
 } LEX;
 
+
+/**
+  The internal state of the syntax parser.
+  This object is only available during parsing,
+  and is private to the syntax parser implementation (sql_yacc.yy).
+*/
+class Yacc_state
+{
+public:
+  Yacc_state()
+    : yacc_yyss(NULL), yacc_yyvs(NULL)
+  {}
+
+  ~Yacc_state();
+
+  /**
+    Bison internal state stack, yyss, when dynamically allocated using
+    my_yyoverflow().
+  */
+  uchar *yacc_yyss;
+
+  /**
+    Bison internal semantic value stack, yyvs, when dynamically allocated using
+    my_yyoverflow().
+  */
+  uchar *yacc_yyvs;
+
+  /*
+    TODO: move more attributes from the LEX structure here.
+  */
+};
+
+/**
+  Internal state of the parser.
+  The complete state consist of:
+  - state data used during lexical parsing,
+  - state data used during syntactic parsing.
+*/
+class Parser_state
+{
+public:
+  Parser_state(THD *thd, const char* buff, unsigned int length)
+    : m_lip(thd, buff, length), m_yacc()
+  {}
+
+  ~Parser_state()
+  {}
+
+  Lex_input_stream m_lip;
+  Yacc_state m_yacc;
+};
+
+
 struct st_lex_local: public st_lex
 {
   static void *operator new(size_t size) throw()

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-07-07 21:53:20 +0000
+++ b/sql/sql_parse.cc	2008-07-15 01:43:12 +0000
@@ -5323,29 +5323,35 @@ bool check_stack_overrun(THD *thd, long 
 
 bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
 {
-  LEX	*lex= current_thd->lex;
+  Yacc_state *state= & current_thd->m_parser_state->m_yacc;
   ulong old_info=0;
+  DBUG_ASSERT(state);
   if ((uint) *yystacksize >= MY_YACC_MAX)
     return 1;
-  if (!lex->yacc_yyvs)
+  if (!state->yacc_yyvs)
     old_info= *yystacksize;
   *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
-  if (!(lex->yacc_yyvs= (uchar*)
-	my_realloc(lex->yacc_yyvs,
-		   *yystacksize*sizeof(**yyvs),
-		   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
-      !(lex->yacc_yyss= (uchar*)
-	my_realloc(lex->yacc_yyss,
-		   *yystacksize*sizeof(**yyss),
-		   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
+  if (!(state->yacc_yyvs= (uchar*)
+        my_realloc(state->yacc_yyvs,
+                   *yystacksize*sizeof(**yyvs),
+                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
+      !(state->yacc_yyss= (uchar*)
+        my_realloc(state->yacc_yyss,
+                   *yystacksize*sizeof(**yyss),
+                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
     return 1;
   if (old_info)
-  {						// Copy old info from stack
-    memcpy(lex->yacc_yyss, (uchar*) *yyss, old_info*sizeof(**yyss));
-    memcpy(lex->yacc_yyvs, (uchar*) *yyvs, old_info*sizeof(**yyvs));
+  {
+    /*
+      Only copy the old stack on the first call to my_yyoverflow(),
+      when replacing a static stack (YYINITDEPTH) by a dynamic stack.
+      For subsequent calls, my_realloc already did preserve the old stack.
+    */
+    memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
+    memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
   }
-  *yyss=(short*) lex->yacc_yyss;
-  *yyvs=(YYSTYPE*) lex->yacc_yyvs;
+  *yyss= (short*) state->yacc_yyss;
+  *yyvs= (YYSTYPE*) state->yacc_yyvs;
   return 0;
 }
 
@@ -5609,10 +5615,10 @@ void mysql_parse(THD *thd, const char *i
     sp_cache_flush_obsolete(&thd->sp_proc_cache);
     sp_cache_flush_obsolete(&thd->sp_func_cache);
 
-    Lex_input_stream lip(thd, inBuf, length);
+    Parser_state parser_state(thd, inBuf, length);
 
-    bool err= parse_sql(thd, &lip, NULL);
-    *found_semicolon= lip.found_semicolon;
+    bool err= parse_sql(thd, & parser_state, NULL);
+    *found_semicolon= parser_state.m_lip.found_semicolon;
 
     if (!err)
     {
@@ -5697,11 +5703,11 @@ bool mysql_test_parse_for_slave(THD *thd
   bool error= 0;
   DBUG_ENTER("mysql_test_parse_for_slave");
 
-  Lex_input_stream lip(thd, inBuf, length);
+  Parser_state parser_state(thd, inBuf, length);
   lex_start(thd);
   mysql_reset_thd_for_next_command(thd);
 
-  if (!parse_sql(thd, &lip, NULL) &&
+  if (!parse_sql(thd, & parser_state, NULL) &&
       all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
     error= 1;                  /* Ignore question */
   thd->end_statement();
@@ -6740,7 +6746,7 @@ bool check_simple_select()
   if (lex->current_select != &lex->select_lex)
   {
     char command[80];
-    Lex_input_stream *lip= thd->m_lip;
+    Lex_input_stream *lip= & thd->m_parser_state->m_lip;
     strmake(command, lip->yylval->symbol.str,
 	    min(lip->yylval->symbol.length, sizeof(command)-1));
     my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
@@ -7417,7 +7423,7 @@ extern int MYSQLparse(void *thd); // fro
   instead of MYSQLparse().
 
   @param thd Thread context.
-  @param lip Lexer context.
+  @param parser_state Parser state.
   @param creation_ctx Object creation context.
 
   @return Error status.
@@ -7426,10 +7432,10 @@ extern int MYSQLparse(void *thd); // fro
 */
 
 bool parse_sql(THD *thd,
-               Lex_input_stream *lip,
+               Parser_state *parser_state,
                Object_creation_ctx *creation_ctx)
 {
-  DBUG_ASSERT(thd->m_lip == NULL);
+  DBUG_ASSERT(thd->m_parser_state == NULL);
 
   /* Backup creation context. */
 
@@ -7438,9 +7444,9 @@ bool parse_sql(THD *thd,
   if (creation_ctx)
     backup_ctx= creation_ctx->set_n_backup(thd);
 
-  /* Set Lex_input_stream. */
+  /* Set parser state. */
 
-  thd->m_lip= lip;
+  thd->m_parser_state= parser_state;
 
   /* Parse the query. */
 
@@ -7451,9 +7457,9 @@ bool parse_sql(THD *thd,
   DBUG_ASSERT(!mysql_parse_status ||
               mysql_parse_status && thd->is_error());
 
-  /* Reset Lex_input_stream. */
+  /* Reset parser state. */
 
-  thd->m_lip= NULL;
+  thd->m_parser_state= NULL;
 
   /* Restore creation context. */
 

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2008-03-07 21:46:29 +0000
+++ b/sql/sql_partition.cc	2008-07-15 01:43:12 +0000
@@ -3767,7 +3767,7 @@ bool mysql_unpack_partition(THD *thd,
   thd->lex= &lex;
   thd->variables.character_set_client= system_charset_info;
 
-  Lex_input_stream lip(thd, part_buf, part_info_len);
+  Parser_state parser_state(thd, part_buf, part_info_len);
 
   lex_start(thd);
   *work_part_info_used= false;
@@ -3797,7 +3797,7 @@ bool mysql_unpack_partition(THD *thd,
   lex.part_info->part_state= part_state;
   lex.part_info->part_state_len= part_state_len;
   DBUG_PRINT("info", ("Parse: %s", part_buf));
-  if (parse_sql(thd, &lip, NULL))
+  if (parse_sql(thd, & parser_state, NULL))
   {
     thd->free_items();
     goto end;

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2008-05-30 10:21:45 +0000
+++ b/sql/sql_plugin.cc	2008-07-15 17:46:02 +0000
@@ -1361,7 +1361,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
     goto end;
   }
   table= tables.table;
-  init_read_record(&read_record_info, new_thd, table, NULL, 1, 0);
+  init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE);
   table->use_all_columns();
   /*
     there're no other threads running yet, so we don't need a mutex.
@@ -1882,7 +1882,7 @@ static int check_func_bool(THD *thd, str
     }
     result= (int) tmp;
   }
-  *(int*)save= -result;
+  *(my_bool *) save= -result;
   return 0;
 err:
   my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
@@ -2063,7 +2063,7 @@ err:
 static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
                              void *tgt, const void *save)
 {
-  *(my_bool *) tgt= *(int *) save ? 1 : 0;
+  *(my_bool *) tgt= *(my_bool *) save ? TRUE : FALSE;
 }
 
 

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2008-07-03 19:41:22 +0000
+++ b/sql/sql_prepare.cc	2008-07-15 01:43:12 +0000
@@ -3017,11 +3017,11 @@ bool Prepared_statement::prepare(const c
   old_stmt_arena= thd->stmt_arena;
   thd->stmt_arena= this;
 
-  Lex_input_stream lip(thd, thd->query, thd->query_length);
-  lip.stmt_prepare_mode= TRUE;
+  Parser_state parser_state(thd, thd->query, thd->query_length);
+  parser_state.m_lip.stmt_prepare_mode= TRUE;
   lex_start(thd);
 
-  error= parse_sql(thd, &lip, NULL) ||
+  error= parse_sql(thd, & parser_state, NULL) ||
          thd->is_error() ||
          init_param_array(this);
 

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2008-06-27 18:54:16 +0000
+++ b/sql/sql_select.cc	2008-07-17 18:28:42 +0000
@@ -11713,7 +11713,7 @@ join_init_read_record(JOIN_TAB *tab)
   if (tab->select && tab->select->quick && tab->select->quick->reset())
     return 1;
   init_read_record(&tab->read_record, tab->join->thd, tab->table,
-		   tab->select,1,1);
+		   tab->select,1,1, FALSE);
   return (*tab->read_record.read_record)(&tab->read_record);
 }
 
@@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field
   @note
     used_key_parts is set to correct key parts used if return value != 0
     (On other cases, used_key_part may be changed)
+    Note that the value may actually be greater than the number of index 
+    key parts. This can happen for storage engines that have the primary 
+    key parts as a suffix for every secondary key.
 
   @retval
     1   key is ok.
@@ -12580,11 +12583,27 @@ static int test_if_order_by_key(ORDER *o
     reverse=flag;				// Remember if reverse
     key_part++;
   }
-  *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
-    (uint) (key_part - table->key_info[idx].key_part);
-  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
-                         HA_READ_PREV))
-    reverse= 0;                                 // Index can't be used
+  if (on_primary_key)
+  {
+    uint used_key_parts_secondary= table->key_info[idx].key_parts;
+    uint used_key_parts_pk=
+      (uint) (key_part - table->key_info[table->s->primary_key].key_part);
+    *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
+
+    if (reverse == -1 &&
+        (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
+           HA_READ_PREV) ||
+         !(table->file->index_flags(table->s->primary_key,
+                                    used_key_parts_pk - 1, 1) & HA_READ_PREV)))
+      reverse= 0;                               // Index can't be used
+  }
+  else
+  {
+    *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
+    if (reverse == -1 && 
+        !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
+      reverse= 0;                               // Index can't be used
+  }
   DBUG_RETURN(reverse);
 }
 

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2008-03-21 08:46:01 +0000
+++ b/sql/sql_servers.cc	2008-07-15 17:46:02 +0000
@@ -182,7 +182,8 @@ static bool servers_load(THD *thd, TABLE
   free_root(&mem, MYF(0));
   init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
 
-  init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0);
+  init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, 
+                   FALSE);
   while (!(read_record_info.read_record(&read_record_info)))
   {
     /* return_val is already TRUE, so no need to set */

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-06-25 09:44:55 +0000
+++ b/sql/sql_table.cc	2008-07-17 18:26:55 +0000
@@ -7113,7 +7113,7 @@ copy_data_between_tables(TABLE *from,TAB
 
   /* Tell handler that we have values for all columns in the to table */
   to->use_all_columns();
-  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
+  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
   if (ignore)
     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
   thd->row_count= 0;

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2008-02-19 12:45:21 +0000
+++ b/sql/sql_trigger.cc	2008-07-15 01:43:12 +0000
@@ -1287,7 +1287,9 @@ bool Table_triggers_list::check_n_load(T
 
         thd->variables.sql_mode= (ulong)*trg_sql_mode;
 
-        Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
+        Parser_state parser_state(thd,
+                                  trg_create_str->str,
+                                  trg_create_str->length);
 
         Trigger_creation_ctx *creation_ctx=
           Trigger_creation_ctx::create(thd,
@@ -1300,7 +1302,7 @@ bool Table_triggers_list::check_n_load(T
         lex_start(thd);
         thd->spcont= NULL;
 
-        if (parse_sql(thd, &lip, creation_ctx))
+        if (parse_sql(thd, & parser_state, creation_ctx))
         {
           /* Currently sphead is always deleted in case of a parse error */
           DBUG_ASSERT(lex.sphead == 0);

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2008-02-19 11:43:01 +0000
+++ b/sql/sql_udf.cc	2008-07-17 18:26:55 +0000
@@ -152,7 +152,7 @@ void udf_init()
   }
 
   table= tables.table;
-  init_read_record(&read_record_info, new_thd, table, NULL,1,0);
+  init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE);
   table->use_all_columns();
   while (!(error= read_record_info.read_record(&read_record_info)))
   {

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-05-20 07:38:17 +0000
+++ b/sql/sql_update.cc	2008-07-17 18:26:55 +0000
@@ -457,7 +457,7 @@ int mysql_update(THD *thd,
       */
 
       if (used_index == MAX_KEY || (select && select->quick))
-        init_read_record(&info,thd,table,select,0,1);
+        init_read_record(&info, thd, table, select, 0, 1, FALSE);
       else
         init_read_record_idx(&info, thd, table, 1, used_index);
 
@@ -523,7 +523,7 @@ int mysql_update(THD *thd,
   if (select && select->quick && select->quick->reset())
     goto err;
   table->file->try_semi_consistent_read(1);
-  init_read_record(&info,thd,table,select,0,1);
+  init_read_record(&info, thd, table, select, 0, 1, FALSE);
 
   updated= found= 0;
   /* Generate an error when trying to set a NOT NULL field to NULL. */

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2008-05-08 11:45:40 +0000
+++ b/sql/sql_view.cc	2008-07-15 01:43:12 +0000
@@ -1147,9 +1147,9 @@ bool mysql_make_view(THD *thd, File_pars
     char old_db_buf[NAME_LEN+1];
     LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
     bool dbchanged;
-    Lex_input_stream lip(thd,
-                         table->select_stmt.str,
-                         table->select_stmt.length);
+    Parser_state parser_state(thd,
+                              table->select_stmt.str,
+                              table->select_stmt.length);
 
     /* 
       Use view db name as thread default database, in order to ensure
@@ -1193,7 +1193,7 @@ bool mysql_make_view(THD *thd, File_pars
 
     /* Parse the query. */
 
-    parse_status= parse_sql(thd, &lip, table->view_creation_ctx);
+    parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
 
     /* Restore environment. */
 

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2008-07-07 21:53:20 +0000
+++ b/sql/sql_yacc.yy	2008-07-15 01:43:12 +0000
@@ -28,6 +28,7 @@
 #define YYPARSE_PARAM yythd
 #define YYLEX_PARAM yythd
 #define YYTHD ((THD *)yythd)
+#define YYLIP (& YYTHD->m_parser_state->m_lip)
 
 #define MYSQL_YACC
 #define YYINITDEPTH 100
@@ -121,7 +122,7 @@ const LEX_STRING null_lex_str= {0,0};
 void my_parse_error(const char *s)
 {
   THD *thd= current_thd;
-  Lex_input_stream *lip= thd->m_lip;
+  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
 
   const char *yytext= lip->get_tok_start();
   /* Push an error into the error stack */
@@ -1356,11 +1357,11 @@ query:
               MYSQL_YYABORT;
             }
             thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
-            thd->m_lip->found_semicolon= NULL;
+            YYLIP->found_semicolon= NULL;
           }
         | verb_clause
           {
-            Lex_input_stream *lip = YYTHD->m_lip;
+            Lex_input_stream *lip = YYLIP;
 
             if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
                 ! lip->stmt_prepare_mode &&
@@ -1386,7 +1387,7 @@ query:
         | verb_clause END_OF_INPUT
           {
             /* Single query, not terminated. */
-            YYTHD->m_lip->found_semicolon= NULL;
+            YYLIP->found_semicolon= NULL;
           }
         ;
 
@@ -1917,7 +1918,7 @@ ev_sql_stmt:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             /*
               This stops the following :
@@ -2574,7 +2575,7 @@ sp_proc_stmt_statement:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             lex->sphead->reset_lex(thd);
             lex->sphead->m_tmp_query= lip->get_tok_start();
@@ -2583,7 +2584,7 @@ sp_proc_stmt_statement:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
             sp_head *sp= lex->sphead;
 
             sp->m_flags|= sp_get_flags_for_command(lex);
@@ -6455,17 +6456,13 @@ select_item:
 
 remember_name:
           {
-            THD *thd= YYTHD;
-            Lex_input_stream *lip= thd->m_lip;
-            $$= (char*) lip->get_cpp_tok_start();
+            $$= (char*) YYLIP->get_cpp_tok_start();
           }
         ;
 
 remember_end:
           {
-            THD *thd= YYTHD;
-            Lex_input_stream *lip= thd->m_lip;
-            $$= (char*) lip->get_cpp_tok_end();
+            $$= (char*) YYLIP->get_cpp_tok_end();
           }
         ;
 
@@ -9645,7 +9642,7 @@ load:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             if (lex->sphead)
             {
@@ -9686,10 +9683,7 @@ load_data:
           }
           opt_duplicate INTO
           {
-            THD *thd= YYTHD;
-            LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
-            lex->fname_end= lip->get_ptr();
+            Lex->fname_end= YYLIP->get_ptr();
           }
           TABLE_SYM table_ident
           {
@@ -9924,7 +9918,7 @@ param_marker:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
             Item_param *item;
             if (! lex->parsing_options.allows_variable)
             {
@@ -9956,7 +9950,7 @@ literal:
         | NULL_SYM
           {
             $$ = new Item_null();
-            YYTHD->m_lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
+            YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
           }
         | FALSE_SYM { $$= new Item_int((char*) "FALSE",0,1); }
         | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); }
@@ -10086,7 +10080,7 @@ simple_ident:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
             sp_variable_t *spv;
             sp_pcontext *spc = lex->spcont;
             if (spc && (spv = spc->find_variable(&$1)))
@@ -10776,7 +10770,7 @@ option_type_value:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             if (lex->sphead)
             {
@@ -10807,7 +10801,7 @@ option_type_value:
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             if (lex->sphead)
             {
@@ -12076,19 +12070,17 @@ view_select:
           {
             THD *thd= YYTHD;
             LEX *lex= Lex;
-            Lex_input_stream *lip= thd->m_lip;
             lex->parsing_options.allows_variable= FALSE;
             lex->parsing_options.allows_select_into= FALSE;
             lex->parsing_options.allows_select_procedure= FALSE;
             lex->parsing_options.allows_derived= FALSE;
-            lex->create_view_select.str= (char *) lip->get_cpp_ptr();
+            lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr();
           }
           view_select_aux view_check_option
           {
             THD *thd= YYTHD;
             LEX *lex= Lex;
-            Lex_input_stream *lip= thd->m_lip;
-            uint len= lip->get_cpp_ptr() - lex->create_view_select.str;
+            uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
             void *create_view_select= thd->memdup(lex->create_view_select.str, len);
             lex->create_view_select.length= len;
             lex->create_view_select.str= (char *) create_view_select;
@@ -12131,26 +12123,20 @@ trigger_tail:
           ON
           remember_name /* $7 */
           { /* $8 */
-            THD *thd= YYTHD;
-            LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
-            lex->raw_trg_on_table_name_begin= lip->get_tok_start();
+            Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start();
           }
           table_ident /* $9 */
           FOR_SYM
           remember_name /* $11 */
           { /* $12 */
-            THD *thd= YYTHD;
-            LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
-            lex->raw_trg_on_table_name_end= lip->get_tok_start();
+            Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
           }
           EACH_SYM
           ROW_SYM
           { /* $15 */
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
             sp_head *sp;
 
             if (lex->sphead)
@@ -12254,7 +12240,7 @@ sf_tail:
           { /* $5 */
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
             sp_head *sp;
             const char* tmp_param_begin;
 
@@ -12282,11 +12268,7 @@ sf_tail:
           sp_fdparam_list /* $6 */
           ')' /* $7 */
           { /* $8 */
-            THD *thd= YYTHD;
-            LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
-
-            lex->sphead->m_param_end= lip->get_cpp_tok_start();
+            Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
           }
           RETURNS_SYM /* $9 */
           { /* $10 */
@@ -12323,7 +12305,7 @@ sf_tail:
           { /* $14 */
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
+            Lex_input_stream *lip= YYLIP;
 
             lex->sphead->m_chistics= &lex->sp_chistics;
             lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
@@ -12408,33 +12390,28 @@ sp_tail:
           }
           '('
           {
-            THD *thd= YYTHD;
-            LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
             const char* tmp_param_begin;
 
-            tmp_param_begin= lip->get_cpp_tok_start();
+            tmp_param_begin= YYLIP->get_cpp_tok_start();
             tmp_param_begin++;
-            lex->sphead->m_param_begin= tmp_param_begin;
+            Lex->sphead->m_param_begin= tmp_param_begin;
           }
           sp_pdparam_list
           ')'
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
 
-            lex->sphead->m_param_end= lip->get_cpp_tok_start();
+            lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
             bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
           }
           sp_c_chistics
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
-            Lex_input_stream *lip= thd->m_lip;
 
             lex->sphead->m_chistics= &lex->sp_chistics;
-            lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
+            lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
           }
           sp_proc_stmt
           {

Thread
bzr commit into mysql-5.1 branch (serg:2672) Sergei Golubchik22 Jul