List:Commits« Previous MessageNext Message »
From:konstantin Date:October 30 2007 12:55pm
Subject:bk commit into 5.1 tree (kostja:1.2581)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 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, 2007-10-30 14:55:00+03:00, kostja@bodhi.(none) +74 -0
  Collapsed changeset. Passing test suite with send_ok()
  removed. 
  send_ok() is replaced with my_ok(), that stores the message like my_error,
  and is sent to client once at the end of the statement.
  Not all changes from this patch are necessary in 5.1: in particular,
  fatal_error and last_error[0] related changes are not strictly necessary.
  ---
  Remove send_eof, use my_eof instead.
  Commit to collapse the changeset with the previous that removes send_ok().
  The patch passes the test suite.

  include/mysql_com.h@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +9 -9
    Remove unused members. Rename no_send_error (don't send error) to
    eof_sent, to suggest when and why one should not send an error to the
    client, even if there is any.
    ---
    Remove send_eof, use my_eof instead.

  libmysql/libmysql.c@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +74 -60
    Remove send_eof, use my_eof instead.

  libmysql/manager.c@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  libmysqld/emb_qcache.cc@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  libmysqld/lib_sql.cc@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +38 -36
    Rework send_ok() to net_send_ok(), not designed for direct usage.
    Delete no_send_ok/no_send_error crap.
    ---
    Remove send_eof, use my_eof instead.

  libmysqld/libmysqld.c@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +2 -2
    Remove send_eof, use my_eof instead.

  mysql-test/r/events.result@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +2 -1
    Slight (allowed) change in wording when mysql.event does not exist.

  mysql-test/r/group_min_max.result@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none)
+1 -2
    Rows should not be deleted in case of a malformed subquery. Fixes
    an actual bug when subquery error was ignored.

  mysql-test/r/udf.result@stripped, 2007-10-30 14:54:46+03:00, kostja@bodhi.(none) +6 -6
    If one can't initialize the udf, SELECT udf() should not succeed.
    Fix an error in the test suite.

  mysql-test/suite/rpl/include/rpl_mixed_dml.inc@stripped, 2007-10-30 14:54:46+03:00,
kostja@bodhi.(none) +2 -1
    Unrelated change. Fix the test suite to pass even if rpl_mixed.dat
    is not checked out.

  mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result@stripped, 2007-10-30 14:54:49+03:00,
kostja@bodhi.(none) +2 -2
    Remove send_eof, use my_eof instead.

  mysql-test/t/group_min_max.test@stripped, 2007-10-30 14:54:49+03:00, kostja@bodhi.(none) +1
-0
    Rows should not be deleted in case of a malformed subquery. Fixes
    an actual bug when subquery error was ignored.

  mysql-test/t/udf.test@stripped, 2007-10-30 14:54:49+03:00, kostja@bodhi.(none) +6 -6
    If one can't initialize the udf, SELECT udf() should not succeed.
    Fix an error in the test suite.

  server-tools/instance-manager/mysql_connection.cc@stripped, 2007-10-30 14:54:49+03:00,
kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql-common/client.c@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +101 -99
    Remove send_eof, use my_eof instead.

  sql/events.cc@stripped, 2007-10-30 14:54:49+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/filesort.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/ha_ndbcluster_binlog.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +11 -5
    Fix a bug: run_query() calls mysql_parse(), which used to call send_ok().
    But run_query() is called from RESET MASTER, which sends OK as well.
    Two OK packets used to be sent, but since most clients "drains" the
    stream before sending a new request, this went unnoticed.
    A valid client/server protocol bug still that would be observable
    in any third-party connector.
    ---
    Remove send_eof, use my_eof instead.

  sql/ha_partition.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +1 -0
    Sometimes fatal_error() is called in the server without prior call
    to my_error(). This is a bug and will lead to ER_UNKNOWN_ERROR returned
    to the client. 

  sql/handler.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +34 -30
    Change the implementation of predicate "is there an error in the stack"
    to in all cases check for thd->net.report_error, never for
    thd->net.last_error[0]. last_error buffer should be reusable
    for success messages.
    ---
    Remove send_eof, use my_eof instead.

  sql/item_func.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +6 -5
    Change the implementation of predicate "is there an error in the stack"
    to in all cases check for thd->net.report_error, never for
    thd->net.last_error[0]. last_error buffer should be reusable
    for success messages.
    
    Always accompany fatal_error() with my_error().
    ---
    Remove send_eof, use my_eof instead.

  sql/item_subselect.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/log.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +2 -1
    Remove send_eof, use my_eof instead.

  sql/log_event.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +34 -22
    mysql_reset_thd_for_next_command() is not a part of mysql_parse() any more.
    ---
    Remove send_eof, use my_eof instead.

  sql/log_event_old.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +8 -8
    Remove send_eof, use my_eof instead.

  sql/mysql_priv.h@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +0 -1
    Remove send_eof, use my_eof instead.

  sql/mysqld.cc@stripped, 2007-10-30 14:54:50+03:00, kostja@bodhi.(none) +35 -22
    Change the implementation of predicate "is there an error in the stack"
    to in all cases check for thd->net.report_error, never for
    thd->net.last_error[0]. last_error buffer should be reusable
    for success messages.
    
    Add asserts.
    ---
    Remove send_eof, use my_eof instead.

  sql/net_serv.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +15 -26
    Remove unused members. Remove setting of net->report_error in case
    of a net error, such as timeout or dead sockeet. net->error should be 
    used instead. net->report_error belongs solely to sql/ layer, and
    should be moved to class Diagnostics_area over time.
    ---
    Remove send_eof, use my_eof instead.

  sql/opt_range.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/opt_sum.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +4 -1
    Always set fatal_error() where it happens, if at all possible.

  sql/protocol.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +78 -187
    Replace send_ok() with public net_send_error(). Remove crude hacks to 
    workaround bugs in the code.
    ---
    Remove send_eof, use my_eof instead.

  sql/protocol.h@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +14 -5
    Update declaration.
    ---
    Remove send_eof, use my_eof instead.

  sql/repl_failsafe.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +6 -4
    Update for COM_TABLE_SEND
    ---
    Remove send_eof, use my_eof instead.

  sql/rpl_record.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +3 -2
    Remove send_eof, use my_eof instead.

  sql/rpl_rli.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +2 -2
    Remove send_eof, use my_eof instead.

  sql/set_var.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/slave.cc@stripped, 2007-10-30 14:54:51+03:00, kostja@bodhi.(none) +32 -16
    Update for COM_TABLE_SEND
    ---
    Remove send_eof, use my_eof instead.

  sql/sp.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +2 -2
    Remove send_eof, use my_eof instead.

  sql/sp_head.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +14 -12
    Another place where it is allowed to clear the diagnostics area.
    ---
    Remove send_eof, use my_eof instead.

  sql/sp_rcontext.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +4 -23
    Remove send_eof, use my_eof instead.

  sql/sql_acl.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +5 -8
    Use my_ok() instead of send_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_base.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +10 -10
    Remove send_eof, use my_eof instead.

  sql/sql_binlog.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +1 -16
    Use my_ok() instead of send_ok().

  sql/sql_cache.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +1 -0
    If response is served from the cache, flag the net to not send anything
    extra.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_class.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +121 -30
    Implement success area in the diagnostics area.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_class.h@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +141 -8
    Implement a class to hold the OK messasge (and other messasges in future).
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_connect.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +83 -72
    Use net_send_ok() in few places where we should speak to the client with
    no barriers.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_db.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +8 -7
    Use my_ok().

  sql/sql_delete.cc@stripped, 2007-10-30 14:54:54+03:00, kostja@bodhi.(none) +25 -11
    Fix a bug in group_min_max.test, lost error of malformed subquery.
    Use my_ok.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_derived.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +3 -2
    Remove send_eof, use my_eof instead.

  sql/sql_do.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +1 -1
    Use my_ok().

  sql/sql_error.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +3 -3
    Remove send_eof, use my_eof instead.

  sql/sql_handler.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +3 -3
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_help.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/sql_insert.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +23 -19
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_load.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +1 -1
    Use my_ok().

  sql/sql_parse.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +136 -147
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_partition.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +4 -1
    Use my_ok().

  sql/sql_prepare.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +19 -25
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_rename.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +1 -1
    Use my_ok().

  sql/sql_repl.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +12 -10
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_select.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +35 -25
    Work in progress. Commit a milestone: passing test suite with send_ok()
    removed.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_servers.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/sql_show.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +41 -30
    Work in progress. Commit a milestone: passing test suite with send_ok()
    removed.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_table.cc@stripped, 2007-10-30 14:54:55+03:00, kostja@bodhi.(none) +18 -17
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_trigger.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +1 -1
    Use my_ok().

  sql/sql_union.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/sql_update.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +7 -7
    Use my_ok().
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_view.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +5 -5
    Replace send_ok() with my_ok(). my_ok() doesn't perform any client
    communication.
    ---
    Remove send_eof, use my_eof instead.

  sql/sql_yacc.yy@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +2 -2
    Remove send_eof, use my_eof instead.

  sql/table.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +14 -13
    Remove send_eof, use my_eof instead.

  sql/tztime.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +1 -1
    Remove send_eof, use my_eof instead.

  sql/unireg.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +2 -2
    Change the implementation of predicate "is there an error in the stack"
    to in all cases check for thd->net.report_error, never for
    thd->net.last_error[0]. last_error buffer should be reusable
    for success messages.
    ---
    Remove send_eof, use my_eof instead.

  storage/myisam/ha_myisam.cc@stripped, 2007-10-30 14:54:56+03:00, kostja@bodhi.(none) +1 -0
    Remove send_eof, use my_eof instead.

diff -Nrup a/include/mysql_com.h b/include/mysql_com.h
--- a/include/mysql_com.h	2007-10-15 15:45:15 +04:00
+++ b/include/mysql_com.h	2007-10-30 14:54:46 +03:00
@@ -202,14 +202,10 @@ typedef struct st_net {
   unsigned int *return_status;
   unsigned char reading_or_writing;
   char save_char;
-  my_bool no_send_ok;  /* For SPs and other things that do multiple stmts */
+  my_bool unused3;  /* Please remove with the next incompatible ABI  change */
   my_bool unused; /* Please remove with the next incompatible ABI change */
   my_bool compress;
-  /*
-    Set if OK packet is already sent, and we do not need to send error
-    messages
-  */
-  my_bool no_send_error;
+  my_bool unused4; /* Please remove with the next ABI change */
   /*
     Pointer to query object in query cache, do not equal NULL (0) for
     queries in cache that have not stored its results yet
@@ -220,11 +216,15 @@ typedef struct st_net {
     functions and methods to maintain proper locking.
   */
   unsigned char *query_cache_query;
-  unsigned int last_errno;
+  unsigned int client_last_errno;
   unsigned char error;
-  my_bool report_error; /* We should report error (we have unreported error) */
+  /* Please move to struct st_mysql */
+  my_bool unused5; /* We should report error (we have unreported error) */
   my_bool return_errno;
-  char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1];
+  /* Please move to struct st_mysql */
+  char client_last_error[MYSQL_ERRMSG_SIZE];
+  /* Please move to struct st_mysql */
+  char client_sqlstate[SQLSTATE_LENGTH+1];
   void *extension;
 } NET;
 
diff -Nrup a/libmysql/libmysql.c b/libmysql/libmysql.c
--- a/libmysql/libmysql.c	2007-10-08 02:05:07 +04:00
+++ b/libmysql/libmysql.c	2007-10-30 14:54:46 +03:00
@@ -427,11 +427,11 @@ static void expand_error(MYSQL* mysql, i
   char tmp[MYSQL_ERRMSG_SIZE];
   char *p;
   uint err_length;
-  strmake(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE-1);
-  p = strmake(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE-1);
-  err_length= (uint) (p - mysql->net.last_error);
+  strmake(tmp, mysql->net.client_last_error, MYSQL_ERRMSG_SIZE-1);
+  p = strmake(mysql->net.client_last_error, ER(error), MYSQL_ERRMSG_SIZE-1);
+  err_length= (uint) (p - mysql->net.client_last_error);
   strmake(p, tmp, MYSQL_ERRMSG_SIZE-1 - err_length);
-  mysql->net.last_errno = error;
+  mysql->net.client_last_errno = error;
 }
 
 /*
@@ -673,9 +673,9 @@ int cli_read_change_user_result(MYSQL *m
     if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
         net_flush(net))
     {
-      net->last_errno= CR_SERVER_LOST;
-      strmov(net->sqlstate, unknown_sqlstate);
-      strmov(net->last_error,ER(net->last_errno));
+      net->client_last_errno= CR_SERVER_LOST;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      strmov(net->client_last_error, ER(net->client_last_errno));
       return 1;
     }
     /* Read what server thinks about out new auth message report */
@@ -847,8 +847,9 @@ my_bool handle_local_infile(MYSQL *mysql
   /* copy filename into local memory and allocate read buffer */
   if (!(buf=my_malloc(packet_length, MYF(0))))
   {
-    strmov(net->sqlstate, unknown_sqlstate);
-    strmov(net->last_error, ER(net->last_errno=CR_OUT_OF_MEMORY));
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    strmov(net->client_last_error,
+           ER(net->client_last_errno=CR_OUT_OF_MEMORY));
     DBUG_RETURN(1);
   }
 
@@ -858,10 +859,10 @@ my_bool handle_local_infile(MYSQL *mysql
   {
     VOID(my_net_write(net,(const uchar*) "",0)); /* Server needs one packet */
     net_flush(net);
-    strmov(net->sqlstate, unknown_sqlstate);
-    net->last_errno= (*options->local_infile_error)(li_ptr,
-						    net->last_error,
-						    sizeof(net->last_error)-1);
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    net->client_last_errno= (*options->local_infile_error)(li_ptr,
+						    net->client_last_error,
+						    sizeof(net->client_last_error)-1);
     goto err;
   }
 
@@ -874,9 +875,9 @@ my_bool handle_local_infile(MYSQL *mysql
     {
       DBUG_PRINT("error",
 		 ("Lost connection to MySQL server during LOAD DATA of local file"));
-      strmov(net->sqlstate, unknown_sqlstate);
-      net->last_errno=CR_SERVER_LOST;
-      strmov(net->last_error,ER(net->last_errno));
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      net->client_last_errno=CR_SERVER_LOST;
+      strmov(net->client_last_error,ER(net->client_last_errno));
       goto err;
     }
   }
@@ -884,17 +885,18 @@ my_bool handle_local_infile(MYSQL *mysql
   /* Send empty packet to mark end of file */
   if (my_net_write(net, (const uchar*) "", 0) || net_flush(net))
   {
-    strmov(net->sqlstate, unknown_sqlstate);
-    net->last_errno=CR_SERVER_LOST;
-    sprintf(net->last_error,ER(net->last_errno),errno);
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    net->client_last_errno=CR_SERVER_LOST;
+    sprintf(net->client_last_error,ER(net->client_last_errno),errno);
     goto err;
   }
 
   if (readcount < 0)
   {
-    net->last_errno= (*options->local_infile_error)(li_ptr,
-						    net->last_error,
-						    sizeof(net->last_error)-1);
+    net->client_last_errno=
+      (*options->local_infile_error)(li_ptr,
+                                     net->client_last_error,
+                                     sizeof(net->client_last_error)-1);
     goto err;
   }
 
@@ -1387,10 +1389,10 @@ const char *cli_read_statistics(MYSQL *m
   mysql->net.read_pos[mysql->packet_length]=0;	/* End of stat string */
   if (!mysql->net.read_pos[0])
   {
-    strmov(mysql->net.sqlstate, unknown_sqlstate);
-    mysql->net.last_errno=CR_WRONG_HOST_INFO;
-    strmov(mysql->net.last_error, ER(mysql->net.last_errno));
-    return mysql->net.last_error;
+    strmov(mysql->net.client_sqlstate, unknown_sqlstate);
+    mysql->net.client_last_errno=CR_WRONG_HOST_INFO;
+    strmov(mysql->net.client_last_error, ER(mysql->net.client_last_errno));
+    return mysql->net.client_last_error;
   }
   return (char*) mysql->net.read_pos;
 }
@@ -1401,7 +1403,7 @@ mysql_stat(MYSQL *mysql)
 {
   DBUG_ENTER("mysql_stat");
   if (simple_command(mysql,COM_STATISTICS,0,0,0))
-    DBUG_RETURN(mysql->net.last_error);
+    DBUG_RETURN(mysql->net.client_last_error);
   DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
 }
 
@@ -1493,7 +1495,7 @@ my_ulonglong STDCALL mysql_insert_id(MYS
 
 const char *STDCALL mysql_sqlstate(MYSQL *mysql)
 {
-  return mysql->net.sqlstate;
+  return mysql->net.client_sqlstate;
 }
 
 uint STDCALL mysql_warning_count(MYSQL *mysql)
@@ -1824,7 +1826,8 @@ static my_bool reset_stmt_handle(MYSQL_S
   RETURN VALUES
     0   Success.
     1   Error, i.e. out of memory or requested packet size is bigger
-        than max_allowed_packet. The error code is stored in net->last_errno.
+        than max_allowed_packet. The error code is stored in
+        net->client_last_errno.
 */
 
 static my_bool my_realloc_str(NET *net, ulong length)
@@ -1845,11 +1848,11 @@ static my_bool my_realloc_str(NET *net, 
 
 static void net_clear_error(NET *net)
 {
-  if (net->last_errno)
+  if (net->client_last_errno)
   {
-    net->last_errno= 0;
-    net->last_error[0]= '\0';
-    strmov(net->sqlstate, not_error_sqlstate);
+    net->client_last_errno= 0;
+    net->client_last_error[0]= '\0';
+    strmov(net->client_sqlstate, not_error_sqlstate);
   }
 }
 
@@ -2110,23 +2113,26 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, con
     stmt->state= MYSQL_STMT_INIT_DONE;
     if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))
     {
-      set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                      mysql->net.sqlstate);
+      set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                      mysql->net.client_last_errno,
+                      mysql->net.client_sqlstate);
       DBUG_RETURN(1);
     }
   }
 
   if (stmt_command(mysql, COM_STMT_PREPARE, (const uchar*) query, length, stmt))
   {
-    set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                    mysql->net.sqlstate);
+    set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                    mysql->net.client_last_errno,
+                    mysql->net.client_sqlstate);
     DBUG_RETURN(1);
   }
 
   if ((*mysql->methods->read_prepare_result)(mysql, stmt))
   {
-    set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                    mysql->net.sqlstate);
+    set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                    mysql->net.client_last_errno,
+                    mysql->net.client_sqlstate);
     DBUG_RETURN(1);
   }
 
