MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:konstantin Date:August 2 2006 10:13am
Subject:bk commit into 5.0 tree (kostja:1.2231)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-08-02 14:13:01+04:00, kostja@stripped +24 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-5.0
  into  bodhi.local:/opt/local/work/mysql-5.0-runtime-merge
  MERGE: 1.2196.22.27

  include/mysql.h@stripped, 2006-08-02 14:06:11+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.158.1.1

  include/sql_common.h@stripped, 2006-08-02 14:06:12+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.14.1.2

  libmysql/libmysql.c@stripped, 2006-08-02 14:06:13+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.244.1.1

  mysql-test/mysql-test-run.pl@stripped, 2006-08-02 14:06:13+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.103.1.2

  mysql-test/r/mysqldump.result@stripped, 2006-08-02 14:06:13+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.100.3.1

  mysql-test/r/ps.result@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +77 -14
    Manual merge.
    MERGE: 1.67.1.2

  mysql-test/r/sp.result@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +15 -15
    Manual merge.
    MERGE: 1.202.1.2

  mysql-test/t/ps.test@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +36 -0
    Manual merge.
    MERGE: 1.65.1.1

  mysql-test/t/sp.test@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +0 -2
    Manual merge.
    MERGE: 1.190.1.1

  mysql-test/t/udf.test@stripped, 2006-08-02 14:06:13+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.5.1.1

  ndb/src/mgmsrv/ConfigInfo.cpp@stripped, 2006-08-02 14:06:13+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.77.1.1

  sql-common/client.c@stripped, 2006-08-02 14:06:16+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.93.1.1

  sql/item.cc@stripped, 2006-08-02 14:06:14+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.227.1.1

  sql/item_func.h@stripped, 2006-08-02 14:06:14+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.141.1.1

  sql/mysql_priv.h@stripped, 2006-08-02 14:06:14+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.398.1.2

  sql/slave.cc@stripped, 2006-08-02 14:06:14+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.273.1.1

  sql/sp.cc@stripped, 2006-08-02 14:06:14+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.113.1.2

  sql/sql_lex.cc@stripped, 2006-08-02 14:06:15+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.190.1.2

  sql/sql_parse.cc@stripped, 2006-08-02 14:06:15+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.560.1.3

  sql/sql_prepare.cc@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +1 -3
    Manual merge.
    MERGE: 1.178.1.1

  sql/sql_yacc.yy@stripped, 2006-08-02 14:06:16+04:00, kostja@stripped +0 -0
    Auto merged
    MERGE: 1.474.1.3

  sql/table.cc@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +0 -0
    Manual merge.
    MERGE: 1.227.1.2

  sql/table.h@stripped, 2006-08-02 14:06:16+04:00, kostja@stripped +0 -1
    Auto merged
    MERGE: 1.129.1.1

  tests/mysql_client_test.c@stripped, 2006-08-02 14:12:57+04:00, kostja@stripped +1 -1
    Manual merge.
    MERGE: 1.189.1.1

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	kostja
# Host:	bodhi.local
# Root:	/opt/local/work/mysql-5.0-runtime-merge/RESYNC