@@ -2504,7 +2510,7 @@ static my_bool store_param(MYSQL_STMT *s
     */
     if ((my_realloc_str(net, *param->length)))
     {
-      set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
+      set_stmt_error(stmt, net->client_last_errno, unknown_sqlstate);
       DBUG_RETURN(1);
     }
     (*param->store_param_func)(net, param);
@@ -2541,7 +2547,8 @@ static my_bool execute(MYSQL_STMT *stmt,
   stmt->insert_id= mysql->insert_id;
   if (res)
   {
-    set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+    set_stmt_errmsg(stmt, net->client_last_error, net->client_last_errno,
+                    net->client_sqlstate);
     DBUG_RETURN(1);
   }
   DBUG_RETURN(0);
@@ -2579,7 +2586,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
     null_count= (stmt->param_count+7) /8;
     if (my_realloc_str(net, null_count + 1))
     {
-      set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
+      set_stmt_error(stmt, net->client_last_errno, unknown_sqlstate);
       DBUG_RETURN(1);
     }
     bzero((char*) net->write_pos, null_count);
@@ -2592,7 +2599,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
     {
       if (my_realloc_str(net, 2 * stmt->param_count))
       {
-        set_stmt_error(stmt, net->last_errno, unknown_sqlstate);
+        set_stmt_error(stmt, net->client_last_errno, unknown_sqlstate);
         DBUG_RETURN(1);
       }
       /*
@@ -2691,8 +2698,9 @@ static int stmt_read_row_unbuffered(MYSQ
   }
   if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row))
   {
-    set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                    mysql->net.sqlstate);
+    set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                    mysql->net.client_last_errno,
+                    mysql->net.client_sqlstate);
     /*
       If there was an error, there are no more pending rows:
       reset statement status to not hang up in following
@@ -2753,7 +2761,8 @@ stmt_read_row_from_cursor(MYSQL_STMT *st
                                             buff, sizeof(buff), (uchar*) 0, 0,
                                             1, NULL))
     {
-      set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+      set_stmt_errmsg(stmt, net->client_last_error, net->client_last_errno,
+                      net->client_sqlstate);
       return 1;
     }
     if ((*mysql->methods->read_rows_from_cursor)(stmt))
@@ -3420,8 +3429,9 @@ mysql_stmt_send_long_data(MYSQL_STMT *st
                                             buff, sizeof(buff), (uchar*) data,
                                             length, 1, NULL))
     {
-      set_stmt_errmsg(stmt, mysql->net.last_error,
-		      mysql->net.last_errno, mysql->net.sqlstate);
+      set_stmt_errmsg(stmt, mysql->net.client_last_error,
+		      mysql->net.client_last_errno,
+                      mysql->net.client_sqlstate);
       DBUG_RETURN(1);
     }
   }
@@ -4742,7 +4752,8 @@ int cli_read_binary_rows(MYSQL_STMT *stm
       DBUG_RETURN(0);
     }
   }
-  set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+  set_stmt_errmsg(stmt, net->client_last_error, net->client_last_errno,
+                  net->client_sqlstate);
 
 err:
   DBUG_RETURN(1);
@@ -4829,7 +4840,8 @@ int STDCALL mysql_stmt_store_result(MYSQ
     if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
                              (uchar*) 0, 0, 1, NULL))
     {
-      set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+      set_stmt_errmsg(stmt, net->client_last_error, net->client_last_errno,
+                      net->client_sqlstate);
       DBUG_RETURN(1);
     }
   }
@@ -5016,8 +5028,9 @@ static my_bool reset_stmt_handle(MYSQL_S
         if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff,
                                                 sizeof(buff), 0, 0, 0, NULL))
         {
-          set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                          mysql->net.sqlstate);
+          set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                          mysql->net.client_last_errno,
+                          mysql->net.client_sqlstate);
           stmt->state= MYSQL_STMT_INIT_DONE;
           return 1;
         }
@@ -5090,8 +5103,9 @@ my_bool STDCALL mysql_stmt_close(MYSQL_S
       int4store(buff, stmt->stmt_id);
       if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
       {
-        set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
-                        mysql->net.sqlstate);
+        set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                        mysql->net.client_last_errno,
+                        mysql->net.client_sqlstate);
       }
     }
   }
@@ -5216,15 +5230,15 @@ int STDCALL mysql_next_result(MYSQL *mys
 
   if (mysql->status != MYSQL_STATUS_READY)
   {
-    strmov(mysql->net.sqlstate, unknown_sqlstate);
-    strmov(mysql->net.last_error,
-	   ER(mysql->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
+    strmov(mysql->net.client_sqlstate, unknown_sqlstate);
+    strmov(mysql->net.client_last_error,
+	   ER(mysql->net.client_last_errno=CR_COMMANDS_OUT_OF_SYNC));
     DBUG_RETURN(1);
   }
 
-  mysql->net.last_error[0]= 0;
-  mysql->net.last_errno= 0;
-  strmov(mysql->net.sqlstate, not_error_sqlstate);
+  mysql->net.client_last_error[0]= 0;
+  mysql->net.client_last_errno= 0;
+  strmov(mysql->net.client_sqlstate, not_error_sqlstate);
   mysql->affected_rows= ~(my_ulonglong) 0;
 
   if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)
diff -Nrup a/libmysql/manager.c b/libmysql/manager.c
--- a/libmysql/manager.c	2007-08-13 17:11:09 +04:00
+++ b/libmysql/manager.c	2007-10-30 14:54:46 +03:00
@@ -160,7 +160,7 @@ MYSQL_MANAGER*  STDCALL mysql_manager_co
   msg_len=strlen(msg_buf);
   if (my_net_write(&con->net,(uchar*) msg_buf,msg_len) ||
net_flush(&con->net))
   {
-    con->last_errno=con->net.last_errno;
+    con->last_errno=con->net.client_last_errno;
     strmov(con->last_error,"Write error on socket");
     goto err;
   }
diff -Nrup a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
--- a/libmysqld/emb_qcache.cc	2007-05-10 13:59:24 +04:00
+++ b/libmysqld/emb_qcache.cc	2007-10-30 14:54:46 +03:00
@@ -447,7 +447,7 @@ int emb_load_querycache_result(THD *thd,
   *prev_row= NULL;
   data->embedded_info->prev_ptr= prev_row;
 return_ok:
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(0);
 err:
   DBUG_RETURN(1);
diff -Nrup a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
--- a/libmysqld/lib_sql.cc	2007-10-10 04:12:09 +04:00
+++ b/libmysqld/lib_sql.cc	2007-10-30 14:54:46 +03:00
@@ -61,9 +61,9 @@ void embedded_get_error(MYSQL *mysql, MY
 {
   NET *net= &mysql->net;
   struct embedded_query_result *ei= data->embedded_info;
-  net->last_errno= ei->last_errno;
-  strmake(net->last_error, ei->info, sizeof(net->last_error));
-  memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
+  net->client_last_errno= ei->last_errno;
+  strmake(net->client_last_error, ei->info, sizeof(net->client_last_error));
+  memcpy(net->client_sqlstate, ei->sqlstate, sizeof(net->client_sqlstate));
   my_free(data, MYF(0));
 }
 
@@ -81,8 +81,8 @@ emb_advanced_command(MYSQL *mysql, enum 
   /* Check that we are calling the client functions in right order */
   if (mysql->status != MYSQL_STATUS_READY)
   {
-    strmov(net->last_error,
-	   ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC));
+    strmov(net->client_last_error,
+	   ER(net->client_last_errno=CR_COMMANDS_OUT_OF_SYNC));
     return 1;
   }
 
@@ -90,7 +90,7 @@ emb_advanced_command(MYSQL *mysql, enum 
   thd->clear_error();
   mysql->affected_rows= ~(my_ulonglong) 0;
   mysql->field_count= 0;
-  net->last_errno= 0;
+  net->client_last_errno= 0;
   thd->current_stmt= stmt;
 
   thd->store_globals();				// Fix if more than one connect
@@ -110,12 +110,11 @@ emb_advanced_command(MYSQL *mysql, enum 
     arg_length= header_length;
   }
 
-  thd->net.no_send_error= 0;
   result= dispatch_command(command, thd, (char *) arg, arg_length);
   thd->cur_data= 0;
 
   if (!skip_check)
-    result= thd->net.last_errno ? -1 : 0;
+    result= thd->is_error() ? -1 : 0;
 
   return result;
 }
@@ -245,8 +244,8 @@ static my_bool emb_read_query_result(MYS
   mysql->fields= res->embedded_info->fields_list;
   mysql->affected_rows= res->embedded_info->affected_rows;
   mysql->insert_id= res->embedded_info->insert_id;
-  mysql->net.last_errno= 0;
-  mysql->net.last_error[0]= 0;
+  mysql->net.client_last_errno= 0;
+  mysql->net.client_last_error[0]= 0;
   mysql->info= 0;
 
   if (res->embedded_info->info[0])
@@ -288,7 +287,8 @@ static int emb_stmt_execute(MYSQL_STMT *
   if (res)
   {
     NET *net= &stmt->mysql->net;
-    set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
+    set_stmt_errmsg(stmt, net->client_last_error, net->client_last_errno,
+                    net->client_sqlstate);
     DBUG_RETURN(1);
   }
   DBUG_RETURN(0);
@@ -299,14 +299,16 @@ int emb_read_binary_rows(MYSQL_STMT *stm
   MYSQL_DATA *data;
   if (!(data= emb_read_rows(stmt->mysql, 0, 0)))
   {
-    set_stmt_errmsg(stmt, stmt->mysql->net.last_error,
-                    stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
+    set_stmt_errmsg(stmt, stmt->mysql->net.client_last_error,
+                    stmt->mysql->net.client_last_errno,
+                    stmt->mysql->net.client_sqlstate);
     return 1;
   }
   stmt->result= *data;
   my_free((char *) data, MYF(0));
-  set_stmt_errmsg(stmt, stmt->mysql->net.last_error,
-                  stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
+  set_stmt_errmsg(stmt, stmt->mysql->net.client_last_error,
+                  stmt->mysql->net.client_last_errno,
+                  stmt->mysql->net.client_sqlstate);
   return 0;
 }
 
@@ -320,16 +322,16 @@ int emb_read_rows_from_cursor(MYSQL_STMT
   if (res->embedded_info->last_errno)
   {
     embedded_get_error(mysql, res);
-    set_stmt_errmsg(stmt, mysql->net.last_error,
-                    mysql->net.last_errno, mysql->net.sqlstate);
+    set_stmt_errmsg(stmt, mysql->net.client_last_error,
+                    mysql->net.client_last_errno, mysql->net.client_sqlstate);
     return 1;
   }
 
   thd->cur_data= res;
   mysql->warning_count= res->embedded_info->warning_count;
   mysql->server_status= res->embedded_info->server_status;
-  mysql->net.last_errno= 0;
-  mysql->net.last_error[0]= 0;
+  mysql->net.client_last_errno= 0;
+  mysql->net.client_last_error[0]= 0;
 
   return emb_read_binary_rows(stmt);
 }
@@ -375,7 +377,7 @@ static void emb_free_embedded_thd(MYSQL 
 static const char * emb_read_statistics(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  return thd->net.last_error;
+  return thd->is_error() ? thd->main_da.message() : "";
 }
 
 
@@ -679,8 +681,8 @@ int check_embedded_connection(MYSQL *mys
 err:
   {
     NET *net= &mysql->net;
-    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
-    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
+    memcpy(net->client_last_error,
+           thd->main_da.message, sizeof(net->client_last_error));
   }
   return result;
 }
@@ -703,9 +705,8 @@ void THD::clear_data_list()
 
 void THD::clear_error()
 {
-  net.last_error[0]= 0;
-  net.last_errno= 0;
-  net.report_error= 0;
+  if (main_da.is_error())
+    main_da.reset_diagnostics_area();
 }
 
 static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
@@ -781,7 +782,8 @@ MYSQL_DATA *THD::alloc_new_dataset()
 
 */
 
-static void write_eof_packet(THD *thd)
+static void write_eof_packet(THD *thd, uint server_status,
+                             uint total_warn_count)
 {
   if (!thd->mysql)            // bootstrap file handling
     return;
@@ -792,13 +794,13 @@ static void write_eof_packet(THD *thd)
   */
   if (thd->is_fatal_error)
     thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
-  thd->cur_data->embedded_info->server_status= thd->server_status;
+  thd->cur_data->embedded_info->server_status= server_status;
   /*
     Don't send warn count during SP execution, as the warn_list
     is cleared between substatements, and mysqltest gets confused
   */
   thd->cur_data->embedded_info->warning_count=
-    (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
+    (thd->spcont ? 0 : min(total_warn_count, 65535));
 }
 
 
@@ -954,7 +956,7 @@ bool Protocol::send_fields(List<Item> *l
   }
 
   if (flags & SEND_EOF)
-    write_eof_packet(thd);
+    write_eof_packet(thd, thd->server_status, thd->total_warn_count);
 
   DBUG_RETURN(prepare_for_send(list));
  err:
@@ -995,16 +997,16 @@ bool Protocol_binary::write()
 }
 
 void
-send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
+net_send_ok(THD *thd,
+            uint server_status, uint total_warn_count,
+            ha_rows affected_rows, ulonglong id, const char *message)
 {
   DBUG_ENTER("send_ok");
   MYSQL_DATA *data;
   MYSQL *mysql= thd->mysql;
-  
+
   if (!mysql)            // bootstrap file handling
     DBUG_VOID_RETURN;
-  if (thd->net.no_send_ok)	// hack for re-parsing queries
-    DBUG_VOID_RETURN;
   if (!(data= thd->alloc_new_dataset()))
     return;
   data->embedded_info->affected_rows= affected_rows;
@@ -1013,15 +1015,15 @@ send_ok(THD *thd,ha_rows affected_rows,u
     strmake(data->embedded_info->info, message,
             sizeof(data->embedded_info->info)-1);
 
-  write_eof_packet(thd);
+  write_eof_packet(thd, server_status, total_warn_count);
   thd->cur_data= 0;
   DBUG_VOID_RETURN;
 }
 
 void
-send_eof(THD *thd)
+net_send_eof(THD *thd, uint server_status, uint total_warn_count)
 {
-  write_eof_packet(thd);
+  write_eof_packet(thd, server_status, total_warn_count);
   thd->cur_data= 0;
 }
 
diff -Nrup a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
--- a/libmysqld/libmysqld.c	2007-03-28 22:05:00 +04:00
+++ b/libmysqld/libmysqld.c	2007-10-30 14:54:46 +03:00
@@ -209,8 +209,8 @@ mysql_real_connect(MYSQL *mysql,const ch
   DBUG_RETURN(mysql);
 
 error:
-  DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
-		      mysql->net.last_error));
+  DBUG_PRINT("error",("message: %u (%s)", mysql->net.client_last_errno,
+		      mysql->net.client_last_error));
   {
     /* Free alloced memory */
     my_bool free_me=mysql->free_me;
diff -Nrup a/mysql-test/r/events.result b/mysql-test/r/events.result
--- a/mysql-test/r/events.result	2007-08-31 18:49:39 +04:00
+++ b/mysql-test/r/events.result	2007-10-30 14:54:46 +03:00
@@ -403,9 +403,10 @@ ERROR 42S02: Table 'mysql.event' doesn't
 DROP DATABASE IF EXISTS mysqltest_no_such_database;
 Warnings:
 Note	1008	Can't drop database 'mysqltest_no_such_database'; database doesn't exist
-Error	1146	Table 'mysql.event' doesn't exist
 CREATE DATABASE mysqltest_db2;
 DROP DATABASE mysqltest_db2;
+Warnings:
+Error	1146	Table 'mysql.event' doesn't exist
 OK, there is an unnecessary warning about the non-existent table 
 but it's not easy to fix and no one complained about it.
 A similar warning is printed if mysql.proc is missing.
diff -Nrup a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
--- a/mysql-test/r/group_min_max.result	2007-08-02 23:45:48 +04:00
+++ b/mysql-test/r/group_min_max.result	2007-10-30 14:54:46 +03:00
@@ -2299,8 +2299,7 @@ Handler_read_next	0
 FLUSH STATUS;
 DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x 
 FROM t1) > 10000;
-Warnings:
-Error	1242	Subquery returns more than 1 row
+ERROR 21000: Subquery returns more than 1 row
 SHOW STATUS LIKE 'handler_read__e%';
 Variable_name	Value
 Handler_read_key	8
diff -Nrup a/mysql-test/r/udf.result b/mysql-test/r/udf.result
--- a/mysql-test/r/udf.result	2007-08-06 05:37:51 +04:00
+++ b/mysql-test/r/udf.result	2007-10-30 14:54:46 +03:00
@@ -11,7 +11,7 @@ RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
 CREATE AGGREGATE FUNCTION avgcost
 RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
 select myfunc_double();
-ERROR HY000: myfunc_double must have at least one argument
+ERROR HY000: Can't initialize function 'myfunc_double'; myfunc_double must have at least
one argument
 select myfunc_double(1);
 myfunc_double(1)
 49.00
@@ -24,26 +24,26 @@ select myfunc_int();
 myfunc_int()
 0
 select lookup();
-ERROR HY000: Wrong arguments to lookup;  Use the source
+ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup;  Use the
source
 select lookup("127.0.0.1");
 lookup("127.0.0.1")
 127.0.0.1
 select lookup(127,0,0,1);
-ERROR HY000: Wrong arguments to lookup;  Use the source
+ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup;  Use the
source
 select lookup("localhost");
 lookup("localhost")
 127.0.0.1
 select reverse_lookup();
-ERROR HY000: Wrong number of arguments to reverse_lookup;  Use the source
+ERROR HY000: Can't initialize function 'reverse_lookup'; Wrong number of arguments to
reverse_lookup;  Use the source
 select reverse_lookup("127.0.0.1");
 select reverse_lookup(127,0,0,1);
 select reverse_lookup("localhost");
 reverse_lookup("localhost")
 NULL
 select avgcost();
-ERROR HY000: wrong number of arguments: AVGCOST() requires two arguments
+ERROR HY000: Can't initialize function 'avgcost'; wrong number of arguments: AVGCOST()
requires two arguments
 select avgcost(100,23.76);
-ERROR HY000: wrong argument type: AVGCOST() requires an INT and a REAL
+ERROR HY000: Can't initialize function 'avgcost'; wrong argument type: AVGCOST() requires
an INT and a REAL
 create table t1(sum int, price float(24));
 insert into t1 values(100, 50.00), (100, 100.00);
 select avgcost(sum, price) from t1;
diff -Nrup a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc
b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc
--- a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc	2007-08-28 04:33:52 +04:00
+++ b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc	2007-10-30 14:54:46 +03:00
@@ -51,9 +51,10 @@ DELETE FROM t2 WHERE a = 2;
 
 --echo
 --echo ******************** LOAD DATA INFILE ********************
+
 --exec cp ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/
 LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;
---exec rm $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
+--remove_file $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
 SELECT * FROM t1;
 --source suite/rpl/include/rpl_mixed_check_select.inc
 --source suite/rpl/include/rpl_mixed_clear_tables.inc
diff -Nrup a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result
--- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result	2007-09-25 19:44:47 +04:00
+++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result	2007-10-30 14:54:49 +03:00
@@ -123,7 +123,7 @@ Replicate_Ignore_Table	
 Replicate_Wild_Do_Table	
 Replicate_Wild_Ignore_Table	
 Last_Errno	1364
-Last_Error	Error in Write_rows event: error during transaction execution on table
test.t1_nodef. 
+Last_Error	Error in Write_rows event: error during transaction execution on table
test.t1_nodef. Field 'x' doesn't have a default value
 Skip_Counter	0
 Exec_Master_Log_Pos	#
 Relay_Log_Space	#
@@ -141,7 +141,7 @@ Master_SSL_Verify_Server_Cert	No
 Last_IO_Errno	0
 Last_IO_Error	
 Last_SQL_Errno	1364
-Last_SQL_Error	Error in Write_rows event: error during transaction execution on table
test.t1_nodef. 
+Last_SQL_Error	Error in Write_rows event: error during transaction execution on table
test.t1_nodef. Field 'x' doesn't have a default value
 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
 START SLAVE;
 INSERT INTO t9 VALUES (2);
diff -Nrup a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
--- a/mysql-test/t/group_min_max.test	2007-06-25 06:06:04 +04:00
+++ b/mysql-test/t/group_min_max.test	2007-10-30 14:54:49 +03:00
@@ -890,6 +890,7 @@ FLUSH STATUS;
 DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000;
 SHOW STATUS LIKE 'handler_read__e%';
 FLUSH STATUS;
+--error ER_SUBQUERY_NO_1_ROW
 DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x 
                       FROM t1) > 10000;
 SHOW STATUS LIKE 'handler_read__e%';
diff -Nrup a/mysql-test/t/udf.test b/mysql-test/t/udf.test
--- a/mysql-test/t/udf.test	2007-08-06 05:37:51 +04:00
+++ b/mysql-test/t/udf.test	2007-10-30 14:54:49 +03:00
@@ -35,20 +35,20 @@ eval CREATE FUNCTION reverse_lookup
 eval CREATE AGGREGATE FUNCTION avgcost
         RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
 
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select myfunc_double();
 select myfunc_double(1);
 select myfunc_double(78654);
 --error 1305
 select myfunc_nonexist();
 select myfunc_int();
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select lookup();
 select lookup("127.0.0.1");
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select lookup(127,0,0,1);
 select lookup("localhost");
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select reverse_lookup();
 
 # These two functions should return "localhost", but it's
@@ -59,9 +59,9 @@ select reverse_lookup(127,0,0,1);
 --enable_result_log
 
 select reverse_lookup("localhost");
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select avgcost();
---error 0
+--error ER_CANT_INITIALIZE_UDF
 select avgcost(100,23.76);
 create table t1(sum int, price float(24));
 insert into t1 values(100, 50.00), (100, 100.00);
diff -Nrup a/server-tools/instance-manager/mysql_connection.cc
b/server-tools/instance-manager/mysql_connection.cc
--- a/server-tools/instance-manager/mysql_connection.cc	2007-06-05 19:31:39 +04:00
+++ b/server-tools/instance-manager/mysql_connection.cc	2007-10-30 14:54:49 +03:00
@@ -257,7 +257,7 @@ int Mysql_connection::do_command()
       return 1;
     if (thread_registry->is_shutdown())
       return 1;
-    net_send_error(&net, net.last_errno);
+    net_send_error(&net, net.client_last_errno);
     net.error= 0;
     return 0;
   }
diff -Nrup a/sql/events.cc b/sql/events.cc
--- a/sql/events.cc	2007-08-15 19:08:40 +04:00
+++ b/sql/events.cc	2007-10-30 14:54:49 +03:00
@@ -737,7 +737,7 @@ send_show_create_event(THD *thd, Event_t
   if (protocol->write())
     DBUG_RETURN(TRUE);
 
-  send_eof(thd);
+  my_eof(thd);
 
   DBUG_RETURN(FALSE);
 }
diff -Nrup a/sql/filesort.cc b/sql/filesort.cc
--- a/sql/filesort.cc	2007-07-26 00:23:37 +04:00
+++ b/sql/filesort.cc	2007-10-30 14:54:50 +03:00
@@ -555,7 +555,7 @@ static ha_rows find_all_keys(SORTPARAM *
     else
       file->unlock_row();
     /* It does not make sense to read more keys in case of a fatal error */
-    if (thd->net.report_error)
+    if (thd->is_error())
       DBUG_RETURN(HA_POS_ERROR);
   }
   if (quick_select)
diff -Nrup a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
--- a/sql/ha_ndbcluster_binlog.cc	2007-09-07 13:15:04 +04:00
+++ b/sql/ha_ndbcluster_binlog.cc	2007-10-30 14:54:50 +03:00
@@ -257,6 +257,11 @@ static void run_query(THD *thd, char *bu
     thd->options&= ~OPTION_BIN_LOG;
     
   DBUG_PRINT("query", ("%s", thd->query));
+
+  DBUG_ASSERT(!thd->in_sub_stmt);
+  DBUG_ASSERT(!thd->prelocked_mode);
+
+  mysql_reset_thd_for_next_command(thd);
   mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
 
   if (no_print_error && thd->query_error)
@@ -265,14 +270,15 @@ static void run_query(THD *thd, char *bu
     Thd_ndb *thd_ndb= get_thd_ndb(thd);
     for (i= 0; no_print_error[i]; i++)
       if ((thd_ndb->m_error_code == no_print_error[i]) ||
-          (thd->net.last_errno == (unsigned)no_print_error[i]))
+          (thd->main_da.sql_errno() == (unsigned)no_print_error[i]))
         break;
     if (!no_print_error[i])
       sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
-                      buf, thd->net.last_error, thd->net.last_errno,
+                      buf, thd->main_da.message(), thd->main_da.sql_errno(),
                       thd_ndb->m_error_code,
-                      thd->net.report_error, thd->query_error);
+                      thd->is_error(), thd->query_error);
   }
+  thd->main_da.reset_diagnostics_area();
 
   thd->options= save_thd_options;
   thd->query_length= save_query_length;
@@ -2301,8 +2307,8 @@ static int open_ndb_binlog_index(THD *th
   if (open_tables(thd, &tables, &counter, MYSQL_LOCK_IGNORE_FLUSH))
   {
     sql_print_error("NDB Binlog: Opening ndb_binlog_index: %d, '%s'",
-                    thd->net.last_errno,
-                    thd->net.last_error ? thd->net.last_error : "");
+                    thd->main_da.sql_errno(),
+                    thd->main_da.message());
     thd->proc_info= save_proc_info;
     return -1;
   }
diff -Nrup a/sql/ha_partition.cc b/sql/ha_partition.cc
--- a/sql/ha_partition.cc	2007-09-24 17:33:39 +04:00
+++ b/sql/ha_partition.cc	2007-10-30 14:54:50 +03:00
@@ -1753,6 +1753,7 @@ partition_element *ha_partition::find_pa
   }
   DBUG_ASSERT(0);
   current_thd->fatal_error();                   // Abort
+  my_error(ER_OUT_OF_RESOURCES, MYF(0));
   return NULL;
 }
 
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-08-31 10:57:57 +04:00
+++ b/sql/handler.cc	2007-10-30 14:54:50 +03:00
@@ -1191,7 +1191,7 @@ bool mysql_xa_recover(THD *thd)
   }
 
   pthread_mutex_unlock(&LOCK_xid_cache);
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(0);
 }
 
@@ -1414,6 +1414,30 @@ static const char *check_lowercase_names
 }
 
 
+struct Ha_delete_table_error_handler: public Internal_error_handler
+{
+public:
+  virtual bool handle_error(uint sql_errno,
+                            const char *message,
+                            MYSQL_ERROR::enum_warning_level level,
+                            THD *thd);
+  char buff[MYSQL_ERRMSG_SIZE];
+};
+
+
+bool
+Ha_delete_table_error_handler::
+handle_error(uint sql_errno,
+             const char *message,
+             MYSQL_ERROR::enum_warning_level level,
+             THD *thd)
+{
+  /* Grab the error message */
+  strmake(buff, message, sizeof(buff)-1);
+  return TRUE;
+}
+
+
 /** @brief
   This should return ENOENT if the file doesn't exists.
   The .frm file will be deleted only if we return 0 or ENOENT
@@ -1440,25 +1464,7 @@ int ha_delete_table(THD *thd, handlerton
   path= check_lowercase_names(file, path, tmp_path);
   if ((error= file->delete_table(path)) && generate_warning)
   {
-    /*
-      Because file->print_error() use my_error() to generate the error message
-      we must store the error state in thd, reset it and restore it to
-      be able to get hold of the error message.
-      (We should in the future either rewrite handler::print_error() or make
-      a nice method of this.
-    */
-    bool query_error= thd->query_error;
-    sp_rcontext *spcont= thd->spcont;
-    SELECT_LEX *current_select= thd->lex->current_select;
-    char buff[sizeof(thd->net.last_error)];
-    char new_error[sizeof(thd->net.last_error)];
-    int last_errno= thd->net.last_errno;
-
-    strmake(buff, thd->net.last_error, sizeof(buff)-1);
-    thd->query_error= 0;
-    thd->spcont= NULL;
-    thd->lex->current_select= 0;
-    thd->net.last_error[0]= 0;
+    Ha_delete_table_error_handler ha_delete_table_error_handler;
 
     /* Fill up strucutures that print_error may need */
     dummy_share.path.str= (char*) path;
@@ -1471,16 +1477,14 @@ int ha_delete_table(THD *thd, handlerton
 
     file->table_share= &dummy_share;
     file->table= &dummy_table;
+
+    thd->push_internal_handler(&ha_delete_table_error_handler);
     file->print_error(error, 0);
-    strmake(new_error, thd->net.last_error, sizeof(buff)-1);
 
-    /* restore thd */
-    thd->query_error= query_error;
-    thd->spcont= spcont;
-    thd->lex->current_select= current_select;
-    thd->net.last_errno= last_errno;
-    strmake(thd->net.last_error, buff, sizeof(buff)-1);
-    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, new_error);
+    thd->pop_internal_handler();
+
+    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
+                ha_delete_table_error_handler.buff);
   }
   delete file;
   DBUG_RETURN(error);
@@ -2203,7 +2207,7 @@ void handler::print_error(int error, myf
   case HA_ERR_NO_SUCH_TABLE:
     my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
              table_share->table_name.str);
-    break;
+    DBUG_VOID_RETURN;
   case HA_ERR_RBR_LOGGING_FAILED:
     textno= ER_BINLOG_ROW_LOGGING_FAILED;
     break;
@@ -3440,7 +3444,7 @@ bool ha_show_status(THD *thd, handlerton
   }
 
   if (!result)
-    send_eof(thd);
+    my_eof(thd);
   return result;
 }
 
diff -Nrup a/sql/item_func.cc b/sql/item_func.cc
--- a/sql/item_func.cc	2007-10-10 13:35:38 +04:00
+++ b/sql/item_func.cc	2007-10-30 14:54:50 +03:00
@@ -187,7 +187,7 @@ Item_func::fix_fields(THD *thd, Item **r
     }
   }
   fix_length_and_dec();
-  if (thd->net.report_error) // An error inside fix_length_and_dec occured
+  if (thd->is_error()) // An error inside fix_length_and_dec occured
     return TRUE;
   fixed= 1;
   return FALSE;
@@ -2892,6 +2892,7 @@ udf_handler::fix_fields(THD *thd, Item_r
 
   if (u_d->func_init)
   {
+    char init_msg_buff[MYSQL_ERRMSG_SIZE];
     char *to=num_buffer;
     for (uint i=0; i < arg_count; i++)
     {
@@ -2942,12 +2943,11 @@ udf_handler::fix_fields(THD *thd, Item_r
         }
       }
     }
-    thd->net.last_error[0]=0;
     Udf_func_init init= u_d->func_init;
-    if ((error=(uchar) init(&initid, &f_args, thd->net.last_error)))
+    if ((error=(uchar) init(&initid, &f_args, init_msg_buff)))
     {
       my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
-               u_d->name.str, thd->net.last_error);
+               u_d->name.str, init_msg_buff);
       free_udf(u_d);
       DBUG_RETURN(TRUE);
     }
@@ -3928,6 +3928,7 @@ Item_func_set_user_var::update_hash(void
                     ptr, length, res_type, cs, dv, unsigned_arg))
   {
     current_thd->fatal_error();     // Probably end of memory
+    my_error(ER_OUTOFMEMORY, MYF(0));
     null_value= 1;
     return 1;
   }
@@ -4061,7 +4062,7 @@ my_decimal *user_var_entry::val_decimal(
 
   NOTES
     For now it always return OK. All problem with value evaluating
-    will be caught by thd->net.report_error check in sql_set_variables().
+    will be caught by thd->is_error() check in sql_set_variables().
 
   RETURN
     FALSE OK.
diff -Nrup a/sql/item_subselect.cc b/sql/item_subselect.cc
--- a/sql/item_subselect.cc	2007-08-25 12:43:12 +04:00
+++ b/sql/item_subselect.cc	2007-10-30 14:54:50 +03:00
@@ -248,7 +248,7 @@ bool Item_subselect::exec()
 {
   int res;
 
-  if (thd->net.report_error)
+  if (thd->is_error())
   /* Do not execute subselect in case of a fatal error */
     return 1;
 
diff -Nrup a/sql/log.cc b/sql/log.cc
--- a/sql/log.cc	2007-10-12 03:55:16 +04:00
+++ b/sql/log.cc	2007-10-30 14:54:50 +03:00
@@ -72,13 +72,14 @@ public:
 
   virtual ~Silence_log_table_errors() {}
 
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd);
 };
 
 bool
 Silence_log_table_errors::handle_error(uint /* sql_errno */,
+                                       const char * /* message */,
                                        MYSQL_ERROR::enum_warning_level /* level */,
                                        THD * /* thd */)
 {
diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc	2007-09-28 22:14:40 +04:00
+++ b/sql/log_event.cc	2007-10-30 14:54:50 +03:00
@@ -1510,7 +1510,8 @@ Query_log_event::Query_log_event(THD* th
   if (killed_status_arg == THD::KILLED_NO_VALUE)
     killed_status_arg= thd_arg->killed;
   error_code=
-    (killed_status_arg == THD::NOT_KILLED) ? thd_arg->net.last_errno :
+    (killed_status_arg == THD::NOT_KILLED) ?
+    (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
     ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
      thd_arg->killed_errno());
   
@@ -2083,6 +2084,7 @@ int Query_log_event::do_apply_event(Rela
       
       /* Execute the query (note that we bypass dispatch_command()) */
       const char* found_semicolon= NULL;
+      mysql_reset_thd_for_next_command(thd);
       mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
       log_slow_statement(thd);
     }
@@ -2112,7 +2114,7 @@ START SLAVE; . Query: '%s'", expected_er
     }
 
     /* If the query was not ignored, it is printed to the general log */
-    if (thd->net.last_errno != ER_SLAVE_IGNORED_TABLE)
+    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
       general_log_print(thd, COM_QUERY, "%s", thd->query);
 
 compare_errors:
@@ -2121,9 +2123,10 @@ compare_errors:
       If we expected a non-zero error code, and we don't get the same error
       code, and none of them should be ignored.
     */
-    DBUG_PRINT("info",("expected_error: %d  last_errno: %d",
- 		       expected_error, thd->net.last_errno));
-    if ((expected_error != (actual_error= thd->net.last_errno)) &&
+    actual_error= thd->is_error() ?  thd->main_da.sql_errno() : 0;
+    DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
+ 		       expected_error, actual_error));
+    if ((expected_error != actual_error) &&
  	expected_error &&
  	!ignored_error_code(actual_error) &&
  	!ignored_error_code(expected_error))
@@ -2135,7 +2138,7 @@ Error on master: '%s' (%d), Error on sla
 Default database: '%s'. Query: '%s'",
                       ER_SAFE(expected_error),
                       expected_error,
-                      actual_error ? thd->net.last_error: "no error",
+                      actual_error ? thd->main_da.message() : "no error",
                       actual_error,
                       print_slave_db_safe(db), query_arg);
       thd->query_error= 1;
@@ -2157,7 +2160,7 @@ Default database: '%s'. Query: '%s'",
     {
       rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' on query. Default database: '%s'. Query: '%s'",
-                      (actual_error ? thd->net.last_error :
+                      (actual_error ? thd->main_da.message():
                        "unexpected success or fatal error"),
                       print_slave_db_safe(thd->db), query_arg);
       thd->query_error= 1;
@@ -3475,8 +3478,11 @@ error:
     /* this err/sql_errno code is copy-paste from net_send_error() */
     const char *err;
     int sql_errno;
-    if ((err=thd->net.last_error)[0])
-      sql_errno=thd->net.last_errno;
+    if (thd->main_da.is_error())
+    {
+      err= thd->main_da.message();
+      sql_errno= thd->main_da.sql_errno();
+    }
     else
     {
       sql_errno=ER_UNKNOWN_ERROR;
@@ -5957,10 +5963,10 @@ int Rows_log_event::do_apply_event(Relay
             Error reporting borrowed from Query_log_event with many excessive
             simplifications (we don't honour --slave-skip-errors)
           */
-          uint actual_error= thd->net.last_errno;
+          uint actual_error= thd->main_da.sql_errno();
           rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' in %s event: when locking tables",
-                      (actual_error ? thd->net.last_error :
+                      (actual_error ? thd->main_da.message():
                        "unexpected success or fatal error"),
                       get_type_str());
           thd->is_fatal_error= 1;
@@ -6001,10 +6007,10 @@ int Rows_log_event::do_apply_event(Relay
             Error reporting borrowed from Query_log_event with many excessive
             simplifications (we don't honour --slave-skip-errors)
           */
-          uint actual_error= thd->net.last_errno;
+          uint actual_error= thd->main_da.sql_errno();
           rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' on reopening tables",
-                      (actual_error ? thd->net.last_error :
+                      (actual_error ? thd->main_da.message() :
                        "unexpected success or fatal error"));
           thd->query_error= 1;
         }
@@ -6155,10 +6161,11 @@ int Rows_log_event::do_apply_event(Relay
 	break;
 
       default:
-	rli->report(ERROR_LEVEL, thd->net.last_errno,
+	rli->report(ERROR_LEVEL,
+                    thd->is_error() ? thd->main_da.sql_errno() : 0,
                     "Error in %s event: row application failed. %s",
                     get_type_str(),
-                    thd->net.last_error ? thd->net.last_error : "");
+                    thd->is_error() ? thd->main_da.message() : "");
 	thd->query_error= 1;
 	break;
       }
@@ -6201,12 +6208,13 @@ int Rows_log_event::do_apply_event(Relay
 
   if (error)
   {                     /* error has occured during the transaction */
-    rli->report(ERROR_LEVEL, thd->net.last_errno,
+    rli->report(ERROR_LEVEL,
+                thd->is_error() ? thd->main_da.sql_errno() : 0,
                 "Error in %s event: error during transaction execution "
                 "on table %s.%s. %s",
                 get_type_str(), table->s->db.str,
                 table->s->table_name.str,
-                thd->net.last_error ? thd->net.last_error : "");
+                thd->is_error() ? thd->main_da.message() : "");
 
     /*
       If one day we honour --skip-slave-errors in row-based replication, and
@@ -6334,7 +6342,7 @@ Rows_log_event::do_update_pos(Relay_log_
         found" (as this is allowed). This is a safety measure; apparently
         those errors (e.g. when executing a Delete_rows_log_event of a
         non-existing row, like in rpl_row_mystery22.test,
-        thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
+        thd->main_da.message() = "Can't find record in 't1'" and sql_errno=1032)
         do not become visible. We still prefer to wipe them out.
       */
       thd->clear_error();
@@ -6804,10 +6812,10 @@ int Table_map_log_event::do_apply_event(
           Error reporting borrowed from Query_log_event with many excessive
           simplifications (we don't honour --slave-skip-errors)
         */
-        uint actual_error= thd->net.last_errno;
+        uint actual_error= thd->main_da.sql_errno();
         rli->report(ERROR_LEVEL, actual_error,
                     "Error '%s' on opening table `%s`.`%s`",
-                    (actual_error ? thd->net.last_error :
+                    (actual_error ? thd->main_da.message() :
                      "unexpected success or fatal error"),
                     table_list->db, table_list->table_name);
         thd->query_error= 1;
@@ -7338,8 +7346,12 @@ Write_rows_log_event::do_exec_row(const 
   DBUG_ASSERT(m_table != NULL);
   int error= write_row(rli, TRUE /* overwrite */);
   
-  if (error && !thd->net.last_errno)
-    thd->net.last_errno= error;
+
+  if (error && !thd->is_error())
+  {
+    DBUG_ASSERT(0);
+    my_error(ER_UNKNOWN_ERROR, MYF(0));
+  }
       
   return error; 
 }
diff -Nrup a/sql/log_event_old.cc b/sql/log_event_old.cc
--- a/sql/log_event_old.cc	2007-08-30 02:57:55 +04:00
+++ b/sql/log_event_old.cc	2007-10-30 14:54:50 +03:00
@@ -74,10 +74,10 @@ Old_rows_log_event::do_apply_event(Rows_
             Error reporting borrowed from Query_log_event with many excessive
             simplifications (we don't honour --slave-skip-errors)
           */
-          uint actual_error= thd->net.last_errno;
+          uint actual_error= thd->main_da.sql_errno();
           rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' in %s event: when locking tables",
-                      (actual_error ? thd->net.last_error :
+                      (actual_error ? thd->main_da.message() :
                        "unexpected success or fatal error"),
                       ev->get_type_str());
           thd->is_fatal_error= 1;
@@ -118,10 +118,10 @@ Old_rows_log_event::do_apply_event(Rows_
             Error reporting borrowed from Query_log_event with many excessive
             simplifications (we don't honour --slave-skip-errors)
           */
-          uint actual_error= thd->net.last_errno;
+          uint actual_error= thd->main_da.sql_errno();
           rli->report(ERROR_LEVEL, actual_error,
                       "Error '%s' on reopening tables",
-                      (actual_error ? thd->net.last_error :
+                      (actual_error ? thd->main_da.message() :
                        "unexpected success or fatal error"));
           thd->query_error= 1;
         }
@@ -251,10 +251,10 @@ Old_rows_log_event::do_apply_event(Rows_
   break;
 
       default:
-  rli->report(ERROR_LEVEL, thd->net.last_errno,
+  rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
                     "Error in %s event: row application failed. %s",
                     ev->get_type_str(),
-                    thd->net.last_error ? thd->net.last_error : "");
+                    thd->is_error() ? thd->main_da.message() : "");
   thd->query_error= 1;
   break;
       }
@@ -280,12 +280,12 @@ Old_rows_log_event::do_apply_event(Rows_
 
   if (error)
   {                     /* error has occured during the transaction */
-    rli->report(ERROR_LEVEL, thd->net.last_errno,
+    rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
                 "Error in %s event: error during transaction execution "
                 "on table %s.%s. %s",
                 ev->get_type_str(), table->s->db.str,
                 table->s->table_name.str,
-                thd->net.last_error ? thd->net.last_error : "");
+                thd->is_error() ? thd->main_da.message() : "");
 
     /*
       If one day we honour --skip-slave-errors in row-based replication, and
diff -Nrup a/sql/mysql_priv.h b/sql/mysql_priv.h
--- a/sql/mysql_priv.h	2007-10-10 17:56:58 +04:00
+++ b/sql/mysql_priv.h	2007-10-30 14:54:50 +03:00
@@ -912,7 +912,6 @@ bool init_new_connection_handler_thread(
 void reset_mqh(LEX_USER *lu, bool get_them);
 bool check_mqh(THD *thd, uint check_command);
 void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
-int check_for_max_user_connections(THD *thd, USER_CONN *uc);
 void decrease_user_connections(USER_CONN *uc);
 void thd_init_client_charset(THD *thd, uint cs_number);
 bool setup_connection_thread_globals(THD *thd);
diff -Nrup a/sql/mysqld.cc b/sql/mysqld.cc
--- a/sql/mysqld.cc	2007-08-28 11:02:53 +04:00
+++ b/sql/mysqld.cc	2007-10-30 14:54:50 +03:00
@@ -2559,6 +2559,7 @@ int my_message_sql(uint error, const cha
   THD *thd;
   DBUG_ENTER("my_message_sql");
   DBUG_PRINT("error", ("error: %u  message: '%s'", error, str));
+
   /*
     Put here following assertion when situation with EE_* error codes
     will be fixed
@@ -2570,24 +2571,10 @@ int my_message_sql(uint error, const cha
       TODO: There are two exceptions mechanism (THD and sp_rcontext),
       this could be improved by having a common stack of handlers.
     */
-    if (thd->handle_error(error,
+    if (thd->handle_error(error, str,
                           MYSQL_ERROR::WARN_LEVEL_ERROR))
       DBUG_RETURN(0);
 
-    if (thd->spcont &&
-        thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
-    {
-      DBUG_RETURN(0);
-    }
-
-    thd->query_error=  1; // needed to catch query errors during replication
-
-    if (!thd->no_warnings_for_error)
-      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
-    /*
-      thd->lex->current_select == 0 if lex structure is not inited
-      (not query command (COM_QUERY))
-    */
     if (thd->lex->current_select &&
 	thd->lex->current_select->no_error && !thd->is_fatal_error)
     {
@@ -2600,15 +2587,40 @@ int my_message_sql(uint error, const cha
     }
     else
     {
-      NET *net= &thd->net;
-      net->report_error= 1;
-      query_cache_abort(net);
-      if (!net->last_error[0])			// Return only first message
+      if (! thd->main_da.is_error())            // Return only first message
       {
-	strmake(net->last_error, str, sizeof(net->last_error)-1);
-	net->last_errno= error ? error : ER_UNKNOWN_ERROR;
+        thd->main_da.set_error_status(thd,
+                                      error ? error : ER_UNKNOWN_ERROR,
+                                      str);
       }
+      query_cache_abort(&thd->net);
+    }
+
+    thd->query_error=  1; // needed to catch query errors during replication
+
+    /*
+      An error always aborts the current statement, even if there
+      is a handler for it. This is why the error needs to be reported
+      in all cases.
+      If a continue handler is found, the error message will be cleared
+      by the stored procedures code.
+    */
+    if (thd->spcont &&
+        thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
+    {
+      /*
+        Do not push any warnings, a handled error must be completely
+        silenced.
+      */
+      DBUG_RETURN(0);
     }
+
+    if (!thd->no_warnings_for_error)
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
+    /*
+      thd->lex->current_select == 0 if lex structure is not inited
+      (not query command (COM_QUERY))
+    */
   }
   if (!thd || MyFlags & ME_NOREFRESH)
     sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
@@ -4307,7 +4319,8 @@ void create_thread_to_handle_connection(
       thd->killed= THD::KILL_CONNECTION;			// Safety
       (void) pthread_mutex_unlock(&LOCK_thread_count);
       statistic_increment(aborted_connects,&LOCK_status);
-      net_printf_error(thd, ER_CANT_CREATE_THREAD, error);
+      my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
+      net_end_statement(thd);
       (void) pthread_mutex_lock(&LOCK_thread_count);
       close_connection(thd,0,0);
       delete thd;
diff -Nrup a/sql/net_serv.cc b/sql/net_serv.cc
--- a/sql/net_serv.cc	2007-10-15 15:49:05 +04:00
+++ b/sql/net_serv.cc	2007-10-30 14:54:51 +03:00
@@ -123,20 +123,17 @@ my_bool my_net_init(NET *net, Vio* vio)
 				     MYF(MY_WME))))
     DBUG_RETURN(1);
   net->buff_end=net->buff+net->max_packet;
-  net->no_send_ok= net->no_send_error= 0;
   net->error=0; net->return_errno=0; net->return_status=0;
   net->pkt_nr=net->compress_pkt_nr=0;
   net->write_pos=net->read_pos = net->buff;
-  net->last_error[0]=0;
   net->compress=0; net->reading_or_writing=0;
   net->where_b = net->remain_in_buf=0;
-  net->last_errno=0;
+  net->client_last_errno=0;
 #ifdef USE_QUERY_CACHE
   query_cache_init_query(net);
 #else
   net->query_cache_query= 0;
 #endif
-  net->report_error= 0;
 
   if (vio != 0)					/* If real connection */
   {
@@ -177,8 +174,10 @@ my_bool net_realloc(NET *net, size_t len
     DBUG_PRINT("error", ("Packet too large. Max size: %lu",
                          net->max_packet_size));
     net->error= 1;
-    net->report_error= 1;
-    net->last_errno= ER_NET_PACKET_TOO_LARGE;
+    net->client_last_errno= ER_NET_PACKET_TOO_LARGE;
+#ifdef MYSQL_SERVER
+    my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
+#endif
     DBUG_RETURN(1);
   }
   pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); 
@@ -191,8 +190,6 @@ my_bool net_realloc(NET *net, size_t len
                                   MYF(MY_WME))))
   {
     net->error= 1;
-    net->report_error= 1;
-    net->last_errno= ER_OUT_OF_RESOURCES;
     DBUG_RETURN(1);
   }
   net->buff=net->write_pos=buff;
@@ -583,10 +580,7 @@ net_real_write(NET *net,const uchar *pac
                                 COMP_HEADER_SIZE, MYF(MY_WME))))
     {
 #ifdef MYSQL_SERVER
-      net->last_errno= ER_OUT_OF_RESOURCES;
       net->error= 2;
-      /* TODO is it needed to set this variable if we have no socket */
-      net->report_error= 1;
 #endif
       net->reading_or_writing= 0;
       DBUG_RETURN(1);
@@ -638,11 +632,10 @@ net_real_write(NET *net,const uchar *pac
 		    "%s: my_net_write: fcntl returned error %d, aborting thread\n",
 		    my_progname,vio_errno(net->vio));
 #endif /* EXTRA_DEBUG */
-#ifdef MYSQL_SERVER	    
-	    net->last_errno= ER_NET_ERROR_ON_WRITE;
+#ifdef MYSQL_SERVER
+            my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
 #endif
 	    net->error= 2;                     /* Close socket */
-            net->report_error= 1;
 	    goto end;
 	  }
 	  retry_count=0;
@@ -669,10 +662,9 @@ net_real_write(NET *net,const uchar *pac
       }
 #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
       net->error= 2;				/* Close socket */
-      net->report_error= 1;
 #ifdef MYSQL_SERVER
-      net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
-			ER_NET_ERROR_ON_WRITE);
+      my_error(interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE,
+               MYF(0));
 #endif /* MYSQL_SERVER */
       break;
     }
@@ -849,9 +841,8 @@ my_real_read(NET *net, size_t *complen)
 #endif /* EXTRA_DEBUG */
 		len= packet_error;
 		net->error= 2;                 /* Close socket */
-	        net->report_error= 1;
 #ifdef MYSQL_SERVER
-		net->last_errno= ER_NET_FCNTL_ERROR;
+		my_error(ER_NET_FCNTL_ERROR, MYF(0));
 #endif
 		goto end;
 	      }
@@ -881,10 +872,10 @@ my_real_read(NET *net, size_t *complen)
 			      remain, vio_errno(net->vio), (long) length));
 	  len= packet_error;
 	  net->error= 2;				/* Close socket */
-	  net->report_error= 1;
 #ifdef MYSQL_SERVER
-	  net->last_errno= (vio_was_interrupted(net->vio) ? ER_NET_READ_INTERRUPTED :
-			    ER_NET_READ_ERROR);
+          my_error(vio_was_interrupted(net->vio) ?
+                   ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR,
+                   MYF(0));
 #endif
 	  goto end;
 	}
@@ -915,9 +906,8 @@ my_real_read(NET *net, size_t *complen)
 #endif
 	  }
 	  len= packet_error;
-	  net->report_error= 1;
 #ifdef MYSQL_SERVER
-	  net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER;
+	  my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
 #endif
 	  goto end;
 	}
@@ -1101,9 +1091,8 @@ my_net_read(NET *net)
 			&complen))
       {
 	net->error= 2;			/* caller will close socket */
-	net->report_error= 1;
 #ifdef MYSQL_SERVER
-	net->last_errno=ER_NET_UNCOMPRESS_ERROR;
+	my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
 #endif
 	return packet_error;
       }
diff -Nrup a/sql/opt_range.cc b/sql/opt_range.cc
--- a/sql/opt_range.cc	2007-09-21 14:17:00 +04:00
+++ b/sql/opt_range.cc	2007-10-30 14:54:51 +03:00
@@ -1271,7 +1271,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_
       the storage engine calls in question happen to never fail with the 
       existing storage engines. 
     */
-    thd->net.report_error= 1; /* purecov: inspected */
+    my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
     /* Caller will free the memory */
     goto failure;  /* purecov: inspected */
   }
diff -Nrup a/sql/opt_sum.cc b/sql/opt_sum.cc
--- a/sql/opt_sum.cc	2007-08-13 17:11:12 +04:00
+++ b/sql/opt_sum.cc	2007-10-30 14:54:51 +03:00
@@ -167,8 +167,9 @@ int opt_sum_query(TABLE_LIST *tables, Li
     else
     {
       error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
-      if(error)
+      if (error)
       {
+        tl->table->in_use->fatal_error();
         tl->table->file->print_error(error, MYF(0));
         return error;
       }
@@ -329,6 +330,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
 	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
 	      return HA_ERR_KEY_NOT_FOUND;	      // No rows matching WHERE
 	    /* HA_ERR_LOCK_DEADLOCK or some other error */
+            table->in_use->fatal_error();
  	    table->file->print_error(error, MYF(0));
             return(error);
 	  }
@@ -416,6 +418,7 @@ int opt_sum_query(TABLE_LIST *tables, Li
 	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
 	      return HA_ERR_KEY_NOT_FOUND;	     // No rows matching WHERE
 	    /* HA_ERR_LOCK_DEADLOCK or some other error */
+            table->in_use->fatal_error();
  	    table->file->print_error(error, MYF(0));
             return(error);
 	  }
diff -Nrup a/sql/protocol.cc b/sql/protocol.cc
--- a/sql/protocol.cc	2007-10-15 15:45:16 +04:00
+++ b/sql/protocol.cc	2007-10-30 14:54:51 +03:00
@@ -29,7 +29,8 @@
 static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
 void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
 #ifndef EMBEDDED_LIBRARY
-static void write_eof_packet(THD *thd, NET *net);
+static void write_eof_packet(THD *thd, NET *net,
+                             uint server_status, uint total_warn_count);
 #endif
 
 #ifndef EMBEDDED_LIBRARY
@@ -65,179 +66,28 @@ bool Protocol_binary::net_store_data(con
    critical that every error that can be intercepted is issued in one
    place only, my_message_sql.
 */
+
 void net_send_error(THD *thd, uint sql_errno, const char *err)
 {
   NET *net= &thd->net;
-  bool generate_warning= thd->killed != THD::KILL_CONNECTION;
   DBUG_ENTER("net_send_error");
-  DBUG_PRINT("enter",("sql_errno: %d  err: %s", sql_errno,
-		      err ? err : net->last_error[0] ?
-		      net->last_error : "NULL"));
 
   DBUG_ASSERT(!thd->spcont);
+  DBUG_ASSERT(sql_errno);
+  DBUG_ASSERT(err && err[0]);
 
-  if (net && net->no_send_error)
-  {
-    thd->clear_error();
-    thd->is_fatal_error= 0;			// Error message is given
-    DBUG_PRINT("info", ("sending error messages prohibited"));
-    DBUG_VOID_RETURN;
-  }
+  DBUG_PRINT("enter",("sql_errno: %d  err: %s", sql_errno, err));
 
-  thd->query_error=  1; // needed to catch query errors during replication
-  if (!err)
-  {
-    if (sql_errno)
-      err=ER(sql_errno);
-    else
-    {
-      if ((err=net->last_error)[0])
-      {
-	sql_errno=net->last_errno;
-        generate_warning= 0;            // This warning has already been given
-      }
-      else
-      {
-	sql_errno=ER_UNKNOWN_ERROR;
-	err=ER(sql_errno);	 /* purecov: inspected */
-      }
-    }
-  }
-
-  if (generate_warning)
-  {
-    /* Error that we have not got with my_error() */
-    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err);
-  }
+  thd->main_da.can_overwrite_status= TRUE;
 
   net_send_error_packet(thd, sql_errno, err);
 
-  thd->is_fatal_error= 0;			// Error message is given
-  thd->net.report_error= 0;
-
+  thd->main_da.can_overwrite_status= FALSE;
   /* Abort multi-result sets */
   thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
   DBUG_VOID_RETURN;
 }
 
-/*
-   Write error package and flush to client
-   It's a little too low level, but I don't want to use another buffer for
-   this
-
-   Design note:
-
-   net_printf_error and net_send_error are low-level functions
-   that shall be used only when a new connection is being
-   established or at server startup.
-   For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
-   critical that every error that can be intercepted is issued in one
-   place only, my_message_sql.
-*/
-
-void
-net_printf_error(THD *thd, uint errcode, ...)
-{
-  va_list args;
-  uint length,offset;
-  const char *format;
-#ifndef EMBEDDED_LIBRARY
-  const char *text_pos;
-  int head_length= NET_HEADER_SIZE;
-#else
-  char text_pos[1024];
-#endif
-  NET *net= &thd->net;
-
-  DBUG_ENTER("net_printf_error");
-  DBUG_PRINT("enter",("message: %u",errcode));
-
-  DBUG_ASSERT(!thd->spcont);
-
-  if (net && net->no_send_error)
-  {
-    thd->clear_error();
-    thd->is_fatal_error= 0;			// Error message is given
-    DBUG_PRINT("info", ("sending error messages prohibited"));
-    DBUG_VOID_RETURN;
-  }
-
-  thd->query_error=  1; // needed to catch query errors during replication
-#ifndef EMBEDDED_LIBRARY
-  query_cache_abort(net);	// Safety
-#endif
-  va_start(args,errcode);
-  /*
-    The following is needed to make net_printf_error() work with 0 argument
-    for errorcode and use the argument after that as the format string. This
-    is useful for rare errors that are not worth the hassle to put in
-    errmsg.sys, but at the same time, the message is not fixed text
-  */
-  if (errcode)
-    format= ER(errcode);
-  else
-  {
-    format=va_arg(args,char*);
-    errcode= ER_UNKNOWN_ERROR;
-  }
-  offset= (net->return_errno ?
-	   ((thd->client_capabilities & CLIENT_PROTOCOL_41) ?
-	    2+SQLSTATE_LENGTH+1 : 2) : 0);
-#ifndef EMBEDDED_LIBRARY
-  text_pos=(char*) net->buff + head_length + offset + 1;
-  length= (uint) ((char*)net->buff_end - text_pos);
-#else
-  length=sizeof(text_pos)-1;
-#endif
-  length=my_vsnprintf(my_const_cast(char*) (text_pos),
-                      min(length, sizeof(net->last_error)),
-                      format,args);
-  va_end(args);
-
-  /* Replication slave relies on net->last_* to see if there was error */
-  net->last_errno= errcode;
-  strmake(net->last_error, text_pos, sizeof(net->last_error)-1);
-
-#ifndef EMBEDDED_LIBRARY
-  if (net->vio == 0)
-  {
-    if (thd->bootstrap)
-    {
-      /*
-	In bootstrap it's ok to print on stderr
-	This may also happen when we get an error from a slave thread
-      */
-      fprintf(stderr,"ERROR: %d  %s\n",errcode,text_pos);
-      thd->fatal_error();
-    }
-    DBUG_VOID_RETURN;
-  }
-
-  int3store(net->buff,length+1+offset);
-  net->buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
-  net->buff[head_length]=(uchar) 255;		// Error package
-  if (offset)
-  {
-    uchar *pos= net->buff+head_length+1;
-    int2store(pos, errcode);
-    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
-    {
-      pos[2]= '#';      /* To make the protocol backward compatible */
-      memcpy(pos+3, mysql_errno_to_sqlstate(errcode), SQLSTATE_LENGTH);
-    }
-  }
-  VOID(net_real_write(net, net->buff, length+head_length+1+offset));
-#else
-  net->last_errno= errcode;
-  strmake(net->last_error, text_pos, length);
-  strmake(net->sqlstate, mysql_errno_to_sqlstate(errcode), SQLSTATE_LENGTH);
-#endif
-  if (thd->killed != THD::KILL_CONNECTION)
-    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, errcode,
-                 text_pos ? text_pos : ER(errcode));
-  thd->is_fatal_error=0;			// Error message is given
-  DBUG_VOID_RETURN;
-}
 
 /*
   Return ok to the client.
@@ -261,23 +111,21 @@ net_printf_error(THD *thd, uint errcode,
     warning_count	Stored in 2 bytes; New in 4.1 protocol
     message		Stored as packed length (1-9 bytes) + message
 			Is not stored if no message
-
-   If net->no_send_ok return without sending packet
 */    
 
 #ifndef EMBEDDED_LIBRARY
 void
-send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
+net_send_ok(THD *thd,
+            uint server_status, uint total_warn_count,
+            ha_rows affected_rows, ulonglong id, const char *message)
 {
   NET *net= &thd->net;
   uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
-  DBUG_ENTER("send_ok");
+  DBUG_ENTER("net_send_ok");
 
-  if (net->no_send_ok || !net->vio)	// hack for re-parsing queries
+  if (!net->vio)
   {
-    DBUG_PRINT("info", ("no send ok: %s, vio present: %s",
-                        (net->no_send_ok ? "YES" : "NO"),
-                        (net->vio ? "YES" : "NO")));
+    DBUG_PRINT("info", ("vio present: NO"));
     DBUG_VOID_RETURN;
   }
 
@@ -288,31 +136,31 @@ send_ok(THD *thd, ha_rows affected_rows,
   {
     DBUG_PRINT("info",
 	       ("affected_rows: %lu  id: %lu  status: %u  warning_count: %u",
-		(ulong) affected_rows,		
+		(ulong) affected_rows,
 		(ulong) id,
-		(uint) (thd->server_status & 0xffff),
-		(uint) thd->total_warn_count));
-    int2store(pos,thd->server_status);
+		(uint) (server_status & 0xffff),
+		(uint) total_warn_count));
+    int2store(pos,server_status);
     pos+=2;
 
     /* We can only return up to 65535 warnings in two bytes */
-    uint tmp= min(thd->total_warn_count, 65535);
+    uint tmp= min(total_warn_count, 65535);
     int2store(pos, tmp);
     pos+= 2;
   }
   else if (net->return_status)			// For 4.0 protocol
   {
-    int2store(pos,thd->server_status);
+    int2store(pos, server_status);
     pos+=2;
   }
-  if (message)
+  thd->main_da.can_overwrite_status= TRUE;
+
+  if (message && message[0])
     pos= net_store_data(pos, (uchar*) message, strlen(message));
   VOID(my_net_write(net, buff, (size_t) (pos-buff)));
   VOID(net_flush(net));
-  /* We can't anymore send an error to the client */
-  thd->net.report_error= 0;
-  thd->net.no_send_error= 1;
-  DBUG_PRINT("info", ("OK sent, so no more error sending allowed"));
+
+  thd->main_da.can_overwrite_status= FALSE;
 
   DBUG_VOID_RETURN;
 }