--- 1.159/include/mysql.h	2006-08-02 14:13:12 +04:00
+++ 1.160/include/mysql.h	2006-08-02 14:13:12 +04:00
@@ -848,7 +848,6 @@ int		STDCALL mysql_drop_db(MYSQL *mysql,
 #define stmt_command(mysql, command, arg, length, stmt) \
   (*(mysql)->methods->advanced_command)(mysql, command, NullS,  \
                                         0, arg, length, 1, stmt)
-unsigned long net_safe_read(MYSQL* mysql);
 
 #ifdef __NETWARE__
 #pragma pack(pop)		/* restore alignment */

--- 1.246/libmysql/libmysql.c	2006-08-02 14:13:12 +04:00
+++ 1.247/libmysql/libmysql.c	2006-08-02 14:13:12 +04:00
@@ -645,7 +645,7 @@ int cli_read_change_user_result(MYSQL *m
   NET *net= &mysql->net;
   ulong pkt_length;
 
-  pkt_length= net_safe_read(mysql);
+  pkt_length= cli_safe_read(mysql);
   
   if (pkt_length == packet_error)
     return 1;
@@ -666,7 +666,7 @@ int cli_read_change_user_result(MYSQL *m
       return 1;
     }
     /* Read what server thinks about out new auth message report */
-    if (net_safe_read(mysql) == packet_error)
+    if (cli_safe_read(mysql) == packet_error)
       return 1;
   }
   return 0;
@@ -1887,7 +1887,7 @@ my_bool cli_read_prepare_result(MYSQL *m
   DBUG_ENTER("cli_read_prepare_result");
 
   mysql= mysql->last_used_con;
-  if ((packet_length= net_safe_read(mysql)) == packet_error)
+  if ((packet_length= cli_safe_read(mysql)) == packet_error)
     DBUG_RETURN(1);
   mysql->warning_count= 0;
 
@@ -2505,7 +2505,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
 
   if (stmt->param_count)
   {
-    NET        *net= &stmt->mysql->net;
+    MYSQL *mysql= stmt->mysql;
+    NET        *net= &mysql->net;
     MYSQL_BIND *param, *param_end;
     char       *param_data;
     ulong length;
@@ -2517,7 +2518,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
       set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate);
       DBUG_RETURN(1);
     }
-    if (stmt->mysql->status != MYSQL_STATUS_READY)
+    if (mysql->status != MYSQL_STATUS_READY ||
+        mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
     {
       set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
       DBUG_RETURN(1);
@@ -4532,7 +4534,7 @@ static int stmt_fetch_row(MYSQL_STMT *st
 
 int cli_unbuffered_fetch(MYSQL *mysql, char **row)
 {
-  if (packet_error == net_safe_read(mysql))
+  if (packet_error == cli_safe_read(mysql))
     return 1;
 
   *row= ((mysql->net.read_pos[0] == 254) ? NULL :
@@ -4641,7 +4643,7 @@ int cli_read_binary_rows(MYSQL_STMT *stm
 
   mysql= mysql->last_used_con;
 
-  while ((pkt_len= net_safe_read(mysql)) != packet_error)
+  while ((pkt_len= cli_safe_read(mysql)) != packet_error)
   {
     cp= net->read_pos;
     if (cp[0] != 254 || pkt_len >= 8)

--- 1.228/sql/item.cc	2006-08-02 14:13:12 +04:00
+++ 1.229/sql/item.cc	2006-08-02 14:13:12 +04:00
@@ -1424,7 +1424,8 @@ bool agg_item_charsets(DTCollation &coll
     In case we're in statement prepare, create conversion item
     in its memory: it will be reused on each execute.
   */
-  arena= thd->activate_stmt_arena_if_needed(&backup);
+  arena= thd->is_stmt_prepare() ? thd->activate_stmt_arena_if_needed(&backup)
+                                : NULL;
 
   for (i= 0, arg= args; i < nargs; i++, arg+= item_sep)
   {
@@ -1459,7 +1460,7 @@ bool agg_item_charsets(DTCollation &coll
       been created in prepare. In this case register the change for
       rollback.
     */
-    if (arena && arena->is_conventional())
+    if (arena)
       *arg= conv;
     else
       thd->change_item_tree(arg, conv);

--- 1.142/sql/item_func.h	2006-08-02 14:13:12 +04:00
+++ 1.143/sql/item_func.h	2006-08-02 14:13:12 +04:00
@@ -156,7 +156,10 @@ public:
   {
     return (null_value=args[0]->get_time(ltime));
   }
-  bool is_null() { (void) val_int(); return null_value; }
+  bool is_null() { 
+    (void) val_int();  /* Discard result. It sets null_value as side-effect. */ 
+    return null_value; 
+  }
   void signal_divide_by_null();
   friend class udf_handler;
   Field *tmp_table_field() { return result_field; }

--- 1.401/sql/mysql_priv.h	2006-08-02 14:13:12 +04:00
+++ 1.402/sql/mysql_priv.h	2006-08-02 14:13:12 +04:00
@@ -865,8 +865,6 @@ bool mysqld_show_create_db(THD *thd, cha
 void mysqld_list_processes(THD *thd,const char *user,bool verbose);
 int mysqld_show_status(THD *thd);
 int mysqld_show_variables(THD *thd,const char *wild);
-int mysql_find_files(THD *thd,List<char> *files, const char *db,
-                const char *path, const char *wild, bool dir);
 bool mysqld_show_storage_engines(THD *thd);
 bool mysqld_show_privileges(THD *thd);
 bool mysqld_show_column_types(THD *thd);
@@ -1138,7 +1136,10 @@ uint check_word(TYPELIB *lib, const char
 bool is_keyword(const char *name, uint len);
 
 #define MY_DB_OPT_FILE "db.opt"
+bool check_db_dir_existence(const char *db_name);
 bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
+bool load_db_opt_by_name(THD *thd, const char *db_name,
+                         HA_CREATE_INFO *db_create_info);
 bool my_dbopt_init(void);
 void my_dbopt_cleanup(void);
 void my_dbopt_free(void);

--- 1.274/sql/slave.cc	2006-08-02 14:13:12 +04:00
+++ 1.275/sql/slave.cc	2006-08-02 14:13:12 +04:00
@@ -3717,15 +3717,12 @@ err:
   write_ignored_events_info_to_relay_log(thd, mi);
   thd->proc_info = "Waiting for slave mutex on exit";
   pthread_mutex_lock(&mi->run_lock);
-  mi->slave_running = 0;
-  mi->io_thd = 0;
 
   /* Forget the relay log's format */
   delete mi->rli.relay_log.description_event_for_queue;
   mi->rli.relay_log.description_event_for_queue= 0;
   // TODO: make rpl_status part of MASTER_INFO
   change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
-  mi->abort_slave = 0; // TODO: check if this is needed
   DBUG_ASSERT(thd->net.buff != 0);
   net_end(&thd->net); // destructor will not free it, because net.vio is 0
   close_thread_tables(thd, 0);
@@ -3733,8 +3730,11 @@ err:
   THD_CHECK_SENTRY(thd);
   delete thd;
   pthread_mutex_unlock(&LOCK_thread_count);
-  pthread_cond_broadcast(&mi->stop_cond);	// tell the world we are done
+  mi->abort_slave= 0;
+  mi->slave_running= 0;
+  mi->io_thd= 0;
   pthread_mutex_unlock(&mi->run_lock);
+  pthread_cond_broadcast(&mi->stop_cond);       // tell the world we are done
 #ifndef DBUG_OFF
   if (abort_slave_event_count && !events_till_abort)
     goto slave_begin;

--- 1.561/sql/sql_parse.cc	2006-08-02 14:13:12 +04:00
+++ 1.562/sql/sql_parse.cc	2006-08-02 14:13:12 +04:00
@@ -69,8 +69,8 @@ extern "C" int gethostname(char *name, i
 static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
 static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
-#endif
 static void decrease_user_connections(USER_CONN *uc);
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 static bool check_db_used(THD *thd,TABLE_LIST *tables);
 static bool check_multi_update_lock(THD *thd);
 static void remove_escape(char *name);
@@ -204,6 +204,7 @@ static bool some_non_temp_table_to_be_up
   return 0;
 }
 
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
 static HASH hash_user_connections;
 
 static int get_or_create_user_conn(THD *thd, const char *user,
@@ -255,6 +256,7 @@ end:
   return return_val;
 
 }
+#endif /* !NO_EMBEDDED_ACCESS_CHECKS */
 
 
 /*
@@ -303,8 +305,6 @@ int check_user(THD *thd, enum enum_serve
     {
       /* Send the error to the client */
       net_send_error(thd);
-      if (thd->user_connect)
-	decrease_user_connections(thd->user_connect);
       DBUG_RETURN(-1);
     }
   }
@@ -495,10 +495,12 @@ extern "C" void free_user(struct user_co
 
 void init_max_user_conn(void)
 {
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
   (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
 		   0,0,
 		   (hash_get_key) get_key_conn, (hash_free_key) free_user,
 		   0);
+#endif
 }
 
 
@@ -561,7 +563,6 @@ static int check_for_max_user_connection
   (void) pthread_mutex_unlock(&LOCK_user_conn);
   DBUG_RETURN(error);
 }
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 
 /*
   Decrease user connection count
@@ -595,13 +596,18 @@ static void decrease_user_connections(US
   DBUG_VOID_RETURN;
 }
 
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+
 
 void free_max_user_conn(void)
 {
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
   hash_free(&hash_user_connections);
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 }
 
 
+
 /*
   Mark all commands that somehow changes a table
   This is used to check number of updates / hour
@@ -1706,9 +1712,11 @@ bool dispatch_command(enum enum_server_c
     }
     else
     {
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
       /* we've authenticated new user */
       if (save_user_connect)
 	decrease_user_connections(save_user_connect);
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
       x_free((gptr) save_db);
       x_free((gptr)  save_security_ctx.user);
     }
@@ -6094,8 +6102,7 @@ TABLE_LIST *st_select_lex::add_table_to_
   if (!table)
     DBUG_RETURN(0);				// End of memory
   alias_str= alias ? alias->str : table->table.str;
-  if (check_table_name(table->table.str,table->table.length) ||
-      table->db.str && check_db_name(table->db.str))
+  if (check_table_name(table->table.str, table->table.length))
   {
     my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
     DBUG_RETURN(0);
@@ -6116,6 +6123,11 @@ TABLE_LIST *st_select_lex::add_table_to_
     DBUG_RETURN(0);				/* purecov: inspected */
   if (table->db.str)
   {
+    if (table->is_derived_table() == FALSE && check_db_name(table->db.str))
+    {
+      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
+      DBUG_RETURN(0);
+    }
     ptr->db= table->db.str;
     ptr->db_length= table->db.length;
   }

--- 1.475/sql/sql_yacc.yy	2006-08-02 14:13:12 +04:00
+++ 1.476/sql/sql_yacc.yy	2006-08-02 14:13:13 +04:00
@@ -1256,6 +1256,17 @@ create_function_tail:
 	  RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys
 	  {
 	    LEX *lex=Lex;
+            if (lex->definer != NULL)
+            {
+              /*
+                 DEFINER is a concept meaningful when interpreting SQL code.
+                 UDF functions are compiled.
+                 Using DEFINER with UDF has therefore no semantic,
+                 and is considered a parsing error.
+              */
+	      my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER");
+              YYABORT;
+            }
 	    lex->sql_command = SQLCOM_CREATE_FUNCTION;
 	    lex->udf.name = lex->spname->m_name;
 	    lex->udf.returns=(Item_result) $2;
@@ -1285,6 +1296,7 @@ create_function_tail:
 	    sp= new sp_head();
 	    sp->reset_thd_mem_root(YYTHD);
 	    sp->init(lex);
+            sp->init_sp_name(YYTHD, lex->spname);
 
 	    sp->m_type= TYPE_ENUM_FUNCTION;
 	    lex->sphead= sp;
@@ -1339,7 +1351,7 @@ create_function_tail:
               YYABORT;
 
 	    lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
-	    sp->init_strings(YYTHD, lex, lex->spname);
+	    sp->init_strings(YYTHD, lex);
             if (!(sp->m_flags & sp_head::HAS_RETURN))
             {
               my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
@@ -1911,9 +1923,12 @@ sp_proc_stmt:
               sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(),
                                                  lex->spcont, lex);
 
-              /* Extract the query statement from the tokenizer:
-                 The end is either lex->tok_end or tok->ptr. */
-              if (lex->ptr - lex->tok_end > 1)
+              /*
+                Extract the query statement from the tokenizer.  The
+                end is either lex->ptr, if there was no lookahead,
+                lex->tok_end otherwise.
+              */
+              if (yychar == YYEMPTY)
                 i->m_query.length= lex->ptr - sp->m_tmp_query;
               else
                 i->m_query.length= lex->tok_end - sp->m_tmp_query;
@@ -7822,7 +7837,12 @@ option_type_value:
                                          lex)))
                 YYABORT;
 
-              if (lex->ptr - lex->tok_end > 1)
+              /*
+                Extract the query statement from the tokenizer.  The
+                end is either lex->ptr, if there was no lookahead,
+                lex->tok_end otherwise.
+              */
+              if (yychar == YYEMPTY)
                 qbuff.length= lex->ptr - sp->m_tmp_query;
               else
                 qbuff.length= lex->tok_end - sp->m_tmp_query;
@@ -9092,6 +9112,7 @@ trigger_tail:
 	    YYABORT;
 	  sp->reset_thd_mem_root(YYTHD);
 	  sp->init(lex);
+          sp->init_sp_name(YYTHD, $3);
 	
 	  lex->stmt_definition_begin= $2;
           lex->ident.str= $7;
@@ -9120,7 +9141,7 @@ trigger_tail:
 	  sp_head *sp= lex->sphead;
 	  
 	  lex->sql_command= SQLCOM_CREATE_TRIGGER;
-	  sp->init_strings(YYTHD, lex, $3);
+	  sp->init_strings(YYTHD, lex);
 	  /* Restore flag if it was cleared above */
 	  if (sp->m_old_cmq)
 	    YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
@@ -9168,13 +9189,14 @@ sp_tail:
 	    my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
 	    YYABORT;
 	  }
-	  
+
 	  lex->stmt_definition_begin= $2;
-	  
+
 	  /* Order is important here: new - reset - init */
 	  sp= new sp_head();
 	  sp->reset_thd_mem_root(YYTHD);
 	  sp->init(lex);
+          sp->init_sp_name(YYTHD, $3);
 
 	  sp->m_type= TYPE_ENUM_PROCEDURE;
 	  lex->sphead= sp;
@@ -9212,7 +9234,7 @@ sp_tail:
 	  LEX *lex= Lex;
 	  sp_head *sp= lex->sphead;
 
-	  sp->init_strings(YYTHD, lex, $3);
+	  sp->init_strings(YYTHD, lex);
 	  lex->sql_command= SQLCOM_CREATE_PROCEDURE;
 	  /* Restore flag if it was cleared above */
 	  if (sp->m_old_cmq)

--- 1.131/sql/table.h	2006-08-02 14:13:13 +04:00
+++ 1.132/sql/table.h	2006-08-02 14:13:13 +04:00
@@ -668,6 +668,10 @@ typedef struct st_table_list
   Security_context *find_view_security_context(THD *thd);
   bool prepare_view_securety_context(THD *thd);
 #endif
+  /*
+    Cleanup for re-execution in a prepared statement or a stored
+    procedure.
+  */
   void reinit_before_use(THD *thd);
 
 private:

--- 1.16/include/sql_common.h	2006-08-02 14:13:13 +04:00
+++ 1.17/include/sql_common.h	2006-08-02 14:13:13 +04:00
@@ -36,7 +36,7 @@ cli_advanced_command(MYSQL *mysql, enum 
 		     const char *header, ulong header_length,
 		     const char *arg, ulong arg_length, my_bool skip_check,
                      MYSQL_STMT *stmt);
-
+unsigned long cli_safe_read(MYSQL *mysql);
 void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode,
 		     const char *sqlstate);
 void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate);

--- 1.95/sql-common/client.c	2006-08-02 14:13:13 +04:00
+++ 1.96/sql-common/client.c	2006-08-02 14:13:13 +04:00
@@ -584,7 +584,7 @@ err:
 *****************************************************************************/
 
 ulong
-net_safe_read(MYSQL *mysql)
+cli_safe_read(MYSQL *mysql)
 {
   NET *net= &mysql->net;
   ulong len=0;
@@ -627,6 +627,16 @@ net_safe_read(MYSQL *mysql)
     }
     else
       set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+    /*
+      Cover a protocol design error: error packet does not
+      contain the server status. Therefore, the client has no way
+      to find out whether there are more result sets of
+      a multiple-result-set statement pending. Luckily, in 5.0 an
+      error always aborts execution of a statement, wherever it is
+      a multi-statement or a stored procedure, so it should be
+      safe to unconditionally turn off the flag here.
+    */
+    mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
     DBUG_PRINT("error",("Got error: %d/%s (%s)",
 			net->last_errno, net->sqlstate, net->last_error));
@@ -653,7 +663,7 @@ cli_advanced_command(MYSQL *mysql, enum 
   NET *net= &mysql->net;
   my_bool result= 1;
   init_sigpipe_variables
-    DBUG_ENTER("cli_advanced_command");
+  DBUG_ENTER("cli_advanced_command");
 
   /* Don't give sigpipe errors if the client doesn't want them */
   set_sigpipe(mysql);
@@ -663,7 +673,8 @@ cli_advanced_command(MYSQL *mysql, enum 
     if (mysql_reconnect(mysql))
       DBUG_RETURN(1);
   }
-  if (mysql->status != MYSQL_STATUS_READY)
+  if (mysql->status != MYSQL_STATUS_READY ||
+      mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
   {
     DBUG_PRINT("error",("state: %d", mysql->status));
     set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
@@ -702,7 +713,7 @@ cli_advanced_command(MYSQL *mysql, enum 
   }
   result=0;
   if (!skip_check)
-    result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ?
+    result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
 	     1 : 0);
 end:
   reset_sigpipe(mysql);
@@ -754,7 +765,7 @@ static void cli_flush_use_result(MYSQL *
   for (;;)
   {
     ulong pkt_len;
-    if ((pkt_len=net_safe_read(mysql)) == packet_error)
+    if ((pkt_len=cli_safe_read(mysql)) == packet_error)
       break;
     if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
     {
@@ -1276,7 +1287,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,M
   NET *net = &mysql->net;
   DBUG_ENTER("cli_read_rows");
 
-  if ((pkt_len= net_safe_read(mysql)) == packet_error)
+  if ((pkt_len= cli_safe_read(mysql)) == packet_error)
     DBUG_RETURN(0);
   if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
 				       MYF(MY_WME | MY_ZEROFILL))))
@@ -1341,7 +1352,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,M
       }
     }
     cur->data[field]=to;			/* End of last field */
-    if ((pkt_len=net_safe_read(mysql)) == packet_error)
+    if ((pkt_len=cli_safe_read(mysql)) == packet_error)
     {
       free_rows(result);
       DBUG_RETURN(0);
@@ -1373,7 +1384,7 @@ read_one_row(MYSQL *mysql,uint fields,MY
   uchar *pos, *prev_pos, *end_pos;
   NET *net= &mysql->net;
 
-  if ((pkt_len=net_safe_read(mysql)) == packet_error)
+  if ((pkt_len=cli_safe_read(mysql)) == packet_error)
     return -1;
   if (pkt_len <= 8 && net->read_pos[0] == 254)
   {
@@ -1650,23 +1661,23 @@ static MYSQL_RES *cli_use_result(MYSQL *
 
 static MYSQL_METHODS client_methods=
 {
-  cli_read_query_result,
-  cli_advanced_command,
-  cli_read_rows,
-  cli_use_result,
-  cli_fetch_lengths,
-  cli_flush_use_result
+  cli_read_query_result,                       /* read_query_result */
+  cli_advanced_command,                        /* advanced_command */
+  cli_read_rows,                               /* read_rows */
+  cli_use_result,                              /* use_result */
+  cli_fetch_lengths,                           /* fetch_lengths */
+  cli_flush_use_result                         /* flush_use_result */
 #ifndef MYSQL_SERVER
-  ,cli_list_fields,
-  cli_read_prepare_result,
-  cli_stmt_execute,
-  cli_read_binary_rows,
-  cli_unbuffered_fetch,
-  NULL,
-  cli_read_statistics,
-  cli_read_query_result,
-  cli_read_change_user_result,
-  cli_read_binary_rows
+  ,cli_list_fields,                            /* list_fields */
+  cli_read_prepare_result,                     /* read_prepare_result */
+  cli_stmt_execute,                            /* stmt_execute */
+  cli_read_binary_rows,                        /* read_binary_rows */
+  cli_unbuffered_fetch,                        /* unbuffered_fetch */
+  NULL,                                        /* free_embedded_thd */
+  cli_read_statistics,                         /* read_statistics */
+  cli_read_query_result,                       /* next_result */
+  cli_read_change_user_result,                 /* read_change_user_result */
+  cli_read_binary_rows                         /* read_rows_from_cursor */
 #endif
 };
 
@@ -2029,7 +2040,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     Part 1: Connection established, read and parse first packet
   */
 
-  if ((pkt_length=net_safe_read(mysql)) == packet_error)
+  if ((pkt_length=cli_safe_read(mysql)) == packet_error)
     goto error;
 
   /* Check if version of protocol matches current one */
@@ -2253,7 +2264,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     OK-packet, or re-request scrambled password.
   */
 
-  if ((pkt_length=net_safe_read(mysql)) == packet_error)
+  if ((pkt_length=cli_safe_read(mysql)) == packet_error)
     goto error;
 
   if (pkt_length == 1 && net->read_pos[0] == 254 && 
@@ -2270,7 +2281,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
       goto error;
     }
     /* Read what server thinks about out new auth message report */
-    if (net_safe_read(mysql) == packet_error)
+    if (cli_safe_read(mysql) == packet_error)
       goto error;
   }
 
@@ -2594,7 +2605,7 @@ static my_bool cli_read_query_result(MYS
   */
   mysql = mysql->last_used_con;
 
-  if ((length = net_safe_read(mysql)) == packet_error)
+  if ((length = cli_safe_read(mysql)) == packet_error)
     DBUG_RETURN(1);
   free_old_query(mysql);		/* Free old result */
 #ifdef MYSQL_CLIENT			/* Avoid warn of unused labels*/
@@ -2629,7 +2640,7 @@ get_info:
   if (field_count == NULL_LENGTH)		/* LOAD DATA LOCAL INFILE */
   {
     int error=handle_local_infile(mysql,(char*) pos);
-    if ((length=net_safe_read(mysql)) == packet_error || error)
+    if ((length= cli_safe_read(mysql)) == packet_error || error)
       DBUG_RETURN(1);
     goto get_info;				/* Get info packet */
   }

--- 1.105/mysql-test/mysql-test-run.pl	2006-08-02 14:13:13 +04:00
+++ 1.106/mysql-test/mysql-test-run.pl	2006-08-02 14:13:13 +04:00
@@ -2898,12 +2898,16 @@ sub im_stop($) {
 
   while (1)
   {
+    # Check that IM-main died.
+
     if (kill (0, $instance_manager->{'pid'}))
     {
       mtr_debug("IM-main is still alive.");
       last;
     }
 
+    # Check that IM-angel died.
+
     if (defined $instance_manager->{'angel_pid'} &&
         kill (0, $instance_manager->{'angel_pid'}))
     {
@@ -2911,21 +2915,39 @@ sub im_stop($) {
       last;
     }
 
+    # Check that all guarded mysqld-instances died.
+
+    my $guarded_mysqlds_dead= 1;
+
     foreach my $pid (@mysqld_pids)
     {
       if (kill (0, $pid))
       {
         mtr_debug("Guarded mysqld ($pid) is still alive.");
+        $guarded_mysqlds_dead= 0;
         last;
       }
     }
 
+    last unless $guarded_mysqlds_dead;
+
+    # Ok, all necessary processes are dead.
+
     $clean_shutdown= 1;
     last;
   }
 
   # Kill leftovers (the order is important).
 
+  if ($clean_shutdown)
+  {
+    mtr_debug("IM-shutdown was clean -- all processed died.");
+  }
+  else
+  {
+    mtr_debug("IM failed to shutdown gracefully. We have to clean the mess...");
+  }
+
   unless ($clean_shutdown)
   {
 
@@ -2946,17 +2968,24 @@ sub im_stop($) {
     mtr_kill_processes(\@mysqld_pids);
 
     # Complain in error log so that a warning will be shown.
-
-    my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
-
-    open (ERRLOG, ">>$errlog") ||
-      mtr_error("Can not open error log ($errlog)");
+    # 
+    # TODO: unless BUG#20761 is fixed, we will print the warning
+    # to stdout, so that it can be seen on console and does not
+    # produce pushbuild error.
+
+    # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
+    # 
+    # open (ERRLOG, ">>$errlog") ||
+    #   mtr_error("Can not open error log ($errlog)");
+    # 
+    # my $ts= localtime();
+    # print ERRLOG
+    #   "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
+    # 
+    # close ERRLOG;
 
     my $ts= localtime();
-    print ERRLOG
-      "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
-
-    close ERRLOG;
+    print "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
   }
 
   # That's all.

--- 1.6/mysql-test/t/udf.test	2006-08-02 14:13:13 +04:00
+++ 1.7/mysql-test/t/udf.test	2006-08-02 14:13:13 +04:00
@@ -109,6 +109,18 @@ SELECT myfunc_double(n) AS f FROM bug199
 SELECT metaphon(v) AS f FROM bug19904;
 DROP TABLE bug19904;
 
+#
+# Bug#21269: DEFINER-clause is allowed for UDF-functions
+#
+
+--error ER_WRONG_USAGE
+CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse
+RETURNS STRING SONAME "should_not_parse.so";
+
+--error ER_WRONG_USAGE
+CREATE DEFINER=someone@somewhere FUNCTION should_not_parse
+RETURNS STRING SONAME "should_not_parse.so";
+
 --echo End of 5.0 tests.
 
 #

--- 1.204/mysql-test/r/sp.result	2006-08-02 14:13:13 +04:00
+++ 1.205/mysql-test/r/sp.result	2006-08-02 14:13:13 +04:00
@@ -5057,6 +5057,171 @@ concat('data was: /', var1, '/')
 data was: /1/
 drop table t3|
 drop procedure bug15217|
+DROP PROCEDURE IF EXISTS bug21013 |
+CREATE PROCEDURE bug21013(IN lim INT)
+BEGIN
+DECLARE i INT DEFAULT 0;
+WHILE (i < lim) DO
+SET @b = LOCATE(_latin1'b', @a, 1);
+SET i = i + 1;
+END WHILE;
+END |
+SET @a = _latin2"aaaaaaaaaa" |
+CALL bug21013(10) |
+DROP PROCEDURE bug21013 |
+DROP DATABASE IF EXISTS mysqltest1|
+DROP DATABASE IF EXISTS mysqltest2|
+CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
+CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8|
+use mysqltest1|
+CREATE FUNCTION bug16211_f1() RETURNS CHAR(10)
+RETURN ""|
+CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r
+RETURN ""|
+CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10)
+RETURN ""|
+CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r
+RETURN ""|
+SHOW CREATE FUNCTION bug16211_f1|
+Function	sql_mode	Create Function
+bug16211_f1		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8
+RETURN ""
+SHOW CREATE FUNCTION bug16211_f2|
+Function	sql_mode	Create Function
+bug16211_f2		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r
+RETURN ""
+SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
+Function	sql_mode	Create Function
+bug16211_f3		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8
+RETURN ""
+SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
+Function	sql_mode	Create Function
+bug16211_f4		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r
+RETURN ""
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
+dtd_identifier
+char(10) CHARSET utf8
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
+dtd_identifier
+char(10) CHARSET koi8r
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
+dtd_identifier
+char(10) CHARSET utf8
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
+dtd_identifier
+char(10) CHARSET koi8r
+SELECT CHARSET(bug16211_f1())|
+CHARSET(bug16211_f1())
+utf8
+SELECT CHARSET(bug16211_f2())|
+CHARSET(bug16211_f2())
+koi8r
+SELECT CHARSET(mysqltest2.bug16211_f3())|
+CHARSET(mysqltest2.bug16211_f3())
+utf8
+SELECT CHARSET(mysqltest2.bug16211_f4())|
+CHARSET(mysqltest2.bug16211_f4())
+koi8r
+ALTER DATABASE mysqltest1 CHARACTER SET cp1251|
+ALTER DATABASE mysqltest2 CHARACTER SET cp1251|
+SHOW CREATE FUNCTION bug16211_f1|
+Function	sql_mode	Create Function
+bug16211_f1		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8
+RETURN ""
+SHOW CREATE FUNCTION bug16211_f2|
+Function	sql_mode	Create Function
+bug16211_f2		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r
+RETURN ""
+SHOW CREATE FUNCTION mysqltest2.bug16211_f3|
+Function	sql_mode	Create Function
+bug16211_f3		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8
+RETURN ""
+SHOW CREATE FUNCTION mysqltest2.bug16211_f4|
+Function	sql_mode	Create Function
+bug16211_f4		CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r
+RETURN ""
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"|
+dtd_identifier
+char(10) CHARSET utf8
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"|
+dtd_identifier
+char(10) CHARSET koi8r
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"|
+dtd_identifier
+char(10) CHARSET utf8
+SELECT dtd_identifier
+FROM INFORMATION_SCHEMA.ROUTINES
+WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"|
+dtd_identifier
+char(10) CHARSET koi8r
+SELECT CHARSET(bug16211_f1())|
+CHARSET(bug16211_f1())
+utf8
+SELECT CHARSET(bug16211_f2())|
+CHARSET(bug16211_f2())
+koi8r
+SELECT CHARSET(mysqltest2.bug16211_f3())|
+CHARSET(mysqltest2.bug16211_f3())
+utf8
+SELECT CHARSET(mysqltest2.bug16211_f4())|
+CHARSET(mysqltest2.bug16211_f4())
+koi8r
+use test|
+DROP DATABASE mysqltest1|
+DROP DATABASE mysqltest2|
+DROP DATABASE IF EXISTS mysqltest1|
+CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8|
+use mysqltest1|
+CREATE PROCEDURE bug16676_p1(
+IN p1 CHAR(10),
+INOUT p2 CHAR(10),
+OUT p3 CHAR(10))
+BEGIN
+SELECT CHARSET(p1), COLLATION(p1);
+SELECT CHARSET(p2), COLLATION(p2);
+SELECT CHARSET(p3), COLLATION(p3);
+END|
+CREATE PROCEDURE bug16676_p2(
+IN p1 CHAR(10) CHARSET koi8r,
+INOUT p2 CHAR(10) CHARSET cp1251,
+OUT p3 CHAR(10) CHARSET greek)
+BEGIN
+SELECT CHARSET(p1), COLLATION(p1);
+SELECT CHARSET(p2), COLLATION(p2);
+SELECT CHARSET(p3), COLLATION(p3);
+END|
+SET @v2 = 'b'|
+SET @v3 = 'c'|
+CALL bug16676_p1('a', @v2, @v3)|
+CHARSET(p1)	COLLATION(p1)
+utf8	utf8_general_ci
+CHARSET(p2)	COLLATION(p2)
+utf8	utf8_general_ci
+CHARSET(p3)	COLLATION(p3)
+utf8	utf8_general_ci
+CALL bug16676_p2('a', @v2, @v3)|
+CHARSET(p1)	COLLATION(p1)
+koi8r	koi8r_general_ci
+CHARSET(p2)	COLLATION(p2)
+cp1251	cp1251_general_ci
+CHARSET(p3)	COLLATION(p3)
+greek	greek_general_ci
+use test|
+DROP DATABASE mysqltest1|
 drop table if exists t3|
 drop database if exists mysqltest1|
 create table t3 (a int)|

--- 1.192/mysql-test/t/sp.test	2006-08-02 14:13:13 +04:00
+++ 1.193/mysql-test/t/sp.test	2006-08-02 14:13:13 +04:00
@@ -6146,6 +6146,29 @@ CALL bug16676_p2('a', @v2, @v3)|
 use test|
 
 DROP DATABASE mysqltest1|
+# Bug#21002 "Derived table not selecting from a "real" table fails in JOINs"
+#         
+# A regression caused by the fix for Bug#18444: for derived tables we should
+# set an empty string as the current database. They do not belong to any
+# database and must be usable even if there is no database
+# selected.
+--disable_warnings
+drop table if exists t3|
+drop database if exists mysqltest1|
+--enable_warnings
+create table t3 (a int)|
+insert into t3 (a) values (1), (2)|
+
+create database mysqltest1|
+use mysqltest1|
+drop database mysqltest1|
+
+# No current database
+select database()|
+
+select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2|
+use test|
+drop table t3|
 
 #
 # BUG#NNNN: New bug synopsis

--- 1.114/sql/sp.cc	2006-08-02 14:13:13 +04:00
+++ 1.115/sql/sp.cc	2006-08-02 14:13:13 +04:00
@@ -495,6 +495,13 @@ sp_returns_type(THD *thd, String &result
   table.s = &table.share_not_to_be_used;
   field= sp->create_result_field(0, 0, &table);
   field->sql_type(result);
+
+  if (field->has_charset())
+  {
+    result.append(STRING_WITH_LEN(" CHARSET "));
+    result.append(field->charset()->csname);
+  }
+
   delete field;
 }
 
@@ -626,7 +633,10 @@ db_create_routine(THD *thd, int type, sp
       log_query.append(STRING_WITH_LEN("CREATE "));
       append_definer(thd, &log_query, &thd->lex->definer->user,
                      &thd->lex->definer->host);
-      log_query.append(thd->lex->stmt_definition_begin);
+      log_query.append(thd->lex->stmt_definition_begin,
+                       (char *)sp->m_body_begin -
+                       thd->lex->stmt_definition_begin +
+                       sp->m_body.length);
 
       /* Such a statement can always go directly to binlog, no trans cache */
       Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0,
@@ -974,6 +984,11 @@ sp_find_routine(THD *thd, int type, sp_n
     sp_head *new_sp;
     const char *returns= "";
     char definer[USER_HOST_BUFF_SIZE];
+
+    /*
+      String buffer for RETURNS data type must have system charset;
+      64 -- size of "returns" column of mysql.proc.
+    */
     String retstr(64);
 
     DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));

--- 1.105/mysql-test/r/mysqldump.result	2006-08-02 14:13:13 +04:00
+++ 1.106/mysql-test/r/mysqldump.result	2006-08-02 14:13:13 +04:00
@@ -2220,7 +2220,7 @@ RETURN a+b */;;
 /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
 /*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;;
 /*!50003 SET SESSION SQL_MODE=""*/;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
+/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
 begin
 set f1= concat( 'hello', f1 );
 return f1;

--- 1.69/mysql-test/r/ps.result	2006-08-02 14:13:13 +04:00
+++ 1.70/mysql-test/r/ps.result	2006-08-02 14:13:13 +04:00
@@ -485,6 +485,11 @@ execute stmt;
 pnum
 deallocate prepare stmt;
 drop table t1, t2;
+create table t1 (a varchar(20));
+insert into t1 values ('foo');
+prepare stmt FROM 'SELECT char_length (a) FROM t1';
+ERROR 42000: FUNCTION test.char_length does not exist
+drop table t1;
 prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0";
 execute stmt;
 foo
@@ -497,6 +502,77 @@ SELECT FOUND_ROWS();
 FOUND_ROWS()
 2
 deallocate prepare stmt;
+create table t1 (a char(3) not null, b char(3) not null,
+c char(3) not null, primary key  (a, b, c));
+create table t2 like t1;
+prepare stmt from
+"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b)
+  where t1.a=1";
+execute stmt;
+a
+execute stmt;
+a
+execute stmt;
+a
+prepare stmt from
+"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from
+(t1 left outer join t2 on t2.a=? and t1.b=t2.b)
+left outer join t2 t3 on t3.a=? where t1.a=?";
+set @a:=1, @b:=1, @c:=1;
+execute stmt using @a, @b, @c;
+a	b	c	a	b	c
+execute stmt using @a, @b, @c;
+a	b	c	a	b	c
+execute stmt using @a, @b, @c;
+a	b	c	a	b	c
+deallocate prepare stmt;
+drop table t1,t2;
+SET @aux= "SELECT COUNT(*)
+                FROM INFORMATION_SCHEMA.COLUMNS A,
+                INFORMATION_SCHEMA.COLUMNS B
+                WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
+                AND A.TABLE_NAME = B.TABLE_NAME
+                AND A.COLUMN_NAME = B.COLUMN_NAME AND
+                A.TABLE_NAME = 'user'";
+prepare my_stmt from @aux;
+execute my_stmt;
+COUNT(*)
+37
+execute my_stmt;
+COUNT(*)
+37
+execute my_stmt;
+COUNT(*)
+37
+deallocate prepare my_stmt;
+drop procedure if exists p1|
+drop table if exists t1|
+create table t1 (id int)|
+insert into t1 values(1)|
+create procedure p1(a int, b int)
+begin
+declare c int;
+select max(id)+1 into c from t1;
+insert into t1 select a+b;
+insert into t1 select a-b;
+insert into t1 select a-c;
+end|
+set @a= 3, @b= 4|
+prepare stmt from "call p1(?, ?)"|
+execute stmt using @a, @b|
+execute stmt using @a, @b|
+select * from t1|
+id
+1
+7
+-1
+1
+7
+-1
+-5
+deallocate prepare stmt|
+drop procedure p1|
+drop table t1|
 drop table if exists t1;
 Warnings:
 Note	1051	Unknown table 't1'

--- 1.67/mysql-test/t/ps.test	2006-08-02 14:13:13 +04:00
+++ 1.68/mysql-test/t/ps.test	2006-08-02 14:13:13 +04:00
@@ -490,6 +490,42 @@ execute stmt;
 deallocate prepare stmt;
 drop table t1, t2;
 
+#
+#
+# Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating
+#            tables"
+# Check that multi-delete tables are also cleaned up before re-execution.
+# 
+--disable_warnings
+drop table if exists t1;
+create temporary table if not exists t1 (a1 int);
+--enable_warnings
+# exact delete syntax is essential
+prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
+drop temporary table t1;
+create temporary table if not exists t1 (a1 int);
+# the server crashed on  the next statement without the fix
+execute stmt;
+drop temporary table t1;
+create temporary table if not exists t1 (a1 int);
+# the problem was in memory corruption: repeat the test just in case
+execute stmt;
+drop temporary table t1;
+create temporary table if not exists t1 (a1 int);
+execute stmt;
+drop temporary table t1;
+deallocate prepare stmt;
+
+# Bug#6102 "Server crash with prepared statement and blank after
+# function name"
+# ensure that stored functions are cached when preparing a statement
+# before we open tables
+#
+create table t1 (a varchar(20)); 
+insert into t1 values ('foo'); 
+--error 1305
+prepare stmt FROM 'SELECT char_length (a) FROM t1'; 
+drop table t1;
 
 #
 # Bug #6089: FOUND_ROWS returns wrong values when no table/view is used 

--- 1.180/sql/sql_prepare.cc	2006-08-02 14:13:13 +04:00
+++ 1.181/sql/sql_prepare.cc	2006-08-02 14:13:13 +04:00
@@ -2157,7 +2157,7 @@ void reinit_stmt_before_use(THD *thd, LE
   }
   lex->allow_sum_func= 0;
   lex->in_sum_func= NULL;
-  DBUG_VOID_RETURN;  
+  DBUG_VOID_RETURN;
 }
 
 

--- 1.194/tests/mysql_client_test.c	2006-08-02 14:13:13 +04:00
+++ 1.195/tests/mysql_client_test.c	2006-08-02 14:13:13 +04:00
@@ -50,7 +50,6 @@ static unsigned int  opt_port;
 static my_bool tty_password= 0, opt_silent= 0;
 
 static MYSQL *mysql= 0;
-static char query[MAX_TEST_QUERY_LENGTH];
 static char current_db[]= "client_test_db";
 static unsigned int test_count= 0;
 static unsigned int opt_count= 0;
@@ -270,6 +269,7 @@ mysql_simple_prepare(MYSQL  *mysql, cons
 static void client_connect(ulong flag)
 {
   int  rc;
+  static char query[MAX_TEST_QUERY_LENGTH];
   myheader_r("client_connect");
 
   if (!opt_silent)
@@ -327,6 +327,8 @@ static void client_connect(ulong flag)
 
 static void client_disconnect()
 {
+  static char query[MAX_TEST_QUERY_LENGTH];
+
   myheader_r("client_disconnect");
 
   if (mysql)
@@ -658,6 +660,7 @@ int my_stmt_result(const char *buff)
 static void verify_col_data(const char *table, const char *col,
                             const char *exp_data)
 {
+  static char query[MAX_TEST_QUERY_LENGTH];
   MYSQL_RES *result;
   MYSQL_ROW row;
   int       rc, field= 1;
@@ -1363,6 +1366,7 @@ static void test_prepare_insert_update()
   
   for (cur_query= testcase; *cur_query; cur_query++)
   {
+    char query[MAX_TEST_QUERY_LENGTH];
     printf("\nRunning query: %s", *cur_query);
     strmov(query, *cur_query);
     stmt= mysql_simple_prepare(mysql, query);
@@ -1397,6 +1401,7 @@ static void test_prepare_simple()
 {
   MYSQL_STMT *stmt;
   int        rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare_simple");
 
@@ -1467,6 +1472,7 @@ static void test_prepare_field_result()
   MYSQL_STMT *stmt;
   MYSQL_RES  *result;
   int        rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare_field_result");
 
@@ -1518,6 +1524,7 @@ static void test_prepare_syntax()
 {
   MYSQL_STMT *stmt;
   int        rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare_syntax");
 
@@ -1559,6 +1566,7 @@ static void test_prepare()
   my_bool    is_null[7];
   char	     llbuf[22];
   MYSQL_BIND bind[7];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare");
 
@@ -1732,6 +1740,7 @@ static void test_double_compare()
   MYSQL_RES  *result;
   MYSQL_BIND bind[3];
   ulong      length[3];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_double_compare");
 
@@ -1814,6 +1823,7 @@ static void test_null()
   uint       nData;
   MYSQL_BIND bind[2];
   my_bool    is_null[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_null");
 
@@ -1960,6 +1970,7 @@ static void test_ps_null_param()
   /* Execute several queries, all returning NULL in result. */
   for(cur_query= queries; *cur_query; cur_query++)
   {
+    char query[MAX_TEST_QUERY_LENGTH];
     strmov(query, *cur_query);
     stmt= mysql_simple_prepare(mysql, query);
     check_stmt(stmt);
@@ -1991,6 +2002,7 @@ static void test_fetch_null()
   MYSQL_BIND bind[11];
   ulong      length[11];
   my_bool    is_null[11];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_fetch_null");
 
@@ -2219,6 +2231,7 @@ static void test_select()
   int        nData= 1;
   MYSQL_BIND bind[2];
   ulong length[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_select");
 
@@ -2290,6 +2303,7 @@ static void test_ps_conj_select()
   int32      int_data;
   char       str_data[32];
   unsigned long str_length;
+  char query[MAX_TEST_QUERY_LENGTH];
   myheader("test_ps_conj_select");
 
   rc= mysql_query(mysql, "drop table if exists t1");
@@ -2347,6 +2361,7 @@ static void test_bug1115()
   MYSQL_BIND bind[1];
   ulong length[1];
   char szData[11];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_bug1115");
 
@@ -2458,6 +2473,7 @@ static void test_bug1180()
   MYSQL_BIND bind[1];
   ulong length[1];
   char szData[11];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_select_bug");
 
@@ -2548,6 +2564,7 @@ static void test_bug1644()
   int num;
   my_bool isnull;
   int rc, i;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_bug1644");
 
@@ -2647,6 +2664,7 @@ static void test_select_show()
 {
   MYSQL_STMT *stmt;
   int        rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_select_show");
 
@@ -2715,6 +2733,7 @@ static void test_simple_update()
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
   ulong      length[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_simple_update");
 
@@ -2792,6 +2811,7 @@ static void test_long_data()
   char       *data= NullS;
   MYSQL_RES  *result;
   MYSQL_BIND bind[3];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_long_data");
 
@@ -2878,6 +2898,7 @@ static void test_long_data_str()
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
   my_bool    is_null[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_long_data_str");
 
@@ -2970,6 +2991,7 @@ static void test_long_data_str1()
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
   MYSQL_FIELD *field;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_long_data_str1");
 
@@ -3125,6 +3147,7 @@ static void test_long_data_bin()
   long       length;
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
 
   myheader("test_long_data_bin");
@@ -3204,6 +3227,7 @@ static void test_simple_delete()
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
   ulong length[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_simple_delete");
 
@@ -3286,6 +3310,7 @@ static void test_update()
   MYSQL_RES  *result;
   MYSQL_BIND bind[2];
   ulong length[2];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_update");
 
@@ -3382,6 +3407,7 @@ static void test_prepare_noparam()
   MYSQL_STMT *stmt;
   int        rc;
   MYSQL_RES  *result;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare_noparam");
 
@@ -4238,6 +4264,7 @@ static void test_prepare_ext()
   short      sData= 10;
   longlong   bData= 20;
   MYSQL_BIND bind[6];
+  char query[MAX_TEST_QUERY_LENGTH];
   myheader("test_prepare_ext");
 
   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
@@ -4625,6 +4652,7 @@ static void test_stmt_close()
   MYSQL_RES   *result;
   unsigned int  count;
   int   rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_stmt_close");
 
@@ -5271,6 +5299,7 @@ static void test_manual_sample()
   ulonglong    affected_rows;
   MYSQL_BIND   bind[3];
   my_bool      is_null;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_manual_sample");
 
@@ -5625,6 +5654,7 @@ static void test_prepare_multi_statement
 {
   MYSQL *mysql_local;
   MYSQL_STMT *stmt;
+  char query[MAX_TEST_QUERY_LENGTH];
   myheader("test_prepare_multi_statements");
 
   if (!(mysql_local= mysql_init(NULL)))
@@ -5842,6 +5872,7 @@ static void test_store_result2()
   int        nData;
   ulong      length;
   MYSQL_BIND bind[1];
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_store_result2");
 
@@ -7121,6 +7152,7 @@ static void test_set_option()
 static void test_prepare_grant()
 {
   int rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_prepare_grant");
 
@@ -8593,6 +8625,7 @@ static void test_sqlmode()
   MYSQL_BIND bind[2];
   char       c1[5], c2[5];
   int        rc;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_sqlmode");
 
@@ -8736,6 +8769,7 @@ static void test_ts()
   ulong      length;
   int        rc, field_count;
   char       name;
+  char query[MAX_TEST_QUERY_LENGTH];
 
   myheader("test_ts");
 
@@ -15027,6 +15061,65 @@ static void test_bug20152()
   }
 }
 
+/* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
+
+static void test_bug15752()
+{
+  MYSQL mysql_local;
+  int rc, i;
+  const int ITERATION_COUNT= 100;
+  char *query= "CALL p1()";
+
+  myheader("test_bug15752");
+
+  rc= mysql_query(mysql, "drop procedure if exists p1");
+  myquery(rc);
+  rc= mysql_query(mysql, "create procedure p1() select 1");
+  myquery(rc);
+
+  mysql_init(&mysql_local);
+  if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
+                           opt_password, current_db, opt_port,
+                           opt_unix_socket,
+                           CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS))
+  {
+    printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
+    DIE_UNLESS(0);
+  }
+  rc= mysql_real_query(&mysql_local, query, strlen(query));
+  myquery(rc);
+  mysql_free_result(mysql_store_result(&mysql_local));
+
+  rc= mysql_real_query(&mysql_local, query, strlen(query));
+  DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
+
+  if (! opt_silent)
+    printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
+
+  /* Check some other commands too */
+
+  DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
+  mysql_free_result(mysql_store_result(&mysql_local));
+  DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
+
+  /* The second problem is not reproducible: add the test case */
+  for (i = 0; i < ITERATION_COUNT; i++)
+  {
+    if (mysql_real_query(&mysql_local, query, strlen(query)))
+    {
+      printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
+      break;
+    }
+    mysql_free_result(mysql_store_result(&mysql_local));
+    DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
+    mysql_free_result(mysql_store_result(&mysql_local));
+    DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
+
+  }
+  mysql_close(&mysql_local);
+  rc= mysql_query(mysql, "drop procedure p1");
+  myquery(rc);
+}
 
 /*
   Bug#21206: memory corruption when too many cursors are opened at once
@@ -15342,7 +15435,8 @@ static struct my_tests_st my_tests[]= {
   { "test_bug20152", test_bug20152 },
   { "test_bug14169", test_bug14169 },
   { "test_bug17667", test_bug17667 },
-  { "test_bug19671", test_bug19671},
+  { "test_bug19671", test_bug19671 },
+  { "test_bug15752", test_bug15752 },
   { "test_bug21206", test_bug21206},
   { 0, 0 }
 };
Thread
bk commit into 5.0 tree (kostja:1.2231)konstantin2 Aug