@@ -323,7 +171,7 @@ static uchar eof_buff[1]= { (uchar) 254 
   Send eof (= end of result set) to the client
 
   SYNOPSIS
-    send_eof()
+    net_send_eof()
     thd			Thread handler
     no_flush		Set to 1 if there will be more data to the client,
 			like in send_fields().
@@ -342,15 +190,17 @@ static uchar eof_buff[1]= { (uchar) 254 
 */    
 
 void
-send_eof(THD *thd)
+net_send_eof(THD *thd, uint server_status, uint total_warn_count)
 {
   NET *net= &thd->net;
-  DBUG_ENTER("send_eof");
+  DBUG_ENTER("net_send_eof");
+  /* Set to TRUE if no active vio, to work well in case of --init-file */
   if (net->vio != 0)
   {
-    write_eof_packet(thd, net);
+    thd->main_da.can_overwrite_status= TRUE;
+    write_eof_packet(thd, net, server_status, total_warn_count);
     VOID(net_flush(net));
-    thd->net.no_send_error= 1;
+    thd->main_da.can_overwrite_status= FALSE;
     DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
   }
   DBUG_VOID_RETURN;
@@ -362,7 +212,9 @@ send_eof(THD *thd)
   write it to the network output buffer.
 */
 
-static void write_eof_packet(THD *thd, NET *net)
+static void write_eof_packet(THD *thd, NET *net,
+                             uint server_status,
+                             uint total_warn_count)
 {
   if (thd->client_capabilities & CLIENT_PROTOCOL_41)
   {
@@ -371,7 +223,7 @@ static void write_eof_packet(THD *thd, N
       Don't send warn count during SP execution, as the warn_list
       is cleared between substatements, and mysqltest gets confused
     */
-    uint tmp= (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
+    uint tmp= (thd->spcont ? 0 : min(total_warn_count, 65535));
     buff[0]= 254;
     int2store(buff+1, tmp);
     /*
@@ -380,8 +232,8 @@ static void write_eof_packet(THD *thd, N
       other queries (see the if test in dispatch_command / COM_QUERY)
     */
     if (thd->is_fatal_error)
-      thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
-    int2store(buff+3, thd->server_status);
+      server_status&= ~SERVER_MORE_RESULTS_EXISTS;
+    int2store(buff+3, server_status);
     VOID(my_net_write(net, buff, 5));
   }
   else
@@ -473,6 +325,38 @@ static uchar *net_store_length_fast(ucha
 }
 
 
+void net_end_statement(THD *thd)
+{
+  DBUG_ASSERT(! thd->main_da.is_sent);
+  switch (thd->main_da.status()) {
+  case Diagnostics_area::DA_ERROR:
+    /* The query failed, send error to log and abort bootstrap */
+    net_send_error(thd, thd->main_da.sql_errno(),
+                   thd->main_da.message());
+    break;
+  case Diagnostics_area::DA_EOF:
+    net_send_eof(thd, thd->main_da.server_status(),
+                 thd->main_da.total_warn_count());
+    break;
+  case Diagnostics_area::DA_OK:
+    net_send_ok(thd, thd->main_da.server_status(),
+                thd->main_da.total_warn_count(),
+                thd->main_da.affected_rows(), thd->main_da.last_insert_id(),
+                thd->main_da.message());
+    break;
+  case Diagnostics_area::DA_DISABLED:
+    break;
+  case Diagnostics_area::DA_EMPTY:
+  default:
+    DBUG_ASSERT(0);
+    net_send_ok(thd, thd->server_status, thd->total_warn_count,
+                0, 0, NULL);
+    break;
+  }
+  thd->main_da.is_sent= TRUE;
+}
+
+
 /****************************************************************************
   Functions used by the protocol functions (like send_ok) to store strings
   and numbers in the header result packet.
@@ -521,6 +405,11 @@ void Protocol::init(THD *thd_arg)
 }
 
 
+void Protocol::end_partial_result_set(THD *thd)
+{
+  net_send_eof(thd, thd->server_status, thd->total_warn_count);
+}
+
 bool Protocol::flush()
 {
 #ifndef EMBEDDED_LIBRARY
@@ -685,7 +574,9 @@ bool Protocol::send_fields(List<Item> *l
   }
 
   if (flags & SEND_EOF)
-    write_eof_packet(thd, &thd->net);
+    write_eof_packet(thd, &thd->net,
+                     thd->server_status,
+                     thd->total_warn_count);
   DBUG_RETURN(prepare_for_send(list));
 
 err:
diff -Nrup a/sql/protocol.h b/sql/protocol.h
--- a/sql/protocol.h	2007-05-24 02:39:21 +04:00
+++ b/sql/protocol.h	2007-10-30 14:54:51 +03:00
@@ -75,6 +75,7 @@ public:
     return 0;
   }
   virtual bool flush();
+  virtual void end_partial_result_set(THD *thd);
   virtual void prepare_for_resend()=0;
 
   virtual bool store_null()=0;
@@ -172,11 +173,19 @@ public:
 };
 
 void send_warning(THD *thd, uint sql_errno, const char *err=0);
-void net_printf_error(THD *thd, uint sql_errno, ...);
-void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
-void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
-	     const char *info=0);
-void send_eof(THD *thd);
+
+void net_send_error(THD *thd, uint sql_errno, const char *err);
+void net_send_ok(THD *thd, uint server_status,
+                 uint total_warn_count,
+                 ha_rows affected_rows,
+                 ulonglong id,
+                 const char *info);
+void net_send_eof(THD *thd,
+                  uint server_status,
+                  uint total_warn_count);
+
+void net_end_statement(THD *thd);
+
 bool send_old_password_request(THD *thd);
 uchar *net_store_data(uchar *to,const uchar *from, size_t length);
 uchar *net_store_data(uchar *to,int32 from);
diff -Nrup a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
--- a/sql/repl_failsafe.cc	2007-08-16 10:52:43 +04:00
+++ b/sql/repl_failsafe.cc	2007-10-30 14:54:51 +03:00
@@ -461,7 +461,7 @@ bool show_new_master(THD* thd)
     protocol->store((ulonglong) lex_mi->pos);
     if (protocol->write())
       DBUG_RETURN(TRUE);
-    send_eof(thd);
+    my_eof(thd);
     DBUG_RETURN(FALSE);
   }
 }
@@ -674,7 +674,7 @@ bool show_slave_hosts(THD* thd)
     }
   }
   pthread_mutex_unlock(&LOCK_slave_list);
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -685,7 +685,7 @@ int connect_to_master(THD *thd, MYSQL* m
 
   if (!mi->host || !*mi->host)			/* empty host */
   {
-    strmov(mysql->net.last_error, "Master is not configured");
+    strmov(mysql->net.client_last_error, "Master is not configured");
     DBUG_RETURN(1);
   }
   mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
@@ -880,6 +880,8 @@ bool load_master_data(THD* thd)
 	cleanup_mysql_results(db_res, cur_table_res - 1, table_res);
 	goto err;
       }
+      /* Clear the result of mysql_create_db */
+      thd->main_da.reset_diagnostics_area();
 
       if (mysql_select_db(&mysql, db) ||
 	  mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) ||
@@ -990,7 +992,7 @@ err:
 
   mysql_close(&mysql); // safe to call since we always do mysql_init()
   if (!error)
-    send_ok(thd);
+    my_ok(thd);
 
   return error;
 }
diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
--- a/sql/rpl_record.cc	2007-09-14 21:29:17 +04:00
+++ b/sql/rpl_record.cc	2007-10-30 14:54:51 +03:00
@@ -345,12 +345,13 @@ int prepare_record(const Slave_reporting
     if (check && ((f->flags & mask) == mask))
     {
       DBUG_ASSERT(log);
-      log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
+      error= ER_NO_DEFAULT_FOR_FIELD;
+      log->report(ERROR_LEVEL, error,
                   "Field `%s` of table `%s`.`%s` "
                   "has no default value and cannot be NULL",
                   f->field_name, table->s->db.str,
                   table->s->table_name.str);
-      error = ER_NO_DEFAULT_FOR_FIELD;
+      my_error(error, MYF(0), f->field_name);
     }
     else
       f->set_default();
diff -Nrup a/sql/rpl_rli.cc b/sql/rpl_rli.cc
--- a/sql/rpl_rli.cc	2007-08-16 09:37:41 +04:00
+++ b/sql/rpl_rli.cc	2007-10-30 14:54:51 +03:00
@@ -166,7 +166,7 @@ int init_relay_log_info(Relay_log_info* 
     {
       sql_print_error("Failed to create a new relay log info file (\
 file '%s', errno %d)", fname, my_errno);
-      msg= current_thd->net.last_error;
+      msg= current_thd->main_da.message();
       goto err;
     }
     if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
@@ -174,7 +174,7 @@ file '%s', errno %d)", fname, my_errno);
     {
       sql_print_error("Failed to create a cache on relay log info file '%s'",
                       fname);
-      msg= current_thd->net.last_error;
+      msg= current_thd->main_da.message();
       goto err;
     }
 
diff -Nrup a/sql/set_var.cc b/sql/set_var.cc
--- a/sql/set_var.cc	2007-10-15 23:53:37 +04:00
+++ b/sql/set_var.cc	2007-10-30 14:54:51 +03:00
@@ -3036,7 +3036,7 @@ int sql_set_variables(THD *thd, List<set
     if ((error= var->check(thd)))
       goto err;
   }
-  if (!(error= test(thd->net.report_error)))
+  if (!(error= test(thd->is_error())))
   {
     it.rewind();
     while ((var= it++))
diff -Nrup a/sql/slave.cc b/sql/slave.cc
--- a/sql/slave.cc	2007-08-30 01:28:34 +04:00
+++ b/sql/slave.cc	2007-10-30 14:54:51 +03:00
@@ -981,17 +981,24 @@ static int create_table_from_dump(THD* t
   }
   thd->query= query;
   thd->query_error = 0;
-  thd->net.no_send_ok = 1;
 
   bzero((char*) &tables,sizeof(tables));
   tables.db = (char*)db;
   tables.alias= tables.table_name= (char*)table_name;
 
   /* Drop the table if 'overwrite' is true */
-  if (overwrite && mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
+  if (overwrite)
   {
-    sql_print_error("create_table_from_dump: failed to drop the table");
-    goto err;
+    if (mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
+    {
+      sql_print_error("create_table_from_dump: failed to drop the table");
+      goto err;
+    }
+    else
+    {
+      /* clear the result of mysql_rm_table */
+      thd->main_da.reset_diagnostics_area();
+    }
   }
 
   /* Create the table. We do not want to log the "create table" statement */
@@ -1004,6 +1011,7 @@ static int create_table_from_dump(THD* t
   thd->db = (char*)db;
   DBUG_ASSERT(thd->db != 0);
   thd->db_length= strlen(thd->db);
+  mysql_reset_thd_for_next_command(thd);
   mysql_parse(thd, thd->query, packet_len, &found_semicolon); // run create table
   thd->db = save_db;            // leave things the way the were before
   thd->db_length= save_db_length;
@@ -1012,6 +1020,7 @@ static int create_table_from_dump(THD* t
   if (thd->query_error)
     goto err;                   // mysql_parse took care of the error send
 
+  thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */
   thd->proc_info = "Opening master dump table";
   tables.lock_type = TL_WRITE;
   if (!open_ltable(thd, &tables, TL_WRITE, 0))
@@ -1049,7 +1058,6 @@ static int create_table_from_dump(THD* t
 
 err:
   close_thread_tables(thd);
-  thd->net.no_send_ok = 0;
   DBUG_RETURN(error);
 }
 
@@ -1101,7 +1109,6 @@ int fetch_master_table(THD *thd, const c
   error = 0;
 
  err:
-  thd->net.no_send_ok = 0; // Clear up garbage after create_table_from_dump
   if (!called_connected)
     mysql_close(mysql);
   if (errmsg && thd->vio_ok())
@@ -1429,7 +1436,7 @@ bool show_master_info(THD* thd, Master_i
     if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(),
packet->length()))
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -1717,12 +1724,20 @@ static int has_temporary_error(THD *thd)
     DBUG_RETURN(0);
 
   /*
+    If there is no message in THD, we can't say if it's a temporary
+    error or not. This is currently the case for Incident_log_event,
+    which sets no message. Return FALSE.
+  */
+  if (!thd->is_error())
+    DBUG_RETURN(0);
+
+  /*
     Temporary error codes:
     currently, InnoDB deadlock detected by InnoDB or lock
     wait timeout (innodb_lock_wait_timeout exceeded
   */
-  if (thd->net.last_errno == ER_LOCK_DEADLOCK ||
-      thd->net.last_errno == ER_LOCK_WAIT_TIMEOUT)
+  if (thd->main_da.sql_errno() == ER_LOCK_DEADLOCK ||
+      thd->main_da.sql_errno() == ER_LOCK_WAIT_TIMEOUT)
     DBUG_RETURN(1);
 
 #ifdef HAVE_NDB_BINLOG
@@ -2529,20 +2544,21 @@ Slave SQL thread aborted. Can't execute 
         */
         uint32 const last_errno= rli->last_error().number;
 
-        DBUG_PRINT("info", ("thd->net.last_errno=%d; rli->last_error.number=%d",
-                            thd->net.last_errno, last_errno));
-        if (thd->net.last_errno != 0)
+        if (thd->is_error())
         {
           char const *const errmsg=
-            thd->net.last_error ? thd->net.last_error : "<no message>";
+            thd->main_da.message() ? thd->main_da.message() : "<no message>";
+
+          DBUG_PRINT("info", ("thd->main_da.sql_errno()=%d;
rli->last_error.number=%d",
+                              thd->main_da.sql_errno(), last_errno));
           if (last_errno == 0)
           {
-            rli->report(ERROR_LEVEL, thd->net.last_errno, errmsg);
+            rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), errmsg);
           }
-          else if (last_errno != thd->net.last_errno)
+          else if (last_errno != thd->main_da.sql_errno())
           {
             sql_print_error("Slave (additional info): %s Error_code: %d",
-                            errmsg, thd->net.last_errno);
+                            errmsg, thd->main_da.sql_errno());
           }
         }
 
diff -Nrup a/sql/sp.cc b/sql/sp.cc
--- a/sql/sp.cc	2007-09-01 00:11:58 +04:00
+++ b/sql/sp.cc	2007-10-30 14:54:54 +03:00
@@ -1165,7 +1165,7 @@ sp_show_status_routine(THD *thd, int typ
   }
 
 err_case1:
-  send_eof(thd);
+  my_eof(thd);
 err_case:
   table->file->ha_index_end();
   close_thread_tables(thd);
@@ -1820,7 +1820,7 @@ sp_cache_routines_and_add_tables_aux(THD
           an error with it's return value without calling my_error(), we
           set the generic "mysql.proc table corrupt" error here.
          */
-        if (!thd->net.report_error)
+        if (!thd->is_error())
         {
           /*
             SP allows full NAME_LEN chars thus he have to allocate enough
diff -Nrup a/sql/sp_head.cc b/sql/sp_head.cc
--- a/sql/sp_head.cc	2007-09-28 15:42:35 +04:00
+++ b/sql/sp_head.cc	2007-10-30 14:54:54 +03:00
@@ -370,7 +370,7 @@ sp_eval_expr(THD *thd, Field *result_fie
   thd->abort_on_warning= save_abort_on_warning;
   thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
 
-  if (thd->net.report_error)
+  if (thd->is_error())
   {
     /* Return error status if something went wrong. */
     err_status= TRUE;
@@ -1166,12 +1166,6 @@ sp_head::execute(THD *thd)
     
     err_status= i->execute(thd, &ip);
 
-    /*
-      If this SP instruction have sent eof, it has caused no_send_error to be
-      set. Clear it back to allow the next instruction to send error. (multi-
-      statement execution code clears no_send_error between statements too)
-    */
-    thd->net.no_send_error= 0;
     if (i->free_list)
       cleanup_items(i->free_list);
     
@@ -1251,7 +1245,7 @@ sp_head::execute(THD *thd)
  done:
   DBUG_PRINT("info", ("err_status: %d  killed: %d  query_error: %d  report_error: %d",
 		      err_status, thd->killed, thd->query_error,
-                      thd->net.report_error));
+                      thd->is_error()));
 
   if (thd->killed)
     err_status= TRUE;
@@ -2326,7 +2320,7 @@ sp_head::show_create_routine(THD *thd, i
   err_status= protocol->write();
 
   if (!err_status)
-    send_eof(thd);
+    my_eof(thd);
 
   DBUG_RETURN(err_status);
 }
@@ -2519,7 +2513,7 @@ sp_head::show_routine_code(THD *thd)
   }
 
   if (!res)
-    send_eof(thd);
+    my_eof(thd);
 
   DBUG_RETURN(res);
 }
@@ -2647,7 +2641,7 @@ sp_lex_keeper::reset_lex_and_exec_core(T
 
     cleanup_items() is called in sp_head::execute()
   */
-  DBUG_RETURN(res || thd->net.report_error);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 
@@ -2713,14 +2707,22 @@ sp_instr_stmt::execute(THD *thd, uint *n
 					  thd->query, thd->query_length) <= 0)
     {
       res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
+
+      if (thd->main_da.is_eof())
+        net_end_statement(thd);
+
+      query_cache_end_of_result(thd);
+
       if (!res && unlikely(thd->enable_slow_log))
         log_slow_statement(thd);
-      query_cache_end_of_result(thd);
     }
     else
       *nextp= m_ip+1;
     thd->query= query;
     thd->query_length= query_length;
+
+    if (!thd->is_error())
+      thd->main_da.reset_diagnostics_area();
   }
   DBUG_RETURN(res);
 }
diff -Nrup a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
--- a/sql/sp_rcontext.cc	2007-08-05 09:11:23 +04:00
+++ b/sql/sp_rcontext.cc	2007-10-30 14:54:54 +03:00
@@ -169,7 +169,7 @@ sp_rcontext::set_return_value(THD *thd, 
 /*
   Find a handler for the given errno.
   This is called from all error message functions (e.g. push_warning,
-  net_send_error, et al) when a sp_rcontext is in effect. If a handler
+  my_error, et al) when a sp_rcontext is in effect. If a handler
   is found, no error is sent, and the the SP execution loop will instead
   invoke the found handler.
   This might be called several times before we get back to the execution
@@ -278,7 +278,7 @@ sp_rcontext::find_handler(THD *thd, uint
    this function will return true.
    If a handler is found and if the severity of the error indicate
    that the current instruction executed should abort,
-   the flag thd->net.report_error is also set.
+   the flag thd->is_error() is also set.
    This will cause the execution of the current instruction in a
    sp_instr* to fail, and give control to the handler code itself
    in the sp_head::execute() loop.
@@ -287,7 +287,7 @@ sp_rcontext::find_handler(THD *thd, uint
     sql_errno     The error code
     level         Warning level
     thd           The current thread
-                  - thd->net.report_error is an optional output.
+                  - thd->is_error() is an optional output.
 
   RETURN
     TRUE       if a handler was found.
@@ -298,7 +298,6 @@ sp_rcontext::handle_error(uint sql_errno
                           MYSQL_ERROR::enum_warning_level level,
                           THD *thd)
 {
-  bool handled= FALSE;
   MYSQL_ERROR::enum_warning_level elevated_level= level;
 
 
@@ -310,25 +309,7 @@ sp_rcontext::handle_error(uint sql_errno
     elevated_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
   }
 
-  if (find_handler(thd, sql_errno, elevated_level))
-  {
-    if (elevated_level == MYSQL_ERROR::WARN_LEVEL_ERROR)
-    {
-      /*
-         Forces to abort the current instruction execution.
-         NOTE: This code is altering the original meaning of
-         the net.report_error flag (send an error to the client).
-         In the context of stored procedures with error handlers,
-         the flag is reused to cause error propagation,
-         until the error handler is reached.
-         No messages will be sent to the client in that context.
-      */
-      thd->net.report_error= 1;
-    }
-    handled= TRUE;
-  }
-
-  return handled;
+  return find_handler(thd, sql_errno, elevated_level);
 }
 
 void
diff -Nrup a/sql/sql_acl.cc b/sql/sql_acl.cc
--- a/sql/sql_acl.cc	2007-08-13 17:11:13 +04:00
+++ b/sql/sql_acl.cc	2007-10-30 14:54:54 +03:00
@@ -694,7 +694,7 @@ my_bool acl_reload(THD *thd)
   if (simple_open_n_lock_tables(thd, tables))
   {
     sql_print_error("Fatal error: Can't open and lock privilege tables: %s",
-		    thd->net.last_error);
+		    thd->main_da.message());
     goto end;
   }
 
@@ -3169,7 +3169,7 @@ bool mysql_table_grant(THD *thd, TABLE_L
   rw_unlock(&LOCK_grant);
 
   if (!result) /* success */
-    send_ok(thd);
+    my_ok(thd);
 
   /* Tables are automatically closed */
   DBUG_RETURN(result);
@@ -3336,7 +3336,7 @@ bool mysql_routine_grant(THD *thd, TABLE
   rw_unlock(&LOCK_grant);
 
   if (!result && !no_error)
-    send_ok(thd);
+    my_ok(thd);
 
   /* Tables are automatically closed */
   DBUG_RETURN(result);
@@ -3452,7 +3452,7 @@ bool mysql_grant(THD *thd, const char *d
   close_thread_tables(thd);
 
   if (!result)
-    send_ok(thd);
+    my_ok(thd);
 
   DBUG_RETURN(result);
 }
@@ -4671,7 +4671,7 @@ end:
   VOID(pthread_mutex_unlock(&acl_cache->lock));
   rw_unlock(&LOCK_grant);
 
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(error);
 }
 
@@ -5546,9 +5546,6 @@ bool mysql_drop_user(THD *thd, List <LEX
 
   if (result)
     my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
-
-  DBUG_PRINT("info", ("thd->net.last_errno: %d", thd->net.last_errno));
-  DBUG_PRINT("info", ("thd->net.last_error: %s", thd->net.last_error));
 
   write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc	2007-10-11 04:16:46 +04:00
+++ b/sql/sql_base.cc	2007-10-30 14:54:54 +03:00
@@ -44,7 +44,7 @@ public:
 
   virtual ~Prelock_error_handler() {}
 
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd);
 
@@ -58,6 +58,7 @@ private:
 
 bool
 Prelock_error_handler::handle_error(uint sql_errno,
+                                    const char * /* message */,
                                     MYSQL_ERROR::enum_warning_level /* level */,
                                     THD * /* thd */)
 {
@@ -491,9 +492,8 @@ static TABLE_SHARE
   int tmp;
   DBUG_ENTER("get_table_share_with_create");
 
-  if ((share= get_table_share(thd, table_list, key, key_length, 
-                              db_flags, error)) ||
-      thd->net.last_errno != ER_NO_SUCH_TABLE)
+  share= get_table_share(thd, table_list, key, key_length, db_flags, error);
+  if (share || thd->is_error() && thd->main_da.sql_errno() !=
ER_NO_SUCH_TABLE)
     DBUG_RETURN(share);
 
   /* Table didn't exist. Check if some engine can provide it */
@@ -504,7 +504,7 @@ static TABLE_SHARE
       No such table in any engine.
       Hide "Table doesn't exist" errors if table belong to view
     */
-    if (table_list->belong_to_view)
+    if (thd->is_error() && table_list->belong_to_view)
     {
       TABLE_LIST *view= table_list->belong_to_view;
       thd->clear_error();
@@ -6260,7 +6260,7 @@ bool setup_fields(THD *thd, Item **ref_p
   thd->lex->allow_sum_func= save_allow_sum_func;
   thd->mark_used_columns= save_mark_used_columns;
   DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
-  DBUG_RETURN(test(thd->net.report_error));
+  DBUG_RETURN(test(thd->is_error()));
 }
 
 
@@ -6807,7 +6807,7 @@ int setup_conds(THD *thd, TABLE_LIST *ta
     select_lex->conds_processed_with_permanent_arena= 1;
   }
   thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
-  DBUG_RETURN(test(thd->net.report_error));
+  DBUG_RETURN(test(thd->is_error()));
 
 err_no_arena:
   select_lex->is_item_list_lookup= save_is_item_list_lookup;
@@ -6889,7 +6889,7 @@ fill_record(THD * thd, List<Item> &field
       goto err;
     }
   }
-  DBUG_RETURN(thd->net.report_error);
+  DBUG_RETURN(thd->is_error());
 err:
   if (table)
     table->auto_increment_field_not_null= FALSE;
@@ -6974,7 +6974,7 @@ fill_record(THD *thd, Field **ptr, List<
     table= (*ptr)->table;
     table->auto_increment_field_not_null= FALSE;
   }
-  while ((field = *ptr++) && !thd->net.report_error)
+  while ((field = *ptr++) && !thd->is_error())
   {
     value=v++;
     table= field->table;
@@ -6983,7 +6983,7 @@ fill_record(THD *thd, Field **ptr, List<
     if (value->save_in_field(field, 0) < 0)
       goto err;
   }
-  DBUG_RETURN(thd->net.report_error);
+  DBUG_RETURN(thd->is_error());
 
 err:
   if (table)
diff -Nrup a/sql/sql_binlog.cc b/sql/sql_binlog.cc
--- a/sql/sql_binlog.cc	2007-08-16 09:37:42 +04:00
+++ b/sql/sql_binlog.cc	2007-10-30 14:54:54 +03:00
@@ -37,12 +37,6 @@ void mysql_client_binlog_statement(THD* 
                             thd->lex->comment.length : 2048),
                      thd->lex->comment.str));
 
-  /*
-    Temporarily turn off send_ok, since different events handle this
-    differently
-  */
-  my_bool nsok= thd->net.no_send_ok;
-  thd->net.no_send_ok= TRUE;
 
   size_t coded_len= thd->lex->comment.length + 1;
   size_t decoded_len= base64_needed_decoded_length(coded_len);
@@ -190,20 +184,11 @@ void mysql_client_binlog_statement(THD* 
     }
   }
 
-  /*
-    Restore setting of no_send_ok
-  */
-  thd->net.no_send_ok= nsok;
 
   DBUG_PRINT("info",("binlog base64 execution finished successfully"));
-  send_ok(thd);
+  my_ok(thd);
 
 end:
-  /*
-    Restore setting of no_send_ok
-  */
-  thd->net.no_send_ok= nsok;
-
   delete desc;
   my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
   DBUG_VOID_RETURN;
diff -Nrup a/sql/sql_cache.cc b/sql/sql_cache.cc
--- a/sql/sql_cache.cc	2007-10-16 16:42:41 +04:00
+++ b/sql/sql_cache.cc	2007-10-30 14:54:54 +03:00
@@ -1403,6 +1403,7 @@ def_week_frmt: %lu",                    
 
   thd->limit_found_rows = query->found_rows();
   thd->status_var.last_query_cost= 0.0;
+  thd->main_da.disable_status();
 
   BLOCK_UNLOCK_RD(query_block);
   DBUG_RETURN(1);				// Result sent to client
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc	2007-10-15 16:42:39 +04:00
+++ b/sql/sql_class.cc	2007-10-30 14:54:54 +03:00
@@ -352,6 +352,94 @@ char *thd_security_context(THD *thd, cha
 }
 
 
+void
+Diagnostics_area::reset_diagnostics_area()
+{
+#ifdef DBUG_OFF
+  can_overwrite_status= FALSE;
+  /** Don't take chances in production */
+  m_message[0]= '\0';
+  m_sql_errno= 0;
+  m_server_status= 0;
+  m_affected_rows= 0;
+  m_last_insert_id= 0;
+  m_total_warn_count= 0;
+#endif
+  is_sent= FALSE;
+  /** Tiny reset in debug mode to see garbage right away */
+  m_status= DA_EMPTY;
+}
+
+
+void
+Diagnostics_area::set_success_status(THD *thd, ha_rows affected_rows_arg,
+                                     ulong last_insert_id_arg,
+                                     const char *message_arg)
+{
+  DBUG_ASSERT(! is_set());
+#ifdef DBUG_OFF
+  /* In production, refuse to overwrite an error with an OK packet. */
+  if (is_error())
+    return;
+#endif
+  /** Only allowed to report success if has not yet reported an error */
+
+  m_server_status= thd->server_status;
+  m_total_warn_count= thd->total_warn_count;
+  m_affected_rows= affected_rows_arg;
+  m_last_insert_id= last_insert_id_arg;
+  if (message_arg)
+    strmake(m_message, message_arg, sizeof(m_message));
+  else
+    m_message[0]= '\0';
+  m_status= DA_OK;
+}
+
+
+void
+Diagnostics_area::set_eof_status(THD *thd)
+{
+  /** Only allowed to report eof if has not yet reported an error */
+
+  DBUG_ASSERT(! is_set());
+#ifdef DBUG_OFF
+  /* In production, refuse to overwrite an error with an EOF packet. */
+  if (is_error())
+    return;
+#endif
+
+  m_server_status= thd->server_status;
+  m_total_warn_count= thd->total_warn_count;
+
+  m_status= DA_EOF;
+}
+
+
+void
+Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
+                                   const char *message_arg)
+{
+  /*
+    Only allowed to report error if has not yet reported a success
+    The only exception is when we flush the message to the client,
+    an error can happen during the flush.
+  */
+  DBUG_ASSERT(! is_set() || can_overwrite_status);
+
+  m_sql_errno= sql_errno_arg;
+  strmake(m_message, message_arg, sizeof(m_message));
+
+  m_status= DA_ERROR;
+}
+
+
+void
+Diagnostics_area::disable_status()
+{
+  DBUG_ASSERT(! is_set());
+  m_status= DA_DISABLED;
+}
+
 
 THD::THD()
    :Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
@@ -431,7 +519,6 @@ THD::THD()
   net.vio=0;
 #endif
   client_capabilities= 0;                       // minimalistic client
-  net.last_error[0]=0;                          // If error on boot
 #ifdef HAVE_QUERY_CACHE
   query_cache_init_query(&net);                 // If error on boot
 #endif
@@ -498,12 +585,12 @@ void THD::push_internal_handler(Internal
 }
 
 
-bool THD::handle_error(uint sql_errno,
+bool THD::handle_error(uint sql_errno, const char *message,
                        MYSQL_ERROR::enum_warning_level level)
 {
   if (m_internal_handler)
   {
-    return m_internal_handler->handle_error(sql_errno, level, this);
+    return m_internal_handler->handle_error(sql_errno, message, level, this);
   }
 
   return FALSE;                                 // 'FALSE', as per coding style
@@ -1305,32 +1392,39 @@ bool select_send::send_fields(List<Item>
 {
   bool res;
   if (!(res= thd->protocol->send_fields(&list, flags)))
-    status= 1;
+    is_result_set_started= 1;
   return res;
 }
 
 void select_send::abort()
 {
   DBUG_ENTER("select_send::abort");
-  if (status && thd->spcont &&
-      thd->spcont->find_handler(thd, thd->net.last_errno,
+  if (is_result_set_started && thd->spcont &&
+      thd->is_error() &&
+      thd->spcont->find_handler(thd, thd->main_da.sql_errno(),
                                 MYSQL_ERROR::WARN_LEVEL_ERROR))
   {
     /*
-      Executing stored procedure without a handler.
-      Here we should actually send an error to the client,
-      but as an error will break a multiple result set, the only thing we
-      can do for now is to nicely end the current data set and remembering
-      the error so that the calling routine will abort
+      We're executing a stored procedure, have an open result
+      set, an SQL exception conditiona and a handler for it.
+      In this situation we must abort the current statement,
+      silence the error and start executing the continue/exit
+      handler.
+      Before aborting the statement, let's end the open result set, as
+      otherwise the client will hang due to the violation of the
+      client/server protocol.
     */
-    thd->net.report_error= 0;
-    send_eof();
-    thd->net.report_error= 1; // Abort SP
+    thd->protocol->end_partial_result_set(thd);
   }
   DBUG_VOID_RETURN;
 }
 
 
+void select_send::cleanup()
+{
+  is_result_set_started= FALSE;
+}
+
 /* Send data to client. Returns 0 if ok */
 
 bool select_send::send_data(List<Item> &items)
@@ -1366,12 +1460,12 @@ bool select_send::send_data(List<Item> &
     }
   }
   thd->sent_row_count++;
-  if (!thd->vio_ok())
-    DBUG_RETURN(0);
-  if (!thd->net.report_error)
-    DBUG_RETURN(protocol->write());
-  protocol->remove_last_row();
-  DBUG_RETURN(1);
+  if (thd->is_error())
+  {
+    protocol->remove_last_row();
+    DBUG_RETURN(1);
+  }
+  DBUG_RETURN(thd->vio_ok() ? protocol->write() : 0);
 }
 
 bool select_send::send_eof()
@@ -1389,10 +1483,12 @@ bool select_send::send_eof()
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
-  if (!thd->net.report_error)
+  /* If error, the caller must call abort() instead */
+  DBUG_ASSERT(!thd->is_error());
+  if (!thd->is_error())
   {
-    ::send_eof(thd);
-    status= 0;
+    my_eof(thd);
+    is_result_set_started= FALSE;
     return 0;
   }
   else
@@ -1429,7 +1525,7 @@ bool select_to_file::send_eof()
       function, SELECT INTO has to have an own SQLCOM.
       TODO: split from SQLCOM_SELECT
     */
-    ::send_ok(thd,row_count);
+    my_ok(thd, row_count);
   }
   file= -1;
   return error;
@@ -2350,7 +2446,7 @@ bool select_dumpvar::send_eof()
     function, SELECT INTO has to have an own SQLCOM.
     TODO: split from SQLCOM_SELECT
   */
-  ::send_ok(thd,row_count);
+  my_ok(thd, row_count);
   return 0;
 }
 
@@ -2649,7 +2745,6 @@ void THD::reset_sub_statement_state(Sub_
 {
   backup->options=         options;
   backup->in_sub_stmt=     in_sub_stmt;
-  backup->no_send_ok=      net.no_send_ok;
   backup->enable_slow_log= enable_slow_log;
   backup->limit_found_rows= limit_found_rows;
   backup->examined_row_count= examined_row_count;
@@ -2680,9 +2775,6 @@ void THD::reset_sub_statement_state(Sub_
   cuted_fields= 0;
   transaction.savepoints= 0;
   first_successful_insert_id_in_cur_stmt= 0;
-
-  /* Surpress OK packets in case if we will execute statements */
-  net.no_send_ok= TRUE;
 }
 
 
@@ -2705,7 +2797,6 @@ void THD::restore_sub_statement_state(Su
   transaction.savepoints= backup->savepoints;
   options=          backup->options;
   in_sub_stmt=      backup->in_sub_stmt;
-  net.no_send_ok=   backup->no_send_ok;
   enable_slow_log=  backup->enable_slow_log;
   first_successful_insert_id_in_prev_stmt= 
     backup->first_successful_insert_id_in_prev_stmt;
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h	2007-09-29 02:11:24 +04:00
+++ b/sql/sql_class.h	2007-10-30 14:54:54 +03:00
@@ -913,7 +913,6 @@ public:
   uint in_sub_stmt;
   bool enable_slow_log;
   bool last_insert_id_used;
-  my_bool no_send_ok;
   SAVEPOINT *savepoints;
 };
 
@@ -969,10 +968,117 @@ public:
     @return true if the error is handled
   */
   virtual bool handle_error(uint sql_errno,
+                            const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd) = 0;
 };
 
+/**
+  Stores status of the currently executed statement.
+  Cleared at the beginning of the statement, and then
+  can hold either OK, error, or EOF status.
+  Can not be assigned twice per statement.
+*/
+
+class Diagnostics_area
+{
+public:
+  enum enum_diagnostics_status
+  {
+    /** The area is cleared at start of a statement. */
+    DA_EMPTY= 0,
+    /** Set whenever one calls my_ok() */
+    DA_OK,
+    /** Set whenever one calls my_eof() */
+    DA_EOF,
+    /** Set whenever one calls my_error() or my_message() */
+    DA_ERROR,
+    /** Set in case of a custom response, such as one from COM_STMT_PREPARE */
+    DA_DISABLED
+  };
+  /* True if sent to the client */
+  bool is_sent;
+  /** Set to make set_error_status after set_{ok,eof}_status possible */
+  bool can_overwrite_status;
+
+  void set_success_status(THD *thd, ha_rows affected_rows_arg,
+                          ulong last_insert_id_arg,
+                          const char *message);
+  void set_eof_status(THD *thd);
+  void set_error_status(THD *thd, uint sql_errno_arg, const char *message_arg);
+
+  void disable_status();
+
+  void reset_diagnostics_area();
+
+  bool is_set() const { return m_status != DA_EMPTY; }
+  bool is_error() const { return m_status == DA_ERROR; }
+  bool is_eof() const { return m_status == DA_EOF; }
+  bool is_disabled() const { return m_status == DA_DISABLED; }
+
+  const char *message() const
+  { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK); return m_message; }
+
+  uint sql_errno() const
+  { DBUG_ASSERT(m_status == DA_ERROR); return m_sql_errno; }
+
+  uint server_status() const
+  {
+    DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
+    return m_server_status;
+  }
+
+  ha_rows affected_rows() const
+  { DBUG_ASSERT(m_status == DA_OK); return m_affected_rows; }
+
+  ulong last_insert_id() const
+  { DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
+
+  uint total_warn_count() const
+  {
+    DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
+    return m_total_warn_count;
+  }
+
+  enum_diagnostics_status status() const { return m_status; }
+
+  Diagnostics_area() { reset_diagnostics_area(); }
+
+private:
+  char m_message[MYSQL_ERRMSG_SIZE];
+  uint m_sql_errno;
+
+  uint m_server_status;
+  /** OK status attributes *****************************************/
+  /**
+    The number of rows affected by the last statement. This is
+    semantically close to thd->row_count_func, but has a different
+    life cycle. thd->row_count_func stores the value returned by
+    function ROW_COUNT() and is cleared only by statements that
+    update its value, such as INSERT, UPDATE, DELETE and few others.
+    This member is cleared by every statement.
+
+    The reason for the difference in the life cycle is legacy:
+    ROW_COUNT() is a non-standard replacement for GET DIAGNOSTICS.
+  */
+  ha_rows    m_affected_rows;
+  /**
+    Similarly to the previous member, this is a replacement of
+    thd->first_successful_insert_id_in_prev_stmt, which is used
+    to implement LAST_INSERT_ID(). This member is cleared before
+    each statement.
+  */
+  ulong      m_last_insert_id;
+  /** The total number of warnings */
+  uint	     m_total_warn_count;
+  enum_diagnostics_status m_status;
+  /**
+    @todo: the following THD members belong here:
+    - warn_list, warn_count, total_warn_count
+    - net.last_error, net.last_errno
+  */
+};
+
 
 /**
   @class THD
@@ -1386,6 +1492,7 @@ public:
   List	     <MYSQL_ERROR> warn_list;
   uint	     warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
   uint	     total_warn_count;
+  Diagnostics_area main_da;
   /*
     Id of current query. Statement can be reused to execute several queries
     query_id is global in context of the whole MySQL server.
@@ -1692,9 +1799,8 @@ public:
   inline void clear_error()
   {
     DBUG_ENTER("clear_error");
-    net.last_error[0]= 0;
-    net.last_errno= 0;
-    net.report_error= 0;
+    if (main_da.is_error())
+      main_da.reset_diagnostics_area();
     query_error= 0;
     DBUG_VOID_RETURN;
   }
@@ -1706,7 +1812,6 @@ public:
   inline void fatal_error()
   {
     is_fatal_error= 1;
-    net.report_error= 1;
     DBUG_PRINT("error",("Fatal error set"));
   }
   inline CHARSET_INFO *charset() { return variables.character_set_client; }
@@ -1902,7 +2007,7 @@ public:
     @param level the error level
     @return true if the error is handled
   */
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level);
 
   /**
@@ -1910,6 +2015,8 @@ public:
   */
   void pop_internal_handler();
 
+  /** True if an error occurred during execution of a query */
+  bool is_error() { return main_da.is_error(); }
 private:
   /** The current internal error handler for this thread, or NULL. */
   Internal_error_handler *m_internal_handler;
@@ -1932,6 +2039,21 @@ private:
 };
 
 
+inline void
+my_ok(THD *thd, ha_rows affected_rows= 0, ulonglong id= 0,
+      const char *message= NULL)
+{
+  thd->main_da.set_success_status(thd, affected_rows, id, message);
+}
+
+
+
+inline void
+my_eof(THD *thd)
+{
+  thd->main_da.set_eof_status(thd);
+}
+
 #define tmp_disable_binlog(A)       \
   {ulonglong tmp_disable_binlog__save_options= (A)->options; \
   (A)->options&= ~OPTION_BIN_LOG
@@ -2029,14 +2151,20 @@ public:
 
 
 class select_send :public select_result {
-  int status;
+  /**
+    True if we have sent result set metadata to the client.
+    In this case the client always expects us to end the result
+    set with an eof or error packet
+  */
+  bool is_result_set_started;
 public:
-  select_send() :status(0) {}
+  select_send() :is_result_set_started(FALSE) {}
   bool send_fields(List<Item> &list, uint flags);
   bool send_data(List<Item> &items);
   bool send_eof();
   virtual bool check_simple_select() const { return FALSE; }
   void abort();
+  virtual void cleanup();
 };
 
 
@@ -2529,6 +2657,11 @@ public:
 #define CF_STATUS_COMMAND	4
 #define CF_SHOW_TABLE_COMMAND	8
 #define CF_WRITE_LOGS_COMMAND  16
+/*
+  Set to true if the command returns result set
+  records and should be followed by 'EOF' packet
+*/
+#define CF_RETURNS_RESULT_SET  32
 
 /* Functions in sql_class.cc */
 
diff -Nrup a/sql/sql_connect.cc b/sql/sql_connect.cc
--- a/sql/sql_connect.cc	2007-10-10 17:56:58 +04:00
+++ b/sql/sql_connect.cc	2007-10-30 14:54:54 +03:00
@@ -87,7 +87,8 @@ static int get_or_create_user_conn(THD *
 	       my_malloc(sizeof(struct user_conn) + temp_len+1,
 			 MYF(MY_WME)))))
     {
-      net_send_error(thd, 0, NullS);		// Out of memory
+      /* MY_WME requests an error message on error */
+      DBUG_ASSERT(thd->main_da.is_error());
       return_val= 1;
       goto end;
     }
@@ -100,8 +101,10 @@ static int get_or_create_user_conn(THD *
     uc->reset_utime= thd->thr_create_utime;
     if (my_hash_insert(&hash_user_connections, (uchar*) uc))
     {
+      /* An error is only possible if out of memory, which should
+        set the message */
+      DBUG_ASSERT(thd->main_da.is_error());
       my_free((char*) uc,0);
-      net_send_error(thd, 0, NullS);		// Out of memory
       return_val= 1;
       goto end;
     }
@@ -132,6 +135,7 @@ end:
     1	error
 */
 
+static
 int check_for_max_user_connections(THD *thd, USER_CONN *uc)
 {
   int error=0;
@@ -141,7 +145,7 @@ int check_for_max_user_connections(THD *
   if (max_user_connections && !uc->user_resources.user_conn &&
       max_user_connections < (uint) uc->connections)
   {
-    net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user);
+    my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
     error=1;
     goto end;
   }
@@ -149,24 +153,24 @@ int check_for_max_user_connections(THD *
   if (uc->user_resources.user_conn &&
       uc->user_resources.user_conn < uc->connections)
   {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-                     "max_user_connections",
-                     (long) uc->user_resources.user_conn);
+    my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
+             "max_user_connections",
+             (long) uc->user_resources.user_conn);
     error= 1;
     goto end;
   }
   if (uc->user_resources.conn_per_hour &&
       uc->user_resources.conn_per_hour <= uc->conn_per_hour)
   {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user,
-                     "max_connections_per_hour",
-                     (long) uc->user_resources.conn_per_hour);
+    my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
+             "max_connections_per_hour",
+             (long) uc->user_resources.conn_per_hour);
     error=1;
     goto end;
   }
   uc->conn_per_hour++;
 
-  end:
+end:
   if (error)
     uc->connections--; // no need for decrease_user_connections() here
   (void) pthread_mutex_unlock(&LOCK_user_conn);
@@ -258,8 +262,8 @@ bool check_mqh(THD *thd, uint check_comm
   if (uc->user_resources.questions &&
       uc->questions++ >= uc->user_resources.questions)
   {
-    net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions",
-                     (long) uc->user_resources.questions);
+    my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
+             (long) uc->user_resources.questions);
     error=1;
     goto end;
   }
@@ -270,7 +274,7 @@ bool check_mqh(THD *thd, uint check_comm
         (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
 	uc->updates++ >= uc->user_resources.updates)
     {
-      net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
+      my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
                        (long) uc->user_resources.updates);
       error=1;
       goto end;
@@ -305,9 +309,8 @@ end:
 
   RETURN VALUE
     0  OK; thd->security_ctx->user/master_access/priv_user/db_access and
-       thd->db are updated; OK is sent to client;
-   -1  access denied or handshake error; error is sent to client;
-   >0  error, not sent to client
+       thd->db are updated
+    1  access denied or handshake error
 */
 
 int check_user(THD *thd, enum enum_server_command command, 
@@ -328,13 +331,9 @@ int check_user(THD *thd, enum enum_serve
     */
     thd->reset_db(NULL, 0);
     if (mysql_change_db(thd, &db_str, FALSE))
-    {
-      /* Send the error to the client */
-      net_send_error(thd);
-      DBUG_RETURN(-1);
-    }
+      DBUG_RETURN(1);
   }
-  send_ok(thd);
+  my_ok(thd);
   DBUG_RETURN(0);
 #else
 
@@ -349,14 +348,17 @@ int check_user(THD *thd, enum enum_serve
   */
   if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
   {
-    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
+    my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
     general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-    DBUG_RETURN(-1);
+    DBUG_RETURN(1);
   }
   if (passwd_len != 0 &&
       passwd_len != SCRAMBLE_LENGTH &&
       passwd_len != SCRAMBLE_LENGTH_323)
-    DBUG_RETURN(ER_HANDSHAKE_ERROR);
+  {
+    my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+    DBUG_RETURN(1);
+  }
 
   /*
     Clear thd->db as it points to something, that will be freed when 
@@ -380,20 +382,21 @@ int check_user(THD *thd, enum enum_serve
     NET *net= &thd->net;
     if (opt_secure_auth_local)
     {
-      net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE,
-                       thd->main_security_ctx.user,
-                       thd->main_security_ctx.host_or_ip);
+      my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
+               thd->main_security_ctx.user,
+               thd->main_security_ctx.host_or_ip);
       general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
                         thd->main_security_ctx.user,
                         thd->main_security_ctx.host_or_ip);
-      DBUG_RETURN(-1);
+      DBUG_RETURN(1);
     }
     /* We have to read very specific packet size */
     if (send_old_password_request(thd) ||
         my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
     {
       inc_host_errors(&thd->remote.sin_addr);
-      DBUG_RETURN(ER_HANDSHAKE_ERROR);
+      my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+      DBUG_RETURN(1);
     }
     /* Final attempt to check the user based on reply */
     /* So as passwd is short, errcode is always >= 0 */
@@ -427,8 +430,8 @@ int check_user(THD *thd, enum enum_serve
         VOID(pthread_mutex_unlock(&LOCK_thread_count));
         if (!count_ok)
         {                                         // too many connections
-          net_send_error(thd, ER_CON_COUNT_ERROR);
-          DBUG_RETURN(-1);
+          my_error(ER_CON_COUNT_ERROR, MYF(0));
+          DBUG_RETURN(1);
         }
       }
 
@@ -462,13 +465,13 @@ int check_user(THD *thd, enum enum_serve
             (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
              thd->main_security_ctx.priv_host),
             &ur))
-	DBUG_RETURN(-1);
+	DBUG_RETURN(1);
       if (thd->user_connect &&
 	  (thd->user_connect->user_resources.conn_per_hour ||
 	   thd->user_connect->user_resources.user_conn ||
 	   max_user_connections) &&
 	  check_for_max_user_connections(thd, thd->user_connect))
-	DBUG_RETURN(-1);
+	DBUG_RETURN(1);
 
       /* Change database if necessary */
       if (db && db[0])
@@ -476,33 +479,32 @@ int check_user(THD *thd, enum enum_serve
         if (mysql_change_db(thd, &db_str, FALSE))
         {
           /* Send error to the client */
-          net_send_error(thd);
           if (thd->user_connect)
             decrease_user_connections(thd->user_connect);
-          DBUG_RETURN(-1);
+          DBUG_RETURN(1);
         }
       }
-      send_ok(thd);
       thd->password= test(passwd_len);          // remember for error messages 
       /* Ready to handle queries */
+      my_ok(thd);
       DBUG_RETURN(0);
     }
   }
   else if (res == 2) // client gave short hash, server has long hash
   {
-    net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE);
+    my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
     general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-    DBUG_RETURN(-1);
+    DBUG_RETURN(1);
   }
-  net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
-                   thd->main_security_ctx.user,
-                   thd->main_security_ctx.host_or_ip,
-                   passwd_len ? ER(ER_YES) : ER(ER_NO));
+  my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
+           thd->main_security_ctx.user,
+           thd->main_security_ctx.host_or_ip,
+           passwd_len ? ER(ER_YES) : ER(ER_NO));
   general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
                     thd->main_security_ctx.user,
                     thd->main_security_ctx.host_or_ip,
                     passwd_len ? ER(ER_YES) : ER(ER_NO));
-  DBUG_RETURN(-1);
+  DBUG_RETURN(1);
 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
 }
 
@@ -666,9 +668,12 @@ static int check_connection(THD *thd)
     char ip[30];
 
     if (vio_peer_addr(net->vio, ip, &thd->peer_port))
-      return (ER_BAD_HOST_ERROR);
-    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(0))))
-      return (ER_OUT_OF_RESOURCES);
+    {
+      my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+      return 1;
+    }
+    if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
+      return 1; /* The error is set by my_strdup */
     thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
     vio_in_addr(net->vio,&thd->remote.sin_addr);
     if (!(specialflag & SPECIAL_NO_RESOLVE))
@@ -685,7 +690,9 @@ static int check_connection(THD *thd)
         thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
       }
       if (connect_errors > max_connect_errors)
-        return(ER_HOST_IS_BLOCKED);
+      {
+        my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip);
+      }
     }
     DBUG_PRINT("info",("Host: %s  ip: %s",
 		       (thd->main_security_ctx.host ?
@@ -693,7 +700,11 @@ static int check_connection(THD *thd)
 		       (thd->main_security_ctx.ip ?
                         thd->main_security_ctx.ip : "unknown ip")));
     if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
-      return(ER_HOST_NOT_PRIVILEGED);
+    {
+      my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),
+               thd->main_security_ctx.host_or_ip);
+      return 1;
+    }
   }
   else /* Hostname given means that the connection was on a socket */
   {
@@ -753,7 +764,9 @@ static int check_connection(THD *thd)
 	pkt_len < MIN_HANDSHAKE_SIZE)
     {
       inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
+      my_error(ER_HANDSHAKE_ERROR, MYF(0),
+               thd->main_security_ctx.host_or_ip);
+      return 1;
     }
   }
 #ifdef _CUSTOMCONFIG_
@@ -762,7 +775,7 @@ static int check_connection(THD *thd)
   if (connect_errors)
     reset_host_errors(&thd->remote.sin_addr);
   if (thd->packet.alloc(thd->variables.net_buffer_length))
-    return(ER_OUT_OF_RESOURCES);
+    return 1; /* The error is set by alloc */
 
   thd->client_capabilities=uint2korr(net->read_pos);
   if (thd->client_capabilities & CLIENT_PROTOCOL_41)
@@ -790,14 +803,16 @@ static int check_connection(THD *thd)
     if (!ssl_acceptor_fd)
     {
       inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
+      my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+      return 1;
     }
     DBUG_PRINT("info", ("IO layer change in progress..."));
     if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
     {
       DBUG_PRINT("error", ("Failed to accept new SSL connection"));
       inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
+      my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+      return 1;
     }
     DBUG_PRINT("info", ("Reading user information over SSL layer"));
     if ((pkt_len= my_net_read(net)) == packet_error ||
@@ -806,7 +821,8 @@ static int check_connection(THD *thd)
       DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
 			   pkt_len));
       inc_host_errors(&thd->remote.sin_addr);
-      return(ER_HANDSHAKE_ERROR);
+      my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+      return 1;
     }
   }
 #endif /* HAVE_OPENSSL */
@@ -814,7 +830,7 @@ static int check_connection(THD *thd)
   if (end >= (char*) net->read_pos+ pkt_len +2)
   {
     inc_host_errors(&thd->remote.sin_addr);
-    return(ER_HANDSHAKE_ERROR);
+    my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
   }
 
   if (thd->client_capabilities & CLIENT_INTERACTIVE)
@@ -851,7 +867,7 @@ static int check_connection(THD *thd)
   if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
   {
     inc_host_errors(&thd->remote.sin_addr);
-    return ER_HANDSHAKE_ERROR;
+    my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
   }
 
   /* Since 4.1 all database names are stored in utf8 */
@@ -879,8 +895,8 @@ static int check_connection(THD *thd)
 
   if (thd->main_security_ctx.user)
     x_free(thd->main_security_ctx.user);
-  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0))))
-    return (ER_OUT_OF_RESOURCES);
+  if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
+    return 1; /* The error is set by my_strdup */
   return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
 }
 
@@ -936,16 +952,15 @@ bool login_connection(THD *thd)
   DBUG_PRINT("info", ("login_connection called by thread %lu",
                       thd->thread_id));
 
-  net->no_send_error= 0;
-
   /* Use "connect_timeout" value during connection phase */
   my_net_set_read_timeout(net, connect_timeout);
   my_net_set_write_timeout(net, connect_timeout);
 
-  if ((error=check_connection(thd)))
+  error= check_connection(thd);
+  net_end_statement(thd);
+
+  if (error)
   {						// Wrong permissions
-    if (error > 0)
-      net_printf_error(thd, error, sctx->host_or_ip);
 #ifdef __NT__
     if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
       my_sleep(1000);				/* must wait after eof() */
@@ -974,13 +989,12 @@ void end_connection(THD *thd)
   if (thd->user_connect)
     decrease_user_connections(thd->user_connect);
 
-  if (thd->killed ||
-      net->error && net->vio != 0 && net->report_error)
+  if (thd->killed || net->error && net->vio != 0)
   {
     statistic_increment(aborted_threads,&LOCK_status);
   }
 
-  if (net->error && net->vio != 0 && net->report_error)
+  if (net->error && net->vio != 0)
   {
     if (!thd->killed && thd->variables.log_warnings > 1)
     {
@@ -990,11 +1004,9 @@ void end_connection(THD *thd)
                         thd->thread_id,(thd->db ? thd->db : "unconnected"),
                         sctx->user ? sctx->user : "unauthenticated",
                         sctx->host_or_ip,
-                        (net->last_errno ? ER(net->last_errno) :
+                        (thd->main_da.is_error() ? thd->main_da.message() :
                          ER(ER_UNKNOWN_ERROR)));
     }
-
-    net_send_error(thd, net->last_errno, NullS);
   }
 }
 
@@ -1030,14 +1042,14 @@ static void prepare_new_connection_state
   if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
   {
     execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
-    if (thd->query_error)
+    if (thd->is_error())
     {
       thd->killed= THD::KILL_CONNECTION;
       sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
                         thd->thread_id,(thd->db ? thd->db : "unconnected"),
                         sctx->user ? sctx->user : "unauthenticated",
                         sctx->host_or_ip, "init_connect command failed");
-      sql_print_warning("%s", thd->net.last_error);
+      sql_print_warning("%s", thd->main_da.message());
     }
     thd->proc_info=0;
     thd->set_time();
@@ -1103,7 +1115,6 @@ pthread_handler_t handle_one_connection(
     while (!net->error && net->vio != 0 &&
            !(thd->killed == THD::KILL_CONNECTION))
     {
-      net->no_send_error= 0;
       if (do_command(thd))
 	break;
     }
diff -Nrup a/sql/sql_db.cc b/sql/sql_db.cc
--- a/sql/sql_db.cc	2007-09-11 02:10:32 +04:00
+++ b/sql/sql_db.cc	2007-10-30 14:54:54 +03:00
@@ -595,7 +595,7 @@ CHARSET_INFO *get_default_db_collation(T
 		In this case the entry should not be logged.
 
   SIDE-EFFECTS
-   1. Report back to client that command succeeded (send_ok)
+   1. Store success status in the THD if command succeeded (my_ok)
    2. Report errors to client
    3. Log event to binary log
    (The 'silent' flags turns off 1 and 3.)
@@ -660,7 +660,7 @@ bool mysql_create_db(THD *thd, char *db,
     push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 			ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
     if (!silent)
-      send_ok(thd);
+      my_ok(thd);
     error= 0;
     goto exit;
   }
@@ -749,7 +749,7 @@ bool mysql_create_db(THD *thd, char *db,
       /* These DDL methods and logging protected with LOCK_mysql_create_db */
       mysql_bin_log.write(&qinfo);
     }
-    send_ok(thd, result);
+    my_ok(thd, result);
   }
 
 exit:
@@ -826,7 +826,7 @@ bool mysql_alter_db(THD *thd, const char
     /* These DDL methods and logging protected with LOCK_mysql_create_db */
     mysql_bin_log.write(&qinfo);
   }
-  send_ok(thd, result);
+  my_ok(thd, result);
 
 exit:
   VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
@@ -914,6 +914,8 @@ bool mysql_rm_db(THD *thd,char *db,bool 
     {
       ha_drop_database(path);
       query_cache_invalidate1(db);
+      (void) sp_drop_db_routines(thd, db); /* QQ Ignore errors for now  */
+      Events::drop_schema_events(thd, db);
       error = 0;
     }
   }
@@ -949,8 +951,9 @@ bool mysql_rm_db(THD *thd,char *db,bool 
       /* These DDL methods and logging protected with LOCK_mysql_create_db */
       mysql_bin_log.write(&qinfo);
     }
+    thd->clear_error();
     thd->server_status|= SERVER_STATUS_DB_DROPPED;
-    send_ok(thd, (ulong) deleted);
+    my_ok(thd, (ulong) deleted);
     thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
   }
   else if (mysql_bin_log.is_open())
@@ -992,8 +995,6 @@ bool mysql_rm_db(THD *thd,char *db,bool 
   }
 
 exit:
-  (void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now  */
-  Events::drop_schema_events(thd, db);
   /*
     If this database was the client's selected database, we silently
     change the client's selected database to nothing (to have an empty
diff -Nrup a/sql/sql_delete.cc b/sql/sql_delete.cc
--- a/sql/sql_delete.cc	2007-10-15 16:42:39 +04:00
+++ b/sql/sql_delete.cc	2007-10-30 14:54:54 +03:00
@@ -111,6 +111,15 @@ bool mysql_delete(THD *thd, TABLE_LIST *
        (!thd->current_stmt_binlog_row_based &&
         !(table->triggers && table->triggers->has_delete_triggers()))))
   {
+    /* Check if error when evaluating the conds */
+    if (thd->is_error())
+    {
+      delete select;
+      free_underlaid_joins(thd, select_lex);
+      thd->row_count_func= 0;
+      DBUG_RETURN(TRUE);
+    }
+
     /* Update the table->file->stats.records number */
     table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
     ha_rows const maybe_deleted= table->file->stats.records;
@@ -142,7 +151,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   {
     free_underlaid_joins(thd, select_lex);
     thd->row_count_func= 0;
-    send_ok(thd, (ha_rows) thd->row_count_func);  // No matching records
+    my_ok(thd, (ha_rows) thd->row_count_func);  // No matching records
     DBUG_RETURN(0);
   }
 #endif
@@ -159,13 +168,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     delete select;
     free_underlaid_joins(thd, select_lex);
     thd->row_count_func= 0;
-    send_ok(thd, (ha_rows) thd->row_count_func);
+    if (! thd->is_error())
+      my_ok(thd, (ha_rows) thd->row_count_func);
     /*
       We don't need to call reset_auto_increment in this case, because
       mysql_truncate always gives a NULL conds argument, hence we never
       get here.
     */
-    DBUG_RETURN(0);				// Nothing to delete
+    DBUG_RETURN(thd->is_error());                 // Nothing to delete
   }
 
   /* If running in safe sql mode, don't allow updates without keys */
@@ -252,12 +262,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   table->mark_columns_needed_for_delete();
 
   while (!(error=info.read_record(&info)) && !thd->killed &&
-	 !thd->net.report_error)
+	 !thd->is_error())
   {
-    // thd->net.report_error is tested to disallow delete row on error
-    if (!(select && select->skip_record())&& !thd->net.report_error
)
+    bool do_delete_record= !select || !select->skip_record();
+    if (thd->is_error())
+    {
+      error= 1;
+      break;
+    }
+    if (do_delete_record)
     {
-
       if (table->triggers &&
           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
                                             TRG_ACTION_BEFORE, FALSE))
@@ -386,10 +400,10 @@ cleanup:
   if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
   {
     thd->row_count_func= deleted;
-    send_ok(thd, (ha_rows) thd->row_count_func);
+    my_ok(thd, (ha_rows) thd->row_count_func);
     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
   }
-  DBUG_RETURN(error >= 0 || thd->net.report_error);
+  DBUG_RETURN(error >= 0 || thd->is_error());
 }
 
 
@@ -889,7 +903,7 @@ bool multi_delete::send_eof()
   if (!local_error)
   {
     thd->row_count_func= deleted;
-    ::send_ok(thd, (ha_rows) thd->row_count_func);
+    my_ok(thd, (ha_rows) thd->row_count_func);
   }
   return 0;
 }
@@ -989,7 +1003,7 @@ end:
         we don't test current_stmt_binlog_row_based.
       */
       write_bin_log(thd, TRUE, thd->query, thd->query_length);
-      send_ok(thd);		// This should return record count
+      my_ok(thd);		// This should return record count
     }
     VOID(pthread_mutex_lock(&LOCK_open));
     unlock_table_name(thd, table_list);
diff -Nrup a/sql/sql_derived.cc b/sql/sql_derived.cc
--- a/sql/sql_derived.cc	2007-04-23 15:16:45 +04:00
+++ b/sql/sql_derived.cc	2007-10-30 14:54:55 +03:00
@@ -147,8 +147,9 @@ exit:
     /* Hide "Unknown column" or "Unknown function" error */
     if (orig_table_list->view)
     {
-      if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
-          thd->net.last_errno == ER_SP_DOES_NOT_EXIST)
+      if (thd->is_error() &&
+          (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR ||
+          thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST))
       {
         thd->clear_error();
         my_error(ER_VIEW_INVALID, MYF(0), orig_table_list->db,
diff -Nrup a/sql/sql_do.cc b/sql/sql_do.cc
--- a/sql/sql_do.cc	2006-12-31 03:06:36 +03:00
+++ b/sql/sql_do.cc	2007-10-30 14:54:55 +03:00
@@ -29,6 +29,6 @@ bool mysql_do(THD *thd, List<Item> &valu
     value->val_int();
   free_underlaid_joins(thd, &thd->lex->select_lex);
   thd->clear_error(); // DO always is OK
-  send_ok(thd);
+  my_ok(thd);
   DBUG_RETURN(FALSE);
 }
diff -Nrup a/sql/sql_error.cc b/sql/sql_error.cc
--- a/sql/sql_error.cc	2007-07-27 04:26:40 +04:00
+++ b/sql/sql_error.cc	2007-10-30 14:54:55 +03:00
@@ -137,7 +137,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQ
     level= MYSQL_ERROR::WARN_LEVEL_ERROR;
   }
 
-  if (thd->handle_error(code, level))
+  if (thd->handle_error(code, msg, level))
     DBUG_RETURN(NULL);
 
   if (thd->spcont &&
@@ -211,7 +211,7 @@ const LEX_STRING warning_level_names[]=
 };
 
 bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
-{  
+{
   List<Item> field_list;
   DBUG_ENTER("mysqld_show_warnings");
 
@@ -249,6 +249,6 @@ bool mysqld_show_warnings(THD *thd, ulon
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
diff -Nrup a/sql/sql_handler.cc b/sql/sql_handler.cc
--- a/sql/sql_handler.cc	2007-10-12 17:56:44 +04:00
+++ b/sql/sql_handler.cc	2007-10-30 14:54:55 +03:00
@@ -283,7 +283,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST 
   }
 
   if (! reopen)
-    send_ok(thd);
+    my_ok(thd, 0, 0, 0);
   DBUG_PRINT("exit",("OK"));
   DBUG_RETURN(FALSE);
 
@@ -335,7 +335,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST
     DBUG_RETURN(TRUE);
   }
 
-  send_ok(thd);
+  my_ok(thd);
   DBUG_PRINT("exit", ("OK"));
   DBUG_RETURN(FALSE);
 }
@@ -643,7 +643,7 @@ retry:
   }
 ok:
   mysql_unlock_tables(thd,lock);
-  send_eof(thd);
+  my_eof(thd);
   DBUG_PRINT("exit",("OK"));
   DBUG_RETURN(FALSE);
 
diff -Nrup a/sql/sql_help.cc b/sql/sql_help.cc
--- a/sql/sql_help.cc	2007-08-13 17:11:13 +04:00
+++ b/sql/sql_help.cc	2007-10-30 14:54:55 +03:00
@@ -779,7 +779,7 @@ bool mysqld_help(THD *thd, const char *m
     if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
       goto error;
   }
-  send_eof(thd);
+  my_eof(thd);
 
   close_system_tables(thd, &open_tables_state_backup);
   DBUG_RETURN(FALSE);
diff -Nrup a/sql/sql_insert.cc b/sql/sql_insert.cc
--- a/sql/sql_insert.cc	2007-09-29 23:04:24 +04:00
+++ b/sql/sql_insert.cc	2007-10-30 14:54:55 +03:00
@@ -740,7 +740,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
                                                table->triggers,
                                                TRG_EVENT_INSERT))
       {
-	if (values_list.elements != 1 && !thd->net.report_error)
+	if (values_list.elements != 1 && !thd->is_error())
 	{
 	  info.records++;
 	  continue;
@@ -771,7 +771,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
                                                table->triggers,
                                                TRG_EVENT_INSERT))
       {
-	if (values_list.elements != 1 && ! thd->net.report_error)
+	if (values_list.elements != 1 && ! thd->is_error())
 	{
 	  info.records++;
 	  continue;
@@ -857,9 +857,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
           {
             /*
               [Guilhem wrote] Temporary errors may have filled
-              thd->net.last_error/errno.  For example if there has
+              thd->main_da.sql_error/messagge.  For example if there has
               been a disk full error when writing the row, and it was
-              MyISAM, then thd->net.last_error/errno will be set to
+              MyISAM, then thd->main_da.sql_error/message will be set to
               "disk full"... and the my_pwrite() will wait until free
               space appears, and so when it finishes then the
               write_row() was entirely successful
@@ -948,7 +948,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     thd->row_count_func= info.copied + info.deleted +
                          ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
                           info.touched : info.updated);
-    send_ok(thd, (ulong) thd->row_count_func, id);
+    my_ok(thd, (ulong) thd->row_count_func, id);
   }
   else
   {
@@ -963,7 +963,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
       sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	      (ulong) (info.deleted + updated), (ulong) thd->cuted_fields);
     thd->row_count_func= info.copied + info.deleted + updated;
-    ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+    my_ok(thd, (ulong) thd->row_count_func, id, buff);
   }
   thd->abort_on_warning= 0;
   DBUG_RETURN(FALSE);
@@ -1865,8 +1865,8 @@ bool delayed_get_table(THD *thd, TABLE_L
     {
       if (!(di= new Delayed_insert()))
       {
-	my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert));
         thd->fatal_error();
+	my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert));
         goto end_create;
       }
       pthread_mutex_lock(&LOCK_thread_count);
@@ -1896,8 +1896,8 @@ bool delayed_get_table(THD *thd, TABLE_L
 	pthread_mutex_unlock(&di->mutex);
 	di->unlock();
 	delete di;
-	my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
         thd->fatal_error();
+	my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
         goto end_create;
       }
 
@@ -1911,7 +1911,7 @@ bool delayed_get_table(THD *thd, TABLE_L
       thd->proc_info="got old table";
       if (di->thd.killed)
       {
-        if (di->thd.net.report_error)
+        if (di->thd.is_error())
         {
           /*
             Copy the error message. Note that we don't treat fatal
@@ -1919,7 +1919,7 @@ bool delayed_get_table(THD *thd, TABLE_L
             main thread. Use of my_message will enable stored
             procedures continue handlers.
           */
-          my_message(di->thd.net.last_errno, di->thd.net.last_error,
+          my_message(di->thd.main_da.sql_errno(), di->thd.main_da.message(),
                      MYF(0));
 	}
 	di->unlock();
@@ -1942,7 +1942,7 @@ bool delayed_get_table(THD *thd, TABLE_L
   pthread_mutex_unlock(&di->mutex);
   if (table_list->table)
   {
-    DBUG_ASSERT(thd->net.report_error == 0);
+    DBUG_ASSERT(thd->is_error() == 0);
     thd->di= di;
   }
   /* Unlock the delayed insert object after its last access. */
@@ -1951,7 +1951,7 @@ bool delayed_get_table(THD *thd, TABLE_L
 
 end_create:
   pthread_mutex_unlock(&LOCK_delayed_create);
-  DBUG_RETURN(thd->net.report_error);
+  DBUG_RETURN(thd->is_error());
 }
 
 
@@ -1996,7 +1996,7 @@ TABLE *Delayed_insert::get_local_table(T
       goto error;
     if (dead)
     {
-      my_message(thd.net.last_errno, thd.net.last_error, MYF(0));
+      my_message(thd.main_da.sql_errno(), thd.main_da.message(), MYF(0));
       goto error;
     }
   }
@@ -2255,7 +2255,9 @@ pthread_handler_t handle_delayed_insert(
 #if !defined( __WIN__) /* Win32 calls this in pthread_create */
   if (my_thread_init())
   {
-    strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
+    /* Can't use my_error since store_globals has not yet been called */
+    thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
+                                  ER(ER_OUT_OF_RESOURCES));
     goto end;
   }
 #endif
@@ -2264,8 +2266,10 @@ pthread_handler_t handle_delayed_insert(
   thd->thread_stack= (char*) &thd;
   if (init_thr_lock() || thd->store_globals())
   {
+    /* Can't use my_error since store_globals has perhaps failed */
+    thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
+                                  ER(ER_OUT_OF_RESOURCES));
     thd->fatal_error();
-    strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
     goto err;
   }
 
@@ -2653,7 +2657,7 @@ bool Delayed_insert::handle_inserts(void
 	{
 	  /* This should never happen */
 	  table->file->print_error(error,MYF(0));
-	  sql_print_error("%s",thd.net.last_error);
+	  sql_print_error("%s", thd.main_da.message());
           DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed in loop"));
 	  goto err;
 	}
@@ -2694,7 +2698,7 @@ bool Delayed_insert::handle_inserts(void
   if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
   {						// This shouldn't happen
     table->file->print_error(error,MYF(0));
-    sql_print_error("%s",thd.net.last_error);
+    sql_print_error("%s", thd.main_da.message());
     DBUG_PRINT("error", ("HA_EXTRA_NO_CACHE failed after loop"));
     goto err;
   }
@@ -3013,7 +3017,7 @@ bool select_insert::send_data(List<Item>
   thd->count_cuted_fields= CHECK_FIELD_WARN;	// Calculate cuted fields
   store_values(values);
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-  if (thd->net.report_error)
+  if (thd->is_error())
     DBUG_RETURN(1);
   if (table_list)                               // Not CREATE ... SELECT
   {
@@ -3157,7 +3161,7 @@ bool select_insert::send_eof()
     (thd->arg_of_last_insert_id_function ?
      thd->first_successful_insert_id_in_prev_stmt :
      (info.copied ? autoinc_value_of_last_inserted_row : 0));
-  ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+  my_ok(thd, (ulong) thd->row_count_func, id, buff);
   DBUG_RETURN(0);
 }
 
diff -Nrup a/sql/sql_load.cc b/sql/sql_load.cc
--- a/sql/sql_load.cc	2007-07-30 20:02:19 +04:00
+++ b/sql/sql_load.cc	2007-10-30 14:54:55 +03:00
@@ -502,7 +502,7 @@ bool mysql_load(THD *thd,sql_exchange *e
     error=ha_autocommit_or_rollback(thd,error);
 
   /* ok to client sent only after binlog write and engine commit */
-  send_ok(thd, info.copied + info.deleted, 0L, name);
+  my_ok(thd, info.copied + info.deleted, 0L, name);
 err:
   DBUG_ASSERT(transactional_table || !(info.copied || info.deleted) ||
               thd->transaction.stmt.modified_non_trans_table);
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc	2007-10-11 04:07:20 +04:00
+++ b/sql/sql_parse.cc	2007-10-30 14:54:55 +03:00
@@ -226,24 +226,24 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
   sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
 
-  sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_TRIGGERS]=    CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_EVENTS]=      CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_PLUGINS]=     CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_TRIGGERS]=    CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_EVENTS]=      CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_PLUGINS]=     CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
+  sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
   sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND |
CF_RETURNS_RESULT_SET;
   sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
@@ -261,15 +261,17 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_SHOW_CREATE_PROC]=  CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]=  CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]=  CF_STATUS_COMMAND;
-  sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]=  CF_STATUS_COMMAND;
+  sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]=  CF_STATUS_COMMAND | CF_RETURNS_RESULT_SET;
   sql_command_flags[SQLCOM_SHOW_PROC_CODE]=  CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_FUNC_CODE]=  CF_STATUS_COMMAND;
   sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]=  CF_STATUS_COMMAND;
 
    sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
-                                               CF_SHOW_TABLE_COMMAND);
+                                               CF_SHOW_TABLE_COMMAND |
+                                               CF_RETURNS_RESULT_SET);
   sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
-                                                CF_SHOW_TABLE_COMMAND);
+                                                CF_SHOW_TABLE_COMMAND |
+                                                CF_RETURNS_RESULT_SET);
 
   /*
     The following is used to preserver CF_ROW_COUNT during the
@@ -287,6 +289,9 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_REPAIR]=           CF_WRITE_LOGS_COMMAND;
   sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
   sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
+
+  sql_command_flags[SQLCOM_SELECT]=           CF_RETURNS_RESULT_SET;
+
 }
 
 
@@ -328,7 +333,6 @@ void execute_init_command(THD *thd, sys_
   */
   save_vio= thd->net.vio;
   thd->net.vio= 0;
-  thd->net.no_send_error= 0;
   dispatch_command(COM_QUERY, thd,
                    init_command_var->value,
                    init_command_var->value_length);
@@ -397,8 +401,8 @@ pthread_handler_t handle_bootstrap(void 
       /* purecov: begin tested */
       if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
       {
-        net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
-        thd->fatal_error();
+        net_end_statement(thd);
+        bootstrap_error= 1;
         break;
       }
       buff= (char*) thd->net.buff;
@@ -406,7 +410,7 @@ pthread_handler_t handle_bootstrap(void 
       length+= (ulong) strlen(buff + length);
       /* purecov: end */
     }
-    if (thd->is_fatal_error)
+    if (bootstrap_error)
       break;                                    /* purecov: inspected */
 
     while (length && (my_isspace(thd->charset(), buff[length-1]) ||
@@ -430,19 +434,16 @@ pthread_handler_t handle_bootstrap(void 
     */
     thd->query_id=next_query_id();
     thd->set_time();
+    mysql_reset_thd_for_next_command(thd);
     mysql_parse(thd, thd->query, length, & found_semicolon);
-    close_thread_tables(thd);			// Free tables
 
-    if (thd->is_fatal_error)
-      break;
+    bootstrap_error= thd->is_error();
+    net_end_statement(thd);
 
-    if (thd->net.report_error)
-    {
-      /* The query failed, send error to log and abort bootstrap */
-      net_send_error(thd);
-      thd->fatal_error();
+    close_thread_tables(thd);			// Free tables
+
+    if (bootstrap_error)
       break;
-    }
 
     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 #ifdef USING_TRANSACTIONS
@@ -451,9 +452,6 @@ pthread_handler_t handle_bootstrap(void 
   }
 
 end:
-  /* Remember the exit code of bootstrap */
-  bootstrap_error= thd->is_fatal_error;
-
   net_end(&thd->net);
   thd->cleanup();
   delete thd;
@@ -672,7 +670,8 @@ bool do_command(THD *thd)
   */
   my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
 
-  thd->clear_error();				// Clear error message
+  thd->clear_error(); // Clear a possible message
+  thd->main_da.reset_diagnostics_area();
 
   net_new_transaction(net);
   if ((packet_length=my_net_read(net)) == packet_error)
@@ -683,10 +682,13 @@ bool do_command(THD *thd)
 
     /* Check if we can continue without closing the connection */
 
+    /* The error must be set */
+    DBUG_ASSERT(thd->is_error());
+    net_end_statement(thd);
+
     if (net->error != 3)
       DBUG_RETURN(TRUE);			// We have to close it.
 
-    net_send_error(thd, net->last_errno, NullS);
     net->error= 0;
     DBUG_RETURN(FALSE);
   }
@@ -770,9 +772,11 @@ bool dispatch_command(enum enum_server_c
   thread_running++;
   /* TODO: set thd->lex->sql_command to SQLCOM_END here */
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
+  mysql_reset_thd_for_next_command(thd);
 
   thd->server_status&=
            ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
+
   switch (command) {
   case COM_INIT_DB:
   {
@@ -783,7 +787,7 @@ bool dispatch_command(enum enum_server_c
     if (!mysql_change_db(thd, &tmp, FALSE))
     {
       general_log_print(thd, command, "%s",thd->db);
-      send_ok(thd);
+      my_ok(thd);
     }
     break;
   }
@@ -791,7 +795,7 @@ bool dispatch_command(enum enum_server_c
   case COM_REGISTER_SLAVE:
   {
     if (!register_slave(thd, (uchar*)packet, packet_length))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
 #endif
@@ -825,7 +829,8 @@ bool dispatch_command(enum enum_server_c
     db.length= db_len;
     tbl_name= strmake(db.str, packet + 1, db_len)+1;
     strmake(tbl_name, packet + db_len + 2, tbl_len);
-    mysql_table_dump(thd, &db, tbl_name);
+    if (mysql_table_dump(thd, &db, tbl_name) == 0)
+      thd->main_da.disable_status();
     break;
   }
   case COM_CHANGE_USER:
@@ -915,11 +920,6 @@ bool dispatch_command(enum enum_server_c
 
     if (res)
     {
-      /* authentication failure, we shall restore old user */
-      if (res > 0)
-        my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-      else
-        thd->clear_error();                     // Error already sent to client
       x_free(thd->security_ctx->user);
       *thd->security_ctx= save_security_ctx;
       thd->user_connect= save_user_connect;
@@ -991,10 +991,12 @@ bool dispatch_command(enum enum_server_c
 
     mysql_parse(thd, thd->query, thd->query_length, & found_semicolon);
 
-    while (!thd->killed && found_semicolon &&
!thd->net.report_error)
+    while (!thd->killed && found_semicolon && !thd->is_error())
     {
       char *next_packet= (char*) found_semicolon;
-      net->no_send_error= 0;
+
+      net_end_statement(thd);
+      query_cache_end_of_result(thd);
       /*
         Multiple queries exits, execute them individually
       */
@@ -1018,6 +1020,7 @@ bool dispatch_command(enum enum_server_c
       thd->set_time(); /* Reset the query start time. */
       /* TODO: set thd->lex->sql_command to SQLCOM_END here */
       VOID(pthread_mutex_unlock(&LOCK_thread_count));
+      mysql_reset_thd_for_next_command(thd);
       mysql_parse(thd, next_packet, length, & found_semicolon);
     }
 
@@ -1078,7 +1081,6 @@ bool dispatch_command(enum enum_server_c
     table_list.select_lex= &(thd->lex->select_lex);
 
     lex_start(thd);
-    mysql_reset_thd_for_next_command(thd);
 
     thd->lex->
       select_lex.table_list.link_in_list((uchar*) &table_list,
@@ -1097,6 +1099,7 @@ bool dispatch_command(enum enum_server_c
     /* We don't calculate statistics for this command */
     general_log_print(thd, command, NullS);
     net->error=0;				// Don't give 'abort' message
+    thd->main_da.disable_status();              // Don't send anything back
     error=TRUE;					// End server
     break;
 
@@ -1186,7 +1189,7 @@ bool dispatch_command(enum enum_server_c
       break;
     general_log_print(thd, command, NullS);
     if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
 #ifndef EMBEDDED_LIBRARY
@@ -1212,17 +1215,7 @@ bool dispatch_command(enum enum_server_c
     }
     DBUG_PRINT("quit",("Got shutdown command for level %u", level));
     general_log_print(thd, command, NullS);
-    send_eof(thd);
-#ifdef __WIN__
-    sleep(1);					// must wait after eof()
-#endif
-    /*
-      The client is next going to send a COM_QUIT request (as part of
-      mysql_close()). Make the life simpler for the client by sending
-      the response for the coming COM_QUIT in advance
-    */
-    send_eof(thd);
-    close_connection(thd, 0, 1);
+    my_eof(thd);
     close_thread_tables(thd);			// Free before kill
     kill_mysql();
     error=TRUE;
@@ -1235,13 +1228,8 @@ bool dispatch_command(enum enum_server_c
     ulong uptime;
     uint length;
     ulonglong queries_per_second1000;
-#ifndef EMBEDDED_LIBRARY
     char buff[250];
     uint buff_len= sizeof(buff);
-#else
-    char *buff= thd->net.last_error;
-    uint buff_len= sizeof(thd->net.last_error);
-#endif
 
     general_log_print(thd, command, NullS);
     status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
@@ -1263,6 +1251,10 @@ bool dispatch_command(enum enum_server_c
                         cached_open_tables(),
                         (uint) (queries_per_second1000 / 1000),
                         (uint) (queries_per_second1000 % 1000));
+#ifdef EMBEDDED_LIBRARY
+    /* Store the buffer in permanent memory */
+    thd->main_da.set_success_status(thd, 0, 0, buff);
+#endif
 #ifdef SAFEMALLOC
     if (sf_malloc_cur_memory)				// Using SAFEMALLOC
     {
@@ -1275,13 +1267,14 @@ bool dispatch_command(enum enum_server_c
 #endif
 #ifndef EMBEDDED_LIBRARY
     VOID(my_net_write(net, (uchar*) buff, length));
-      VOID(net_flush(net));
+    VOID(net_flush(net));
+    thd->main_da.disable_status();
 #endif
     break;
   }
   case COM_PING:
     status_var_increment(thd->status_var.com_other);
-    send_ok(thd);				// Tell client we are alive
+    my_ok(thd);
     break;
   case COM_PROCESS_INFO:
     status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
@@ -1308,11 +1301,11 @@ bool dispatch_command(enum enum_server_c
     switch (opt_command) {
     case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
       thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
-      send_eof(thd);
+      my_eof(thd);
       break;
     case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
       thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
-      send_eof(thd);
+      my_eof(thd);
       break;
     default:
       my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
@@ -1326,7 +1319,7 @@ bool dispatch_command(enum enum_server_c
       break;					/* purecov: inspected */
     mysql_print_status();
     general_log_print(thd, command, NullS);
-    send_eof(thd);
+    my_eof(thd);
     break;
   case COM_SLEEP:
   case COM_CONNECT:				// Impossible here
@@ -1356,10 +1349,11 @@ bool dispatch_command(enum enum_server_c
     thd->transaction.xid_state.xid.null();
 
   /* report error issued during command execution */
-  if (thd->killed_errno() && !thd->net.report_error)
+  if (thd->killed_errno() && !thd->main_da.is_set())
     thd->send_kill_message();
-  if (thd->net.report_error)
-    net_send_error(thd);
+
+  net_end_statement(thd);
+  query_cache_end_of_result(thd);
 
   log_slow_statement(thd);
 
@@ -1729,7 +1723,6 @@ mysql_execute_command(THD *thd)
   SELECT_LEX_UNIT *unit= &lex->unit;
   /* Saved variable value */
   DBUG_ENTER("mysql_execute_command");
-  thd->net.no_send_error= 0;
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   thd->work_part_info= 0;
 #endif
@@ -1942,7 +1935,7 @@ mysql_execute_command(THD *thd)
     break;
 
   case SQLCOM_EMPTY_QUERY:
-    send_ok(thd);
+    my_ok(thd);
     break;
 
   case SQLCOM_HELP:
@@ -2145,7 +2138,7 @@ mysql_execute_command(THD *thd)
     if (!fetch_master_table(thd, first_table->db, first_table->table_name,
 			    active_mi, 0, 0))
     {
-      send_ok(thd);
+      my_ok(thd);
     }
     pthread_mutex_unlock(&LOCK_active_mi);
     break;
@@ -2343,7 +2336,7 @@ mysql_execute_command(THD *thd)
                                 &alter_info, 0, 0);
       }
       if (!res)
-	send_ok(thd);
+        my_ok(thd);
     }
 
     /* put tables back for PS rexecuting */
@@ -3020,7 +3013,7 @@ end_with_restore_list:
     LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
     if (!mysql_change_db(thd, &db_str, FALSE))
-      send_ok(thd);
+      my_ok(thd);
 
     break;
   }
@@ -3069,7 +3062,7 @@ end_with_restore_list:
         about the ONE_SHOT property of that SET. So we use a |= instead of = .
       */
       thd->one_shot_set|= lex->one_shot_set;
-      send_ok(thd);
+      my_ok(thd);
     }
     break;
   }
@@ -3089,7 +3082,7 @@ end_with_restore_list:
     }
     if (thd->global_read_lock)
       unlock_global_read_lock(thd);
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_LOCK_TABLES:
     unlock_locked_tables(thd);
@@ -3109,7 +3102,7 @@ end_with_restore_list:
 #endif /*HAVE_QUERY_CACHE*/
       thd->locked_tables=thd->lock;
       thd->lock=0;
-      send_ok(thd);
+      my_ok(thd);
     }
     else
     {
@@ -3246,7 +3239,7 @@ end_with_restore_list:
 
     res= mysql_upgrade_db(thd, db);
     if (!res)
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
   case SQLCOM_ALTER_DB:
@@ -3331,7 +3324,7 @@ end_with_restore_list:
     }
     DBUG_PRINT("info",("DDL error code=%d", res));
     if (!res)
-      send_ok(thd);
+      my_ok(thd);
 
   } while (0);
   /* Don't do it, if we are inside a SP */
@@ -3350,7 +3343,7 @@ end_with_restore_list:
     if (!(res= Events::drop_event(thd,
                                   lex->spname->m_db, lex->spname->m_name,
                                   lex->drop_if_exists)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   case SQLCOM_CREATE_FUNCTION:                  // UDF function
   {
@@ -3364,7 +3357,7 @@ end_with_restore_list:
       goto error;
     }
     if (!(res = mysql_create_function(thd, &lex->udf)))
-      send_ok(thd);
+      my_ok(thd);
 #else
     my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
     res= TRUE;
@@ -3381,7 +3374,7 @@ end_with_restore_list:
       goto error;
     /* Conditionally writes to binlog */
     if (!(res= mysql_create_user(thd, lex->users_list)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
   case SQLCOM_DROP_USER:
@@ -3393,7 +3386,7 @@ end_with_restore_list:
       goto error;
     /* Conditionally writes to binlog */
     if (!(res= mysql_drop_user(thd, lex->users_list)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
   case SQLCOM_RENAME_USER:
@@ -3405,7 +3398,7 @@ end_with_restore_list:
       goto error;
     /* Conditionally writes to binlog */
     if (!(res= mysql_rename_user(thd, lex->users_list)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
   case SQLCOM_REVOKE_ALL:
@@ -3417,7 +3410,7 @@ end_with_restore_list:
       break;
     /* Conditionally writes to binlog */
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   }
   case SQLCOM_REVOKE:
@@ -3554,7 +3547,7 @@ end_with_restore_list:
       {
         write_bin_log(thd, FALSE, thd->query, thd->query_length);
       }
-      send_ok(thd);
+      my_ok(thd);
     } 
     
     break;
@@ -3626,19 +3619,19 @@ end_with_restore_list:
     }
     if (begin_trans(thd))
       goto error;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_COMMIT:
     if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
                               lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
       goto error;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_ROLLBACK:
     if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
                               lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
       goto error;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_RELEASE_SAVEPOINT:
   {
@@ -3655,7 +3648,7 @@ end_with_restore_list:
       if (ha_release_savepoint(thd, sv))
         res= TRUE; // cannot happen
       else
-        send_ok(thd);
+        my_ok(thd);
       thd->transaction.savepoints=sv->prev;
     }
     else
@@ -3684,7 +3677,7 @@ end_with_restore_list:
           push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                        ER_WARNING_NOT_COMPLETE_ROLLBACK,
                        ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
-        send_ok(thd);
+        my_ok(thd);
       }
       thd->transaction.savepoints=sv;
     }
@@ -3695,7 +3688,7 @@ end_with_restore_list:
   case SQLCOM_SAVEPOINT:
     if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
           thd->in_sub_stmt) || !opt_using_transactions)
-      send_ok(thd);
+      my_ok(thd);
     else
     {
       SAVEPOINT **sv, *newsv;
@@ -3732,7 +3725,7 @@ end_with_restore_list:
       {
         newsv->prev=thd->transaction.savepoints;
         thd->transaction.savepoints=newsv;
-        send_ok(thd);
+        my_ok(thd);
       }
     }
     break;
@@ -3830,7 +3823,7 @@ end_with_restore_list:
 create_sp_error:
     if (sp_result != SP_OK )
       goto error;
-    send_ok(thd);
+    my_ok(thd);
     break; /* break super switch */
   } /* end case group bracket */
   case SQLCOM_CALL:
@@ -3874,8 +3867,6 @@ create_sp_error:
             goto error;
         }
 
-	my_bool save_no_send_ok= thd->net.no_send_ok;
-	thd->net.no_send_ok= TRUE;
 	if (sp->m_flags & sp_head::MULTI_RESULTS)
 	{
 	  if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
@@ -3885,7 +3876,6 @@ create_sp_error:
               back
             */
 	    my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
-	    thd->net.no_send_ok= save_no_send_ok;
 	    goto error;
 	  }
           /*
@@ -3901,7 +3891,6 @@ create_sp_error:
 	if (check_routine_access(thd, EXECUTE_ACL,
 				 sp->m_db.str, sp->m_name.str, TRUE, FALSE))
 	{
-	  thd->net.no_send_ok= save_no_send_ok;
 	  goto error;
 	}
 #endif
@@ -3926,15 +3915,17 @@ create_sp_error:
 
 	thd->variables.select_limit= select_limit;
 
-	thd->net.no_send_ok= save_no_send_ok;
         thd->server_status&= ~bits_to_be_cleared;
 
-	if (!res)
-	  send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
-                                thd->row_count_func));
+        if (!res)
+        {
+          my_ok(thd, (ulong)
+                (thd->row_count_func < 0 ?  0 : thd->row_count_func),
+                0, 0);
+        }
 	else
         {
-          DBUG_ASSERT(thd->net.report_error == 1 || thd->killed);
+          DBUG_ASSERT(thd->is_error() == 1 || thd->killed);
 	  goto error;		// Substatement should already have sent error
         }
       }
@@ -4008,7 +3999,7 @@ create_sp_error:
       switch (sp_result)
       {
       case SP_OK:
-	send_ok(thd);
+        my_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
 	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4073,7 +4064,7 @@ create_sp_error:
 
 	    if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
 	    {
-	      send_ok(thd);
+              my_ok(thd);
 	      break;
 	    }
 	  }
@@ -4090,7 +4081,7 @@ create_sp_error:
       res= sp_result;
       switch (sp_result) {
       case SP_OK:
-	send_ok(thd);
+        my_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
 	if (lex->drop_if_exists)
@@ -4099,7 +4090,7 @@ create_sp_error:
 			      ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
 			      SP_COM_STRING(lex), lex->spname->m_name.str);
 	  res= FALSE;
-	  send_ok(thd);
+          my_ok(thd);
 	  break;
 	}
 	my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
@@ -4231,7 +4222,7 @@ create_sp_error:
         break;
       }
       thd->transaction.xid_state.xa_state=XA_ACTIVE;
-      send_ok(thd);
+      my_ok(thd);
       break;
     }
     if (thd->lex->xa_opt != XA_NONE)
@@ -4262,7 +4253,7 @@ create_sp_error:
     thd->transaction.all.modified_non_trans_table= FALSE;
     thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
     thd->server_status|= SERVER_STATUS_IN_TRANS;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_XA_END:
     /* fake it */
@@ -4283,7 +4274,7 @@ create_sp_error:
       break;
     }
     thd->transaction.xid_state.xa_state=XA_IDLE;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_XA_PREPARE:
     if (thd->transaction.xid_state.xa_state != XA_IDLE)
@@ -4305,7 +4296,7 @@ create_sp_error:
       break;
     }
     thd->transaction.xid_state.xa_state=XA_PREPARED;
-    send_ok(thd);
+    my_ok(thd);
     break;
   case SQLCOM_XA_COMMIT:
     if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
@@ -4317,7 +4308,7 @@ create_sp_error:
       {
         ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
         xid_cache_delete(xs);
-        send_ok(thd);
+        my_ok(thd);
       }
       break;
     }
@@ -4328,7 +4319,7 @@ create_sp_error:
       if ((r= ha_commit(thd)))
         my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
       else
-        send_ok(thd);
+        my_ok(thd);
     }
     else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
              thd->lex->xa_opt == XA_NONE)
@@ -4343,7 +4334,7 @@ create_sp_error:
         if (ha_commit_one_phase(thd, 1))
           my_error(ER_XAER_RMERR, MYF(0));
         else
-          send_ok(thd);
+          my_ok(thd);
         start_waiting_global_read_lock(thd);
       }
     }
@@ -4369,7 +4360,7 @@ create_sp_error:
       {
         ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
         xid_cache_delete(xs);
-        send_ok(thd);
+        my_ok(thd);
       }
       break;
     }
@@ -4383,7 +4374,7 @@ create_sp_error:
     if (ha_rollback(thd))
       my_error(ER_XAER_RMERR, MYF(0));
     else
-      send_ok(thd);
+      my_ok(thd);
     thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
     thd->transaction.all.modified_non_trans_table= FALSE;
     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
@@ -4397,16 +4388,16 @@ create_sp_error:
     if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ?
is_schema_db(thd->db) : 0))
       break;
     if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   case SQLCOM_INSTALL_PLUGIN:
     if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
                                      &thd->lex->ident)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   case SQLCOM_UNINSTALL_PLUGIN:
     if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
-      send_ok(thd);
+      my_ok(thd);
     break;
   case SQLCOM_BINLOG_BASE64_EVENT:
   {
@@ -4433,7 +4424,7 @@ create_sp_error:
       my_error(error, MYF(0), lex->server_options.server_name);
       break;
     }
-    send_ok(thd, 1);
+    my_ok(thd, 1);
     break;
   }
   case SQLCOM_ALTER_SERVER:
@@ -4452,7 +4443,7 @@ create_sp_error:
       my_error(error, MYF(0), lex->server_options.server_name);
       break;
     }
-    send_ok(thd, 1);
+    my_ok(thd, 1);
     break;
   }
   case SQLCOM_DROP_SERVER:
@@ -4474,18 +4465,18 @@ create_sp_error:
       }
       else
       {
-        send_ok(thd, 0);
+        my_ok(thd);
       }
       break;
     }
-    send_ok(thd, 1);
+    my_ok(thd, 1);
     break;
   }
   default:
 #ifndef EMBEDDED_LIBRARY
     DBUG_ASSERT(0);                             /* Impossible */
 #endif
-    send_ok(thd);
+    my_ok(thd);
     break;
   }
 
@@ -4527,7 +4518,7 @@ finish:
     */
     start_waiting_global_read_lock(thd);
   }
-  DBUG_RETURN(res || thd->net.report_error);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 
@@ -4567,7 +4558,8 @@ static bool execute_sqlcom_select(THD *t
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                      ER_YES, str.ptr());
       }
-      result->send_eof();
+      if (!res)
+        result->send_eof();
       delete result;
     }
     else
@@ -5240,18 +5232,19 @@ void mysql_reset_thd_for_next_command(TH
   }
   DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
   thd->thread_specific_used= FALSE;
-  if (!thd->in_sub_stmt)
+  DBUG_ASSERT (!thd->in_sub_stmt);
+
+  if (opt_bin_log)
   {
-    if (opt_bin_log)
-    {
-      reset_dynamic(&thd->user_var_events);
-      thd->user_var_events_alloc= thd->mem_root;
-    }
-    thd->clear_error();
-    thd->total_warn_count=0;			// Warnings for this query
-    thd->rand_used= 0;
-    thd->sent_row_count= thd->examined_row_count= 0;
+    reset_dynamic(&thd->user_var_events);
+    thd->user_var_events_alloc= thd->mem_root;
   }
+  thd->clear_error();
+  thd->total_warn_count=0;			// Warnings for this query
+  thd->rand_used= 0;
+  thd->sent_row_count= thd->examined_row_count= 0;
+  thd->main_da.reset_diagnostics_area();
+
   /*
     Because we come here only for start of top-statements, binlog format is
     constant inside a complex statement (using stored functions) etc.
@@ -5446,7 +5439,6 @@ void mysql_parse(THD *thd, const char *i
     FIXME: cleanup the dependencies in the code to simplify this.
   */
   lex_start(thd);
-  mysql_reset_thd_for_next_command(thd);
 
   if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
   {
@@ -5471,7 +5463,7 @@ void mysql_parse(THD *thd, const char *i
       else
 #endif
       {
-	if (! thd->net.report_error)
+	if (! thd->is_error())
 	{
           /*
             Binlog logs a string starting from thd->query and having length
@@ -5489,13 +5481,12 @@ void mysql_parse(THD *thd, const char *i
           /* Actually execute the query */
           lex->set_trg_event_type_for_tables();
           mysql_execute_command(thd);
-          query_cache_end_of_result(thd);
 	}
       }
     }
     else
     {
-      DBUG_ASSERT(thd->net.report_error);
+      DBUG_ASSERT(thd->is_error());
       DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
 			 thd->is_fatal_error));
 
@@ -5540,7 +5531,6 @@ bool mysql_test_parse_for_slave(THD *thd
 
   Lex_input_stream lip(thd, inBuf, length);
   lex_start(thd);
-  mysql_reset_thd_for_next_command(thd);
 
   if (!parse_sql(thd, &lip, NULL) &&
       all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
@@ -6310,7 +6300,7 @@ void add_join_natural(TABLE_LIST *a, TAB
 
   RETURN
     0	 ok
-    !=0  error.  thd->killed or thd->net.report_error is set
+    !=0  error.  thd->killed or thd->is_error() is set
 */
 
 bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
@@ -6455,7 +6445,6 @@ bool reload_acl_and_cache(THD *thd, ulon
     if (reset_master(thd))
     {
       result=1;
-      thd->fatal_error();                       // Ensure client get error
     }
   }
 #endif
@@ -6546,7 +6535,7 @@ void sql_kill(THD *thd, ulong id, bool o
 {
   uint error;
   if (!(error= kill_one_thread(thd, id, only_kill_query)))
-    send_ok(thd);
+    my_ok(thd);
   else
     my_error(error, MYF(0), id);
 }
@@ -7273,10 +7262,10 @@ bool parse_sql(THD *thd,
 
   bool mysql_parse_status= MYSQLparse(thd) != 0;
 
-  /* Check that if MYSQLparse() failed, thd->net.report_error is set. */
+  /* Check that if MYSQLparse() failed, thd->is_error() is set. */
 
   DBUG_ASSERT(!mysql_parse_status ||
-              mysql_parse_status && thd->net.report_error);
+              mysql_parse_status && thd->is_error());
 
   /* Reset Lex_input_stream. */
 
diff -Nrup a/sql/sql_partition.cc b/sql/sql_partition.cc
--- a/sql/sql_partition.cc	2007-09-14 14:17:40 +04:00
+++ b/sql/sql_partition.cc	2007-10-30 14:54:55 +03:00
@@ -2049,6 +2049,7 @@ char *generate_partition_syntax(partitio
       DBUG_ASSERT(0);
       /* We really shouldn't get here, no use in continuing from here */
       current_thd->fatal_error();
+      my_error(ER_UNKNOWN_ERROR, MYF(0));
       DBUG_RETURN(NULL);
   }
   if (part_info->part_expr)
@@ -3960,7 +3961,7 @@ static int fast_end_partition(THD *thd, 
                 (ulong) (copied + deleted),
                 (ulong) deleted,
                 (ulong) 0);
-    send_ok(thd, (ha_rows) (copied+deleted),0L,tmp_name);
+    my_ok(thd, (ha_rows) (copied+deleted), 0L, tmp_name);
     DBUG_RETURN(FALSE);
   }
   table->file->print_error(error, MYF(0));
@@ -5084,7 +5085,9 @@ static bool mysql_change_partitions(ALTE
     if (error != ER_OUTOFMEMORY)
       file->print_error(error, MYF(0));
     else
+    {
       lpt->thd->fatal_error();
+    }
     DBUG_RETURN(TRUE);
   }
   DBUG_RETURN(FALSE);
diff -Nrup a/sql/sql_prepare.cc b/sql/sql_prepare.cc
--- a/sql/sql_prepare.cc	2007-09-28 15:42:35 +04:00
+++ b/sql/sql_prepare.cc	2007-10-30 14:54:55 +03:00
@@ -230,6 +230,7 @@ static bool send_prep_stmt(Prepared_stat
   NET *net= &stmt->thd->net;
   uchar buff[12];
   uint tmp;
+  int res;
   DBUG_ENTER("send_prep_stmt");
 
   buff[0]= 0;                                   /* OK packet indicator */
@@ -244,11 +245,14 @@ static bool send_prep_stmt(Prepared_stat
     Send types and names of placeholders to the client
     XXX: fix this nasty upcast from List<Item_param> to List<Item>
   */
-  DBUG_RETURN(my_net_write(net, buff, sizeof(buff)) ||
-              (stmt->param_count &&
-               stmt->thd->protocol_text.send_fields((List<Item> *)
-                                                    &stmt->lex->param_list,
-                                                    Protocol::SEND_EOF)));
+  res= my_net_write(net, buff, sizeof(buff)) ||
+       (stmt->param_count &&
+        stmt->thd->protocol_text.send_fields((List<Item> *)
+                                             &stmt->lex->param_list,
+                                             Protocol::SEND_EOF));
+  /** Flag that a response has already been sent */
+  stmt->thd->main_da.disable_status();
+  DBUG_RETURN(res);
 }
 #else
 static bool send_prep_stmt(Prepared_statement *stmt,
@@ -259,6 +263,7 @@ static bool send_prep_stmt(Prepared_stat
   thd->client_stmt_id= stmt->id;
   thd->client_param_count= stmt->param_count;
   thd->clear_error();
+  thd->main_da.disable_status();
 
   return 0;
 }
@@ -1907,9 +1912,6 @@ void mysql_stmt_prepare(THD *thd, const 
 
   DBUG_PRINT("prep_query", ("%s", packet));
 
-  /* First of all clear possible warnings from the previous command */
-  mysql_reset_thd_for_next_command(thd);
-
   if (! (stmt= new Prepared_statement(thd, &thd->protocol_binary)))
     DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
 
@@ -2113,7 +2115,7 @@ void mysql_sql_stmt_prepare(THD *thd)
     thd->stmt_map.erase(stmt);
   }
   else
-    send_ok(thd, 0L, 0L, "Statement prepared");
+    my_ok(thd, 0L, 0L, "Statement prepared");
 
   DBUG_VOID_RETURN;
 }
@@ -2278,9 +2280,6 @@ void mysql_stmt_execute(THD *thd, char *
 
   packet+= 9;                               /* stmt_id + 5 bytes of flags */
 
-  /* First of all clear possible warnings from the previous command */
-  mysql_reset_thd_for_next_command(thd);
-
   if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
     DBUG_VOID_RETURN;
 
@@ -2418,8 +2417,6 @@ void mysql_stmt_fetch(THD *thd, char *pa
   Server_side_cursor *cursor;
   DBUG_ENTER("mysql_stmt_fetch");
 
-  /* First of all clear possible warnings from the previous command */
-  mysql_reset_thd_for_next_command(thd);
   status_var_increment(thd->status_var.com_stmt_fetch);
   if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
     DBUG_VOID_RETURN;
@@ -2481,9 +2478,6 @@ void mysql_stmt_reset(THD *thd, char *pa
   Prepared_statement *stmt;
   DBUG_ENTER("mysql_stmt_reset");
 
-  /* First of all clear possible warnings from the previous command */
-  mysql_reset_thd_for_next_command(thd);
-
   status_var_increment(thd->status_var.com_stmt_reset);
   if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
     DBUG_VOID_RETURN;
@@ -2498,7 +2492,7 @@ void mysql_stmt_reset(THD *thd, char *pa
 
   stmt->state= Query_arena::PREPARED;
 
-  send_ok(thd);
+  my_ok(thd);
 
   DBUG_VOID_RETURN;
 }
@@ -2526,6 +2520,8 @@ void mysql_stmt_close(THD *thd, char *pa
   DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
   (void) stmt->deallocate();
 
+  thd->main_da.disable_status();
+
   DBUG_VOID_RETURN;
 }
 
@@ -2558,7 +2554,7 @@ void mysql_sql_stmt_close(THD *thd)
   }
 
   if (stmt->deallocate() == 0)
-    send_ok(thd);
+    my_ok(thd);
 }
 
 /*
@@ -2590,6 +2586,8 @@ void mysql_stmt_get_longdata(THD *thd, c
   DBUG_ENTER("mysql_stmt_get_longdata");
 
   status_var_increment(thd->status_var.com_stmt_send_long_data);
+
+  thd->main_da.disable_status();
 #ifndef EMBEDDED_LIBRARY
   /* Minimal size of long data packet is 6 bytes */
   if (packet_length < MYSQL_LONG_DATA_HEADER)
@@ -2665,10 +2663,7 @@ bool Select_fetch_protocol_binary::send_
 bool Select_fetch_protocol_binary::send_eof()
 {
   Protocol *save_protocol= thd->protocol;
-
-  thd->protocol= &protocol;
-  ::send_eof(thd);
-  thd->protocol= save_protocol;
+  my_eof(thd);
   return FALSE;
 }
 
@@ -2864,7 +2859,7 @@ bool Prepared_statement::prepare(const c
   lex_start(thd);
 
   error= parse_sql(thd, &lip, NULL) ||
-         thd->net.report_error ||
+         thd->is_error() ||
          init_param_array(this);
 
   lex->set_trg_event_type_for_tables();
@@ -3102,7 +3097,6 @@ bool Prepared_statement::execute(String 
                                           thd->query_length) <= 0)
     {
       error= mysql_execute_command(thd);
-      query_cache_end_of_result(thd);
     }
   }
 
diff -Nrup a/sql/sql_rename.cc b/sql/sql_rename.cc
--- a/sql/sql_rename.cc	2007-07-27 04:26:40 +04:00
+++ b/sql/sql_rename.cc	2007-10-30 14:54:55 +03:00
@@ -176,7 +176,7 @@ bool mysql_rename_tables(THD *thd, TABLE
   if (!silent && !error)
   {
     write_bin_log(thd, TRUE, thd->query, thd->query_length);
-    send_ok(thd);
+    my_ok(thd);
   }
 
   if (!error)
diff -Nrup a/sql/sql_repl.cc b/sql/sql_repl.cc
--- a/sql/sql_repl.cc	2007-08-16 10:52:44 +04:00
+++ b/sql/sql_repl.cc	2007-10-30 14:54:55 +03:00
@@ -252,7 +252,7 @@ bool purge_error_message(THD* thd, int r
     my_message(errmsg, ER(errmsg), MYF(0));
     return TRUE;
   }
-  send_ok(thd);
+  my_ok(thd);
   return FALSE;
 }
 
@@ -262,7 +262,7 @@ bool purge_master_logs(THD* thd, const c
   char search_file_name[FN_REFLEN];
   if (!mysql_bin_log.is_open())
   {
-    send_ok(thd);
+    my_ok(thd);
     return FALSE;
   }
 
@@ -277,7 +277,7 @@ bool purge_master_logs_before_date(THD* 
 {
   if (!mysql_bin_log.is_open())
   {
-    send_ok(thd);
+    my_ok(thd);
     return 0;
   }
   return purge_error_message(thd,
@@ -340,6 +340,8 @@ void mysql_binlog_send(THD* thd, char* l
 
   bzero((char*) &log,sizeof(log));
 
+  DBUG_ASSERT(thd->is_error() == 0);
+
 #ifndef DBUG_OFF
   if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2))
   {
@@ -735,7 +737,7 @@ end:
   end_io_cache(&log);
   (void)my_close(file, MYF(MY_WME));
 
-  send_eof(thd);
+  my_eof(thd);
   thd->proc_info = "Waiting to finalize termination";
   pthread_mutex_lock(&LOCK_thread_count);
   thd->current_linfo = 0;
@@ -881,7 +883,7 @@ int start_slave(THD* thd , Master_info* 
     DBUG_RETURN(1);
   }
   else if (net_report)
-    send_ok(thd);
+    my_ok(thd);
 
   DBUG_RETURN(0);
 }
@@ -933,7 +935,7 @@ int stop_slave(THD* thd, Master_info* mi
     DBUG_RETURN(1);
   }
   else if (net_report)
-    send_ok(thd);
+    my_ok(thd);
 
   DBUG_RETURN(0);
 }
@@ -1278,7 +1280,7 @@ bool change_master(THD* thd, Master_info
 
   unlock_slave_threads(mi);
   thd->proc_info = 0;
-  send_ok(thd);
+  my_ok(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -1445,7 +1447,7 @@ err:
     my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
              "SHOW BINLOG EVENTS", errmsg);
   else
-    send_eof(thd);
+    my_eof(thd);
 
   pthread_mutex_lock(&LOCK_thread_count);
   thd->current_linfo = 0;
@@ -1482,7 +1484,7 @@ bool show_binlog_info(THD* thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -1564,7 +1566,7 @@ bool show_binlogs(THD* thd)
       goto err;
   }
   mysql_bin_log.unlock_index();
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 
 err:
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc	2007-10-08 02:02:44 +04:00
+++ b/sql/sql_select.cc	2007-10-30 14:54:55 +03:00
@@ -122,7 +122,7 @@ static int do_select(JOIN *join,List<Ite
 
 static enum_nested_loop_state
 evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
-                     int error, my_bool *report_error);
+                     int error);
 static enum_nested_loop_state
 evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
 static enum_nested_loop_state
@@ -263,8 +263,8 @@ bool handle_select(THD *thd, LEX *lex, s
 		      result, unit, select_lex);
   }
   DBUG_PRINT("info",("res: %d  report_error: %d", res,
-		     thd->net.report_error));
-  res|= thd->net.report_error;
+		     thd->is_error()));
+  res|= thd->is_error();
   if (unlikely(res))
     result->abort();
 
@@ -491,7 +491,7 @@ JOIN::prepare(Item ***rref_pointer_array
 			 (having->fix_fields(thd, &having) ||
 			  having->check_cols(1)));
     select_lex->having_fix_field= 0;
-    if (having_fix_rc || thd->net.report_error)
+    if (having_fix_rc || thd->is_error())
       DBUG_RETURN(-1);				/* purecov: inspected */
     thd->lex->allow_sum_func= save_allow_sum_func;
   }
@@ -817,7 +817,7 @@ JOIN::optimize()
   }
 
   conds= optimize_cond(this, conds, join_list, &cond_value);   
-  if (thd->net.report_error)
+  if (thd->is_error())
   {
     error= 1;
     DBUG_PRINT("error",("Error from optimize_cond"));
@@ -826,7 +826,7 @@ JOIN::optimize()
 
   {
     having= optimize_cond(this, having, join_list, &having_value);
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       error= 1;
       DBUG_PRINT("error",("Error from optimize_cond"));
@@ -890,7 +890,6 @@ JOIN::optimize()
       }
       if (res > 1)
       {
-        thd->fatal_error();
         error= res;
         DBUG_PRINT("error",("Error from opt_sum_query"));
 	DBUG_RETURN(1);
@@ -1031,7 +1030,7 @@ JOIN::optimize()
   {
     ORDER *org_order= order;
     order=remove_const(this, order,conds,1, &simple_order);
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       error= 1;
       DBUG_PRINT("error",("Error from remove_const"));
@@ -1162,7 +1161,7 @@ JOIN::optimize()
     group_list= remove_const(this, (old_group_list= group_list), conds,
                              rollup.state == ROLLUP::STATE_NONE,
 			     &simple_group);
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       error= 1;
       DBUG_PRINT("error",("Error from remove_const"));
@@ -1185,7 +1184,7 @@ JOIN::optimize()
   {
     group_list= procedure->group= remove_const(this, procedure->group, conds,
 					       1, &simple_group);
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       error= 1;
       DBUG_PRINT("error",("Error from remove_const"));
@@ -1615,6 +1614,7 @@ JOIN::exec()
 		      (zero_result_cause?zero_result_cause:"No tables used"));
     else
     {
+      bool cond_result;
       result->send_fields(*columns_list,
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
       /*
@@ -1622,9 +1622,15 @@ JOIN::exec()
         even if we don't have any tables for prepared statements or if
         conds uses something like 'rand()'.
       */
-      if (cond_value != Item::COND_FALSE &&
-          (!conds || conds->val_int()) &&
-          (!having || having->val_int()))
+      cond_result= (cond_value != Item::COND_FALSE &&
+                    (!conds || conds->val_int()) &&
+                    (!having || having->val_int()));
+      if (thd->is_error())
+      {
+        result->abort();
+        error= 1;
+      }
+      else if (cond_result)
       {
 	if (do_send_rows &&
             (procedure ? (procedure->send_row(procedure_fields_list) ||
@@ -2098,10 +2104,10 @@ JOIN::exec()
       }
     }
   }
-  /* XXX: When can we have here thd->net.report_error not zero? */
-  if (thd->net.report_error)
+  /* XXX: When can we have here thd->is_error() not zero? */
+  if (thd->is_error())
   {
-    error= thd->net.report_error;
+    error= thd->is_error();
     DBUG_VOID_RETURN;
   }
   curr_join->having= curr_join->tmp_having;
@@ -2307,7 +2313,7 @@ mysql_select(THD *thd, Item ***rref_poin
     join->having_history= (join->having?join->having:join->tmp_having);
   }
 
-  if (thd->net.report_error)
+  if (thd->is_error())
     goto err;
 
   join->exec();
@@ -2333,7 +2339,7 @@ err:
   {
     thd->proc_info="end";
     err|= select_lex->cleanup();
-    DBUG_RETURN(err || thd->net.report_error);
+    DBUG_RETURN(err || thd->is_error());
   }
   DBUG_RETURN(join->error);
 }
@@ -9296,7 +9302,11 @@ Field *create_tmp_field(THD *thd, TABLE 
     Item_sum *item_sum=(Item_sum*) item;
     result= item_sum->create_tmp_field(group, table, convert_blob_length);
     if (!result)
+    {
+      DBUG_ASSERT(thd->is_error());
       thd->fatal_error();
+      my_error(ER_UNKNOWN_ERROR, MYF(0));
+    }
     return result;
   }
   case Item::FIELD_ITEM:
@@ -10710,7 +10720,7 @@ do_select(JOIN *join,List<Item> *fields,
     DBUG_PRINT("error",("Error: do_select() failed"));
   }
 #endif
-  DBUG_RETURN(join->thd->net.report_error ? -1 : rc);
+  DBUG_RETURN(join->thd->is_error() ? -1 : rc);
 }
 
 
@@ -10864,7 +10874,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
 
   int error;
   enum_nested_loop_state rc;
-  my_bool *report_error= &(join->thd->net.report_error);
   READ_RECORD *info= &join_tab->read_record;
 
   if (join->resume_nested_loop)
@@ -10896,13 +10905,13 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
     join->thd->row_count= 0;
 
     error= (*join_tab->read_first_record)(join_tab);
-    rc= evaluate_join_record(join, join_tab, error, report_error);
+    rc= evaluate_join_record(join, join_tab, error);
   }
 
   while (rc == NESTED_LOOP_OK)
   {
     error= info->read_record(info);
-    rc= evaluate_join_record(join, join_tab, error, report_error);
+    rc= evaluate_join_record(join, join_tab, error);
   }
 
   if (rc == NESTED_LOOP_NO_MORE_ROWS &&
@@ -10926,13 +10935,13 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
 
 static enum_nested_loop_state
 evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
-                     int error, my_bool *report_error)
+                     int error)
 {
   bool not_used_in_distinct=join_tab->not_used_in_distinct;
   ha_rows found_records=join->found_records;
   COND *select_cond= join_tab->select_cond;
 
-  if (error > 0 || (*report_error))				// Fatal error
+  if (error > 0 || join->thd->is_error())       // Fatal error
     return NESTED_LOOP_ERROR;
   if (error < 0)
     return NESTED_LOOP_NO_MORE_ROWS;
@@ -14411,6 +14420,7 @@ calc_group_buffer(JOIN *join,ORDER *grou
         /* This case should never be choosen */
         DBUG_ASSERT(0);
         join->thd->fatal_error();
+        my_error(ER_UNKNOWN_ERROR, MYF(0));
       }
     }
     parts++;
@@ -16020,7 +16030,7 @@ bool mysql_explain_union(THD *thd, SELEC
 			first->options | thd->options | SELECT_DESCRIBE,
 			result, unit, first);
   }
-  DBUG_RETURN(res || thd->net.report_error);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 
diff -Nrup a/sql/sql_servers.cc b/sql/sql_servers.cc
--- a/sql/sql_servers.cc	2007-08-13 17:11:14 +04:00
+++ b/sql/sql_servers.cc	2007-10-30 14:54:55 +03:00
@@ -238,7 +238,7 @@ bool servers_reload(THD *thd)
   if (simple_open_n_lock_tables(thd, tables))
   {
     sql_print_error("Can't open and lock privilege tables: %s",
-		    thd->net.last_error);
+		    thd->main_da.message());
     goto end;
   }
 
diff -Nrup a/sql/sql_show.cc b/sql/sql_show.cc
--- a/sql/sql_show.cc	2007-09-20 13:10:03 +04:00
+++ b/sql/sql_show.cc	2007-10-30 14:54:55 +03:00
@@ -222,7 +222,7 @@ bool mysqld_show_authors(THD *thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -256,7 +256,7 @@ bool mysqld_show_contributors(THD *thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -329,7 +329,7 @@ bool mysqld_show_privileges(THD *thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -417,7 +417,7 @@ bool mysqld_show_column_types(THD *thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -576,7 +576,8 @@ mysqld_show_create(THD *thd, TABLE_LIST 
   /* Only one table for now, but VIEW can involve several tables */
   if (open_normal_and_derived_tables(thd, table_list, 0))
   {
-    if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
+    if (!table_list->view ||
+        thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
       DBUG_RETURN(TRUE);
 
     /*
@@ -663,7 +664,7 @@ mysqld_show_create(THD *thd, TABLE_LIST 
   if (protocol->write())
     DBUG_RETURN(TRUE);
 
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -744,7 +745,7 @@ bool mysqld_show_create_db(THD *thd, cha
 
   if (protocol->write())
     DBUG_RETURN(TRUE);
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -784,10 +785,11 @@ mysqld_list_fields(THD *thd, TABLE_LIST 
   }
   restore_record(table, s->default_values);              // Get empty record
   table->use_all_columns();
-  if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
-                                              Protocol::SEND_EOF))
+  if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
     DBUG_VOID_RETURN;
-  thd->protocol->flush();
+
+  my_eof(thd);
+
   DBUG_VOID_RETURN;
 }
 
@@ -1736,7 +1738,7 @@ void mysqld_list_processes(THD *thd,cons
     if (protocol->write())
       break; /* purecov: inspected */
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_VOID_RETURN;
 }
 
@@ -2901,7 +2903,7 @@ static int fill_schema_table_names(THD *
     default:
       DBUG_ASSERT(0);
     }
-    if (thd->net.last_errno == ER_NO_SUCH_TABLE)
+    if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
     {
       thd->clear_error();
       return 0;
@@ -3246,7 +3248,15 @@ int get_all_tables(THD *thd, TABLE_LIST 
                                                 MYSQL_LOCK_IGNORE_FLUSH);
             lex->sql_command= save_sql_command;
             
-            if (thd->net.last_errno == ER_NO_SUCH_TABLE)
+            /*
+              XXX:  show_table_list has a flag i_is_requested object, 
+              and in this case open_normal_and_derived_tables can return
+              an error without setting an error message in THD, which
+              is a hack. This is why we have to check for res,
+              thd->is_error() only then for thd->main_da.sql_errno().
+            */
+            if (res && thd->is_error() &&
+                thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
             {
               /*
                 Hide error for not existing table.
@@ -3398,7 +3408,7 @@ static int get_schema_tables_record(THD 
     /*
       there was errors during opening tables
     */
-    const char *error= thd->net.last_error;
+    const char *error= thd->main_da.message();
     if (tables->view)
       table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
     else if (tables->schema_table)
@@ -3599,7 +3609,7 @@ static int get_schema_column_record(THD 
         rather than in SHOW COLUMNS
       */ 
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
       thd->clear_error();
       res= 0;
     }
@@ -4070,9 +4080,9 @@ static int get_schema_stat_record(THD *t
         I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
         rather than in SHOW KEYS
       */
-      if (thd->net.last_errno)
+      if (thd->is_error())
         push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                     thd->net.last_errno, thd->net.last_error);
+                     thd->main_da.sql_errno(), thd->main_da.message());
       thd->clear_error();
       res= 0;
     }
@@ -4262,9 +4272,9 @@ static int get_schema_views_record(THD *
 
     if (schema_table_store_record(thd, table))
       DBUG_RETURN(1);
-    if (res && thd->net.last_errno)
+    if (res && thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
   }
   if (res) 
     thd->clear_error();
@@ -4295,9 +4305,9 @@ static int get_schema_constraints_record
   DBUG_ENTER("get_schema_constraints_record");
   if (res)
   {
-    if (thd->net.last_errno)
+    if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -4400,9 +4410,9 @@ static int get_schema_triggers_record(TH
   */
   if (res)
   {
-    if (thd->net.last_errno)
+    if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -4483,9 +4493,9 @@ static int get_schema_key_column_usage_r
   DBUG_ENTER("get_schema_key_column_usage_record");
   if (res)
   {
-    if (thd->net.last_errno)
+    if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -4678,9 +4688,9 @@ static int get_schema_partitions_record(
 
   if (res)
   {
-    if (thd->net.last_errno)
+    if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -4724,6 +4734,7 @@ static int get_schema_partitions_record(
     default:
       DBUG_ASSERT(0);
       current_thd->fatal_error();
+      my_error(ER_OUT_OF_RESOURCES, MYF(0));
       DBUG_RETURN(1);
     }
     table->field[7]->set_notnull();
@@ -5215,9 +5226,9 @@ get_referential_constraints_record(THD *
 
   if (res)
   {
-    if (thd->net.last_errno)
+    if (thd->is_error())
       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   thd->net.last_errno, thd->net.last_error);
+                   thd->main_da.sql_errno(), thd->main_da.message());
     thd->clear_error();
     DBUG_RETURN(0);
   }
@@ -6717,7 +6728,7 @@ static bool show_create_trigger_impl(THD
   ret_code= p->write();
 
   if (!ret_code)
-    send_eof(thd);
+    my_eof(thd);
 
   return ret_code != 0;
 }
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc	2007-08-25 12:43:15 +04:00
+++ b/sql/sql_table.cc	2007-10-30 14:54:55 +03:00
@@ -434,7 +434,7 @@ static uint read_ddl_log_header()
 
   create_ddl_log_file_name(file_name);
   if ((global_ddl_log.file_id= my_open(file_name,
-                                        O_RDWR | O_BINARY, MYF(MY_WME))) >= 0)
+                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
   {
     if (read_ddl_log_file_entry(0UL))
     {
@@ -1461,7 +1461,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST 
 
   if (error)
     DBUG_RETURN(TRUE);
-  send_ok(thd);
+  my_ok(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -1648,7 +1648,10 @@ int mysql_rm_table_part2(THD *thd, TABLE
                              !dont_log_query);
       if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
 	  (if_exists || table_type == NULL))
+      {
 	error= 0;
+        thd->clear_error();
+      }
       if (error == HA_ERR_ROW_IS_REFERENCED)
       {
 	/* the table is referenced by a foreign key constraint */
@@ -4147,17 +4150,15 @@ static bool mysql_admin_table(THD* thd, 
           (table->table->file->ha_check_for_upgrade(check_opt) ==
            HA_ADMIN_NEEDS_ALTER))
       {
-        my_bool save_no_send_ok= thd->net.no_send_ok;
         ha_autocommit_or_rollback(thd, 1);
         close_thread_tables(thd);
         tmp_disable_binlog(thd); // binlogging is done by caller if wanted
-        thd->net.no_send_ok= TRUE;
         result_code= mysql_recreate_table(thd, table);
-        thd->net.no_send_ok= save_no_send_ok;
         reenable_binlog(thd);
+        if (!thd->is_error())
+          thd->main_da.reset_diagnostics_area();
         goto send_result;
       }
-
     }
 
     result_code = (table->table->file->*operator_func)(thd, check_opt);
@@ -4249,7 +4250,6 @@ send_result_message:
 
     case HA_ADMIN_TRY_ALTER:
     {
-      my_bool save_no_send_ok= thd->net.no_send_ok;
       /*
         This is currently used only by InnoDB. ha_innobase::optimize() answers
         "try with alter", so here we close the table, do an ALTER TABLE,
@@ -4261,9 +4261,7 @@ send_result_message:
                  *save_next_global= table->next_global;
       table->next_local= table->next_global= 0;
       tmp_disable_binlog(thd); // binlogging is done by caller if wanted
-      thd->net.no_send_ok= TRUE;
       result_code= mysql_recreate_table(thd, table);
-      thd->net.no_send_ok= save_no_send_ok;
       reenable_binlog(thd);
       ha_autocommit_or_rollback(thd, 0);
       close_thread_tables(thd);
@@ -4272,12 +4270,14 @@ send_result_message:
         if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
             ((result_code= table->table->file->analyze(thd, check_opt)) > 0))
           result_code= 0; // analyze went ok
+        /* Clear the 'OK' status from mysql_recreate_table. */
+        thd->main_da.reset_diagnostics_area();
       }
       if (result_code) // either mysql_recreate_table or analyze failed
       {
-        const char *err_msg;
-        if ((err_msg= thd->net.last_error))
+        if (thd->is_error())
         {
+          const char *err_msg= thd->main_da.message();
           if (!thd->vio_ok())
           {
             sql_print_error(err_msg);
@@ -4293,6 +4293,7 @@ send_result_message:
             protocol->store(table_name, system_charset_info);
             protocol->store(operator_name, system_charset_info);
           }
+          thd->clear_error();
         }
       }
       result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
@@ -4359,7 +4360,7 @@ send_result_message:
       goto err;
   }
 
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 
  err:
@@ -4843,7 +4844,7 @@ err:
   
   if (error == 0)
   {
-    send_ok(thd);
+    my_ok(thd);
     DBUG_RETURN(0);
   }
 
@@ -5806,7 +5807,7 @@ bool mysql_alter_table(THD *thd,char *ne
         Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
         mysql_bin_log.write(&qinfo);
       }
-      send_ok(thd);
+      my_ok(thd);
     }
 
     unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
@@ -6028,7 +6029,7 @@ view_err:
     if (!error)
     {
       write_bin_log(thd, TRUE, thd->query, thd->query_length);
-      send_ok(thd);
+      my_ok(thd);
     }
     else if (error > 0)
     {
@@ -6651,7 +6652,7 @@ end_temporary:
   my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 	      (ulong) (copied + deleted), (ulong) deleted,
 	      (ulong) thd->cuted_fields);
-  send_ok(thd, copied + deleted, 0L, tmp_name);
+  my_ok(thd, copied + deleted, 0L, tmp_name);
   thd->some_tables_deleted=0;
   DBUG_RETURN(FALSE);
 
@@ -7063,7 +7064,7 @@ bool mysql_checksum_table(THD *thd, TABL
       goto err;
   }
 
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 
  err:
diff -Nrup a/sql/sql_trigger.cc b/sql/sql_trigger.cc
--- a/sql/sql_trigger.cc	2007-09-05 02:50:03 +04:00
+++ b/sql/sql_trigger.cc	2007-10-30 14:54:56 +03:00
@@ -473,7 +473,7 @@ end:
   start_waiting_global_read_lock(thd);
 
   if (!result)
-    send_ok(thd);
+    my_ok(thd);
 
   DBUG_RETURN(result);
 }
diff -Nrup a/sql/sql_union.cc b/sql/sql_union.cc
--- a/sql/sql_union.cc	2007-08-05 09:11:26 +04:00
+++ b/sql/sql_union.cc	2007-10-30 14:54:56 +03:00
@@ -58,7 +58,7 @@ bool select_union::send_data(List<Item> 
     return 0;
   }
   fill_record(thd, table->field, values, 1);
-  if (thd->net.report_error)
+  if (thd->is_error())
     return 1;
 
   if ((error= table->file->ha_write_row(table->record[0])))
diff -Nrup a/sql/sql_update.cc b/sql/sql_update.cc
--- a/sql/sql_update.cc	2007-09-21 12:15:00 +04:00
+++ b/sql/sql_update.cc	2007-10-30 14:54:56 +03:00
@@ -318,7 +318,7 @@ int mysql_update(THD *thd,
   if (prune_partitions(thd, table, conds))
   {
     free_underlaid_joins(thd, select_lex);
-    send_ok(thd);				// No matching records
+    my_ok(thd);                         // No matching records
     DBUG_RETURN(0);
   }
 #endif
@@ -335,7 +335,7 @@ int mysql_update(THD *thd,
     {
       DBUG_RETURN(1);				// Error in where
     }
-    send_ok(thd);				// No matching records
+    my_ok(thd);                         // No matching records
     DBUG_RETURN(0);
   }
   if (!select && limit != HA_POS_ERROR)
@@ -839,12 +839,12 @@ int mysql_update(THD *thd,
 	    (ulong) thd->cuted_fields);
     thd->row_count_func=
       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-    send_ok(thd, (ulong) thd->row_count_func, id, buff);
+    my_ok(thd, (ulong) thd->row_count_func, id, buff);
     DBUG_PRINT("info",("%ld records updated", (long) updated));
   }
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;		/* calc cuted fields */
   thd->abort_on_warning= 0;
-  DBUG_RETURN((error >= 0 || thd->net.report_error) ? 1 : 0);
+  DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
 
 err:
   delete select;
@@ -1193,8 +1193,8 @@ bool mysql_multi_update(THD *thd,
                       OPTION_SETUP_TABLES_DONE,
                       result, unit, select_lex);
   DBUG_PRINT("info",("res: %d  report_error: %d", res,
-                     thd->net.report_error));
-  res|= thd->net.report_error;
+                     thd->is_error()));
+  res|= thd->is_error();
   if (unlikely(res))
   {
     /* If we had a another error reported earlier then this will be ignored */
@@ -2012,6 +2012,6 @@ bool multi_update::send_eof()
 	  (ulong) thd->cuted_fields);
   thd->row_count_func=
     (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-  ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+  my_ok(thd, (ulong) thd->row_count_func, id, buff);
   DBUG_RETURN(FALSE);
 }
diff -Nrup a/sql/sql_view.cc b/sql/sql_view.cc
--- a/sql/sql_view.cc	2007-09-13 01:08:41 +04:00
+++ b/sql/sql_view.cc	2007-10-30 14:54:56 +03:00
@@ -602,7 +602,7 @@ bool mysql_create_view(THD *thd, TABLE_L
   if (res)
     goto err;
 
-  send_ok(thd);
+  my_ok(thd);
   lex->link_first_table_back(view, link_to_local);
   DBUG_RETURN(0);
 
@@ -610,7 +610,7 @@ err:
   thd->proc_info= "end";
   lex->link_first_table_back(view, link_to_local);
   unit->cleanup();
-  DBUG_RETURN(res || thd->net.report_error);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 
@@ -826,7 +826,7 @@ loop_out:
                         view_parameters + revision_number_position, 1,
                         &file_parser_dummy_hook))
       {
-        error= thd->net.report_error? -1 : 0;
+        error= thd->is_error()? -1 : 0;
         goto err;
       }
     }
@@ -889,7 +889,7 @@ loop_out:
   if (sql_create_definition_file(&dir, &file, view_file_type,
 				 (uchar*)view, view_parameters, num_view_backups))
   {
-    error= thd->net.report_error? -1 : 1;
+    error= thd->is_error()? -1 : 1;
     goto err;
   }
   DBUG_RETURN(0);
@@ -1541,7 +1541,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
 
   write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
-  send_ok(thd);
+  my_ok(thd);
   VOID(pthread_mutex_unlock(&LOCK_open));
   DBUG_RETURN(FALSE);
 }
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy	2007-10-12 00:38:36 +04:00
+++ b/sql/sql_yacc.yy	2007-10-30 14:54:56 +03:00
@@ -9953,7 +9953,7 @@ NUM_literal:
         | DECIMAL_NUM
           {
             $$= new Item_decimal($1.str, $1.length, YYTHD->charset());
-            if (YYTHD->net.report_error)
+            if (YYTHD->is_error())
             {
               MYSQL_YYABORT;
             }
@@ -9961,7 +9961,7 @@ NUM_literal:
         | FLOAT_NUM
           {
             $$ = new Item_float($1.str, $1.length);
-            if (YYTHD->net.report_error)
+            if (YYTHD->is_error())
             {
               MYSQL_YYABORT;
             }
diff -Nrup a/sql/table.cc b/sql/table.cc
--- a/sql/table.cc	2007-08-16 20:04:12 +04:00
+++ b/sql/table.cc	2007-10-30 14:54:56 +03:00
@@ -3262,31 +3262,32 @@ bool TABLE_LIST::prep_check_option(THD *
 }
 
 
-/*
+/**
   Hide errors which show view underlying table information
 
-  SYNOPSIS
-    TABLE_LIST::hide_view_error()
-    thd     thread handler
+  @param[in,out]  thd     thread handler
 
+  @pre This method can be called only if there is an error.
 */
 
 void TABLE_LIST::hide_view_error(THD *thd)
 {
   /* Hide "Unknown column" or "Unknown function" error */
-  if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
-      thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
-      thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
-      thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
-      thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR ||
-      thd->net.last_errno == ER_TABLE_NOT_LOCKED ||
-      thd->net.last_errno == ER_NO_SUCH_TABLE)
+  DBUG_ASSERT(thd->is_error());
+
+  if (thd->main_da.sql_errno() == ER_BAD_FIELD_ERROR ||
+      thd->main_da.sql_errno() == ER_SP_DOES_NOT_EXIST ||
+      thd->main_da.sql_errno() == ER_PROCACCESS_DENIED_ERROR ||
+      thd->main_da.sql_errno() == ER_COLUMNACCESS_DENIED_ERROR ||
+      thd->main_da.sql_errno() == ER_TABLEACCESS_DENIED_ERROR ||
+      thd->main_da.sql_errno() == ER_TABLE_NOT_LOCKED ||
+      thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
   {
     TABLE_LIST *top= top_table();
-    thd->clear_error(); 
+    thd->clear_error();
     my_error(ER_VIEW_INVALID, MYF(0), top->view_db.str, top->view_name.str);
   }
-  else if (thd->net.last_errno == ER_NO_DEFAULT_FOR_FIELD)
+  else if (thd->main_da.sql_errno() == ER_NO_DEFAULT_FOR_FIELD)
   {
     TABLE_LIST *top= top_table();
     thd->clear_error();
diff -Nrup a/sql/tztime.cc b/sql/tztime.cc
--- a/sql/tztime.cc	2007-08-13 17:11:14 +04:00
+++ b/sql/tztime.cc	2007-10-30 14:54:56 +03:00
@@ -1641,7 +1641,7 @@ my_tz_init(THD *org_thd, const char *def
   if (open_system_tables_for_read(thd, tz_tables, &open_tables_state_backup))
   {
     sql_print_warning("Can't open and lock time zone table: %s "
-                      "trying to live without them", thd->net.last_error);
+                      "trying to live without them", thd->main_da.message());
     /* We will try emulate that everything is ok */
     return_val= time_zone_tables_exist= 0;
     goto end_with_setting_default_tz;
diff -Nrup a/sql/unireg.cc b/sql/unireg.cc
--- a/sql/unireg.cc	2007-07-11 12:57:47 +04:00
+++ b/sql/unireg.cc	2007-10-30 14:54:56 +03:00
@@ -105,11 +105,11 @@ bool mysql_create_frm(THD *thd, const ch
                   data_offset, db_file))
   {
     my_free(screen_buff, MYF(0));
-    if (thd->net.last_errno != ER_TOO_MANY_FIELDS)
+    if (thd->main_da.sql_errno() != ER_TOO_MANY_FIELDS)
       DBUG_RETURN(1);
 
     // Try again without UNIREG screens (to get more columns)
-    thd->net.last_error[0]=0;
+    thd->clear_error();
     if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
       DBUG_RETURN(1);
     if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
diff -Nrup a/sql-common/client.c b/sql-common/client.c
--- a/sql-common/client.c	2007-08-13 17:11:14 +04:00
+++ b/sql-common/client.c	2007-10-30 14:54:56 +03:00
@@ -312,30 +312,30 @@ HANDLE create_named_pipe(NET *net, uint 
       break;
     if (GetLastError() != ERROR_PIPE_BUSY)
     {
-      net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                  ER(net->last_errno), host, unix_socket,
+      net->client_last_errno=CR_NAMEDPIPEOPEN_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno), host, unix_socket,
 	          (ulong) GetLastError());
       return INVALID_HANDLE_VALUE;
     }
     /* wait for for an other instance */
     if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
     {
-      net->last_errno=CR_NAMEDPIPEWAIT_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                  ER(net->last_errno), host, unix_socket,
+      net->client_last_errno=CR_NAMEDPIPEWAIT_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno), host, unix_socket,
 	          (ulong) GetLastError());
       return INVALID_HANDLE_VALUE;
     }
   }
   if (hPipe == INVALID_HANDLE_VALUE)
   {
-    net->last_errno=CR_NAMEDPIPEOPEN_ERROR;
-    strmov(net->sqlstate, unknown_sqlstate);
-    my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                ER(net->last_errno), host, unix_socket,
+    net->client_last_errno=CR_NAMEDPIPEOPEN_ERROR;
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                ER(net->client_last_errno), host, unix_socket,
 	        (ulong) GetLastError());
     return INVALID_HANDLE_VALUE;
   }
@@ -343,10 +343,10 @@ HANDLE create_named_pipe(NET *net, uint 
   if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
   {
     CloseHandle( hPipe );
-    net->last_errno=CR_NAMEDPIPESETSTATE_ERROR;
-    strmov(net->sqlstate, unknown_sqlstate);
-    my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                ER(net->last_errno),host, unix_socket,
+    net->client_last_errno=CR_NAMEDPIPESETSTATE_ERROR;
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                ER(net->client_last_errno),host, unix_socket,
 	        (ulong) GetLastError());
     return INVALID_HANDLE_VALUE;
   }
@@ -566,14 +566,14 @@ err:
     CloseHandle(handle_connect_file_map);
   if (error_allow)
   {
-    net->last_errno=error_allow;
-    strmov(net->sqlstate, unknown_sqlstate);
+    net->client_last_errno= error_allow;
+    strmov(net->client_sqlstate, unknown_sqlstate);
     if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
-      my_snprintf(net->last_error,sizeof(net->last_error)-1,
-                  ER(net->last_errno),suffix_pos,error_code);
+      my_snprintf(net->client_last_error,sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno), suffix_pos,error_code);
     else
-      my_snprintf(net->last_error,sizeof(net->last_error)-1,
-                  ER(net->last_errno),error_code);
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno), error_code);
     return(INVALID_HANDLE_VALUE);
   }
   return(handle_map);
@@ -607,7 +607,7 @@ cli_safe_read(MYSQL *mysql)
       return (packet_error);
 #endif /*MYSQL_SERVER*/
     end_server(mysql);
-    set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
+    set_mysql_error(mysql, net->client_last_errno == ER_NET_PACKET_TOO_LARGE ?
                     CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
     return (packet_error);
   }
@@ -616,16 +616,16 @@ cli_safe_read(MYSQL *mysql)
     if (len > 3)
     {
       char *pos=(char*) net->read_pos+1;
-      net->last_errno=uint2korr(pos);
+      net->client_last_errno=uint2korr(pos);
       pos+=2;
       len-=2;
       if (protocol_41(mysql) && pos[0] == '#')
       {
-	strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
+	strmake(net->client_sqlstate, pos+1, SQLSTATE_LENGTH);
 	pos+= SQLSTATE_LENGTH+1;
       }
-      (void) strmake(net->last_error,(char*) pos,
-		     min((uint) len,(uint) sizeof(net->last_error)-1));
+      (void) strmake(net->client_last_error,(char*) pos,
+		     min((uint) len,(uint) sizeof(net->client_last_error)-1));
     }
     else
       set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
@@ -641,7 +641,8 @@ cli_safe_read(MYSQL *mysql)
     mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
     DBUG_PRINT("error",("Got error: %d/%s (%s)",
-			net->last_errno, net->sqlstate, net->last_error));
+			net->client_last_errno,
+                        net->client_sqlstate, net->client_last_error));
     return(packet_error);
   }
   return len;
@@ -683,10 +684,9 @@ cli_advanced_command(MYSQL *mysql, enum 
     DBUG_RETURN(1);
   }
 
-  net->last_error[0]=0;
-  net->last_errno= 0;
-  strmov(net->sqlstate, not_error_sqlstate);
-  mysql->net.report_error=0;
+  net->client_last_error[0]=0;
+  net->client_last_errno= 0;
+  strmov(net->client_sqlstate, not_error_sqlstate);
   mysql->info=0;
   mysql->affected_rows= ~(my_ulonglong) 0;
   /*
@@ -701,10 +701,10 @@ cli_advanced_command(MYSQL *mysql, enum 
   {
     DBUG_PRINT("error",("Can't send command to server. Error: %d",
 			socket_errno));
-    if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
+    if (net->client_last_errno == ER_NET_PACKET_TOO_LARGE)
     {
-      net->last_errno=CR_NET_PACKET_TOO_LARGE;
-      strmov(net->last_error,ER(net->last_errno));
+      net->client_last_errno=CR_NET_PACKET_TOO_LARGE;
+      strmov(net->client_last_error,ER(net->client_last_errno));
       goto end;
     }
     end_server(mysql);
@@ -713,8 +713,8 @@ cli_advanced_command(MYSQL *mysql, enum 
     if (net_write_command(net,(uchar) command, header, header_length,
 			  arg, arg_length))
     {
-      net->last_errno=CR_SERVER_GONE_ERROR;
-      strmov(net->last_error,ER(net->last_errno));
+      net->client_last_errno=CR_SERVER_GONE_ERROR;
+      strmov(net->client_last_error, ER(net->client_last_errno));
       goto end;
     }
   }
@@ -753,9 +753,9 @@ void set_mysql_error(MYSQL *mysql, int e
   DBUG_ASSERT(mysql != 0);
 
   net= &mysql->net;
-  net->last_errno= errcode;
-  strmov(net->last_error, ER(errcode));
-  strmov(net->sqlstate, sqlstate);
+  net->client_last_errno= errcode;
+  strmov(net->client_last_error, ER(errcode));
+  strmov(net->client_sqlstate, sqlstate);
 
   DBUG_VOID_RETURN;
 }
@@ -772,12 +772,12 @@ static void set_mysql_extended_error(MYS
   DBUG_ASSERT(mysql != 0);
 
   net= &mysql->net;
-  net->last_errno= errcode;
+  net->client_last_errno= errcode;
   va_start(args, format);
-  my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
+  my_vsnprintf(net->client_last_error, sizeof(net->client_last_error)-1,
                format, args);
   va_end(args);
-  strmov(net->sqlstate, sqlstate);
+  strmov(net->client_sqlstate, sqlstate);
 
   DBUG_VOID_RETURN;
 }
@@ -831,7 +831,7 @@ static my_bool is_NT(void)
   RETURN VALUE
     0  success
    !0  network error or the server is not commercial.
-       Error code is saved in mysql->net.last_errno.
+       Error code is saved in mysql->net.client_last_errno.
 */
 
 static int check_license(MYSQL *mysql)
@@ -844,11 +844,11 @@ static int check_license(MYSQL *mysql)
 
   if (mysql_real_query(mysql, query, sizeof(query)-1))
   {
-    if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
+    if (net->client_last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
     {
-      net->last_errno= CR_WRONG_LICENSE;
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                  ER(net->last_errno), required_license);
+      net->client_last_errno= CR_WRONG_LICENSE;
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno), required_license);
     }
     return 1;
   }
@@ -860,16 +860,16 @@ static int check_license(MYSQL *mysql)
     two is ever true for server variables now), or column value
     mismatch, set wrong license error.
   */
-  if (!net->last_errno &&
+  if (!net->client_last_errno &&
       (!row || !row[0] ||
        strncmp(row[0], required_license, sizeof(required_license))))
   {
-    net->last_errno= CR_WRONG_LICENSE;
-    my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                ER(net->last_errno), required_license);
+    net->client_last_errno= CR_WRONG_LICENSE;
+    my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                ER(net->client_last_errno), required_license);
   }
   mysql_free_result(res);
-  return net->last_errno;
+  return net->client_last_errno;
 }
 #endif /* CHECK_LICENSE */
 
@@ -1480,7 +1480,7 @@ mysql_init(MYSQL *mysql)
   mysql->options.connect_timeout= CONNECT_TIMEOUT;
   mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
   mysql->charset=default_client_charset_info;
-  strmov(mysql->net.sqlstate, not_error_sqlstate);
+  strmov(mysql->net.client_sqlstate, not_error_sqlstate);
   /*
     By default, we are a replication pivot. The caller must reset it
     after we return if this is not the case.
@@ -1764,19 +1764,19 @@ int mysql_init_character_set(MYSQL *mysq
   
   if (!mysql->charset)
   {
-    net->last_errno=CR_CANT_READ_CHARSET;
-    strmov(net->sqlstate, unknown_sqlstate);
+    net->client_last_errno=CR_CANT_READ_CHARSET;
+    strmov(net->client_sqlstate, unknown_sqlstate);
     if (mysql->options.charset_dir)
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                  ER(net->last_errno),
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno),
                   mysql->options.charset_name,
                   mysql->options.charset_dir);
     else
     {
       char cs_dir_name[FN_REFLEN];
       get_charsets_dir(cs_dir_name);
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
-                  ER(net->last_errno),
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno),
                   mysql->options.charset_name,
                   cs_dir_name);
     }
@@ -1910,10 +1910,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
     if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
     {
-      net->last_errno=CR_SOCKET_CREATE_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error,sizeof(net->last_error)-1,
-                  ER(net->last_errno),socket_errno);
+      net->client_last_errno=CR_SOCKET_CREATE_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error,sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno),socket_errno);
       goto error;
     }
     net->vio= vio_new(sock, VIO_TYPE_SOCKET,
@@ -1926,10 +1926,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     {
       DBUG_PRINT("error",("Got error %d on connect to local server",
 			  socket_errno));
-      net->last_errno=CR_CONNECTION_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error,sizeof(net->last_error)-1,
-                  ER(net->last_errno),unix_socket,socket_errno);
+      net->client_last_errno=CR_CONNECTION_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error,sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno),unix_socket,socket_errno);
       goto error;
     }
     mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
@@ -1986,10 +1986,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 #endif
     if (sock == SOCKET_ERROR)
     {
-      net->last_errno=CR_IPSOCK_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error,sizeof(net->last_error)-1,
-                  ER(net->last_errno),socket_errno);
+      net->client_last_errno=CR_IPSOCK_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error,sizeof(net->client_last_error)-1,
+                  ER(net->client_last_errno),socket_errno);
       goto error;
     }
     net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
@@ -2014,9 +2014,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
       if (!hp)
       {
 	my_gethostbyname_r_free();
-	net->last_errno=CR_UNKNOWN_HOST;
-	strmov(net->sqlstate, unknown_sqlstate);
-	my_snprintf(net->last_error, sizeof(net->last_error)-1,
+	net->client_last_errno=CR_UNKNOWN_HOST;
+	strmov(net->client_sqlstate, unknown_sqlstate);
+	my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
                     ER(CR_UNKNOWN_HOST), host, tmp_errno);
 	goto error;
       }
@@ -2030,9 +2030,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     {
       DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
 			  host));
-      net->last_errno= CR_CONN_HOST_ERROR;
-      strmov(net->sqlstate, unknown_sqlstate);
-      my_snprintf(net->last_error, sizeof(net->last_error)-1,
+      net->client_last_errno= CR_CONN_HOST_ERROR;
+      strmov(net->client_sqlstate, unknown_sqlstate);
+      my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
                   ER(CR_CONN_HOST_ERROR), host, socket_errno);
       goto error;
     }
@@ -2082,7 +2082,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 
   if ((pkt_length=cli_safe_read(mysql)) == packet_error)
   {
-    if (mysql->net.last_errno == CR_SERVER_LOST)
+    if (mysql->net.client_last_errno == CR_SERVER_LOST)
       set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                                ER(CR_SERVER_LOST_EXTENDED),
                                "reading initial communication packet",
@@ -2097,9 +2097,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 		     PROTOCOL_VERSION, mysql->protocol_version));
   if (mysql->protocol_version != PROTOCOL_VERSION)
   {
-    strmov(net->sqlstate, unknown_sqlstate);
-    net->last_errno= CR_VERSION_ERROR;
-    my_snprintf(net->last_error, sizeof(net->last_error)-1,
+    strmov(net->client_sqlstate, unknown_sqlstate);
+    net->client_last_errno= CR_VERSION_ERROR;
+    my_snprintf(net->client_last_error, sizeof(net->client_last_error)-1,
                 ER(CR_VERSION_ERROR), mysql->protocol_version,
 	        PROTOCOL_VERSION);
     goto error;
@@ -2318,7 +2318,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 
   if ((pkt_length=cli_safe_read(mysql)) == packet_error)
   {
-    if (mysql->net.last_errno == CR_SERVER_LOST)
+    if (mysql->net.client_last_errno == CR_SERVER_LOST)
       set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                                ER(CR_SERVER_LOST_EXTENDED),
                                "reading authorization packet",
@@ -2346,7 +2346,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     /* Read what server thinks about out new auth message report */
     if (cli_safe_read(mysql) == packet_error)
     {
-      if (mysql->net.last_errno == CR_SERVER_LOST)
+      if (mysql->net.client_last_errno == CR_SERVER_LOST)
         set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                                  ER(CR_SERVER_LOST_EXTENDED),
                                  "reading final connect information",
@@ -2365,7 +2365,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 
   if (db && mysql_select_db(mysql, db))
   {
-    if (mysql->net.last_errno == CR_SERVER_LOST)
+    if (mysql->net.client_last_errno == CR_SERVER_LOST)
         set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
                                  ER(CR_SERVER_LOST_EXTENDED),
                                  "Setting intital database",
@@ -2409,7 +2409,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
 error:
   reset_sigpipe(mysql);
   DBUG_PRINT("error",("message: %u/%s (%s)",
-		      net->last_errno, net->sqlstate, net->last_error));
+		      net->client_last_errno, net->client_sqlstate,
+                      net->client_last_error));
   {
     /* Free alloced memory */
     end_server(mysql);
@@ -2467,9 +2468,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
 			  mysql->db, mysql->port, mysql->unix_socket,
 			  mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
   {
-    mysql->net.last_errno= tmp_mysql.net.last_errno;
-    strmov(mysql->net.last_error, tmp_mysql.net.last_error);
-    strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
+    mysql->net.client_last_errno= tmp_mysql.net.client_last_errno;
+    strmov(mysql->net.client_last_error, tmp_mysql.net.client_last_error);
+    strmov(mysql->net.client_sqlstate, tmp_mysql.net.client_sqlstate);
     DBUG_RETURN(1);
   }
   if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
@@ -2477,9 +2478,9 @@ my_bool mysql_reconnect(MYSQL *mysql)
     DBUG_PRINT("error", ("mysql_set_character_set() failed"));
     bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options));
     mysql_close(&tmp_mysql);
-    mysql->net.last_errno= tmp_mysql.net.last_errno;
-    strmov(mysql->net.last_error, tmp_mysql.net.last_error);
-    strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
+    mysql->net.client_last_errno= tmp_mysql.net.client_last_errno;
+    strmov(mysql->net.client_last_error, tmp_mysql.net.client_last_error);
+    strmov(mysql->net.client_sqlstate, tmp_mysql.net.client_sqlstate);
     DBUG_RETURN(1);
   }
 
@@ -3071,13 +3072,13 @@ unsigned int STDCALL mysql_num_fields(MY
 
 uint STDCALL mysql_errno(MYSQL *mysql)
 {
-  return mysql->net.last_errno;
+  return mysql->net.client_last_errno;
 }
 
 
 const char * STDCALL mysql_error(MYSQL *mysql)
 {
-  return mysql->net.last_error;
+  return mysql->net.client_last_error;
 }
 
 
@@ -3142,14 +3143,15 @@ int STDCALL mysql_set_character_set(MYSQ
   {
     char cs_dir_name[FN_REFLEN];
     get_charsets_dir(cs_dir_name);
-    mysql->net.last_errno= CR_CANT_READ_CHARSET;
-    strmov(mysql->net.sqlstate, unknown_sqlstate);
-    my_snprintf(mysql->net.last_error, sizeof(mysql->net.last_error) - 1,
-		ER(mysql->net.last_errno), cs_name, cs_dir_name);
+    mysql->net.client_last_errno= CR_CANT_READ_CHARSET;
+    strmov(mysql->net.client_sqlstate, unknown_sqlstate);
+    my_snprintf(mysql->net.client_last_error,
+                sizeof(mysql->net.client_last_error) - 1,
+		ER(mysql->net.client_last_errno), cs_name, cs_dir_name);
 
   }
   charsets_dir= save_csdir;
-  return mysql->net.last_errno;
+  return mysql->net.client_last_errno;
 }
 
 
diff -Nrup a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
--- a/storage/myisam/ha_myisam.cc	2007-09-21 12:15:03 +04:00
+++ b/storage/myisam/ha_myisam.cc	2007-10-30 14:54:56 +03:00
@@ -1384,6 +1384,7 @@ int ha_myisam::enable_indexes(uint mode)
     const char *save_proc_info=thd->proc_info;
     thd->proc_info="Creating index";
     myisamchk_init(&param);
+    param.thd= thd;
     param.op_name= "recreating_index";
     param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
                      T_CREATE_MISSING_KEYS);
Thread
bk commit into 5.1 tree (kostja:1.2581)konstantin30 Oct