List:Commits« Previous MessageNext Message »
From:konstantin Date:October 30 2007 11:45am
Subject:bk commit into 5.1 tree (kostja:1.2582)
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:45:19+03:00, kostja@bodhi.(none) +59 -0
  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:45:11+03:00, kostja@bodhi.(none) +8 -8
    Remove send_eof, use my_eof instead.

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

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

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

  libmysqld/lib_sql.cc@stripped, 2007-10-30 14:45:11+03:00, kostja@bodhi.(none) +35 -33
    Remove send_eof, use my_eof instead.

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

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

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

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

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

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

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

  sql/handler.cc@stripped, 2007-10-30 14:45:11+03:00, kostja@bodhi.(none) +34 -32
    Remove send_eof, use my_eof instead.

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

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

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

  sql/log_event.cc@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +33 -22
    Remove send_eof, use my_eof instead.

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

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

  sql/mysqld.cc@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +34 -23
    Remove send_eof, use my_eof instead.

  sql/net_serv.cc@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +15 -13
    Remove send_eof, use my_eof instead.

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

  sql/protocol.cc@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +66 -156
    Remove send_eof, use my_eof instead.

  sql/protocol.h@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +10 -4
    Remove send_eof, use my_eof instead.

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

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

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

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

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

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

  sql/sp_head.cc@stripped, 2007-10-30 14:45:12+03:00, kostja@bodhi.(none) +13 -8
    Remove send_eof, use my_eof instead.

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

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

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

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

  sql/sql_class.cc@stripped, 2007-10-30 14:45:13+03:00, kostja@bodhi.(none) +109 -43
    Remove send_eof, use my_eof instead.

  sql/sql_class.h@stripped, 2007-10-30 14:45:13+03:00, kostja@bodhi.(none) +100 -26
    Remove send_eof, use my_eof instead.

  sql/sql_connect.cc@stripped, 2007-10-30 14:45:13+03:00, kostja@bodhi.(none) +81 -68
    Remove send_eof, use my_eof instead.

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

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

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

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

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

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

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

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

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

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

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

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

  sql/sql_table.cc@stripped, 2007-10-30 14:45:15+03:00, kostja@bodhi.(none) +8 -5
    Remove send_eof, use my_eof instead.

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

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

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

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

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

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

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

  storage/myisam/ha_myisam.cc@stripped, 2007-10-30 14:45:15+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-19 14:37:19 +04:00
+++ b/include/mysql_com.h	2007-10-30 14:45:11 +03:00
@@ -205,11 +205,7 @@ typedef struct st_net {
   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;
-  /*
-    Is set if EOF packet is already sent, and we do not need to send OK
-    or error messages.
-  */
-  my_bool eof_sent;
+  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:45:11 +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:45:11 +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:45:11 +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-19 14:37:19 +04:00
+++ b/libmysqld/lib_sql.cc	2007-10-30 14:45:11 +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
@@ -114,7 +114,7 @@ emb_advanced_command(MYSQL *mysql, enum 
   thd->cur_data= 0;
 
   if (!skip_check)
-    result= thd->net.last_errno ? -1 : 0;
+    result= thd->is_error() ? -1 : 0;
 
   return result;
 }
@@ -244,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])
@@ -287,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);
@@ -298,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;
 }
 
@@ -319,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);
 }
@@ -374,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() : "";
 }
 
 
@@ -678,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;
 }
@@ -702,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,
@@ -780,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;
@@ -791,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));
 }
 
 
@@ -953,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,7 +998,7 @@ bool Protocol_binary::write()
 
 void
 net_send_ok(THD *thd,
-            ulong server_status, uint total_warn_count,
+            uint server_status, uint total_warn_count,
             ha_rows affected_rows, ulonglong id, const char *message)
 {
   DBUG_ENTER("send_ok");
@@ -1012,16 +1015,15 @@ net_send_ok(THD *thd,
     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);
-  thd->net.eof_sent= TRUE;
+  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:45:11 +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/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:45:11 +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/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:45:11 +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:45:11 +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:45:11 +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-10-19 14:37:20 +04:00
+++ b/sql/ha_ndbcluster_binlog.cc	2007-10-30 14:45:11 +03:00
@@ -270,15 +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();
+  thd->main_da.reset_diagnostics_area();
 
   thd->options= save_thd_options;
   thd->query_length= save_query_length;
@@ -2307,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/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-10-19 14:37:20 +04:00
+++ b/sql/handler.cc	2007-10-30 14:45:11 +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,26 +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;
-    int report_error= thd->net.report_error;
-
-    strmake(buff, thd->net.last_error, sizeof(buff)-1);
-    thd->query_error= 0;
-    thd->spcont= NULL;
-    thd->lex->current_select= 0;
-    thd->net.report_error= 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;
@@ -1472,17 +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);
-    thd->net.report_error= report_error;
-    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);
@@ -2205,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;
@@ -3442,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-19 14:37:20 +04:00
+++ b/sql/item_func.cc	2007-10-30 14:45:11 +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.report_error= 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);
     }
@@ -4062,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:45:11 +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:45:11 +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-10-19 14:37:20 +04:00
+++ b/sql/log_event.cc	2007-10-30 14:45:12 +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());
   
@@ -2113,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:
@@ -2122,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))
@@ -2136,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;
@@ -2158,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;
@@ -3476,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;
@@ -5958,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;
@@ -6002,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;
         }
@@ -6156,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;
       }
@@ -6202,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
@@ -6335,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();
@@ -6805,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;
@@ -7339,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:45:12 +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:45:12 +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-10-19 14:37:20 +04:00
+++ b/sql/mysqld.cc	2007-10-30 14:45:12 +03:00
@@ -2571,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)
     {
@@ -2601,16 +2587,40 @@ int my_message_sql(uint error, const cha
     }
     else
     {
-      NET *net= &thd->net;
-      DBUG_ASSERT(! net->eof_sent);
-      if (! net->report_error)                  // 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;
-        net->report_error= 1;
+        thd->main_da.set_error_status(thd,
+                                      error ? error : ER_UNKNOWN_ERROR,
+                                      str);
       }
-      query_cache_abort(net);
+      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 */
@@ -4309,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-19 14:37:20 +04:00
+++ b/sql/net_serv.cc	2007-10-30 14:45:12 +03:00
@@ -123,19 +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->eof_sent= 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->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 */
   {
@@ -176,7 +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->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); 
@@ -631,8 +632,8 @@ 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 */
 	    goto end;
@@ -662,8 +663,8 @@ net_real_write(NET *net,const uchar *pac
 #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
       net->error= 2;				/* Close socket */
 #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;
     }
@@ -841,7 +842,7 @@ my_real_read(NET *net, size_t *complen)
 		len= packet_error;
 		net->error= 2;                 /* Close socket */
 #ifdef MYSQL_SERVER
-		net->last_errno= ER_NET_FCNTL_ERROR;
+		my_error(ER_NET_FCNTL_ERROR, MYF(0));
 #endif
 		goto end;
 	      }
@@ -872,8 +873,9 @@ my_real_read(NET *net, size_t *complen)
 	  len= packet_error;
 	  net->error= 2;				/* Close socket */
 #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;
 	}
@@ -905,7 +907,7 @@ my_real_read(NET *net, size_t *complen)
 	  }
 	  len= packet_error;
 #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;
 	}
@@ -1090,7 +1092,7 @@ my_net_read(NET *net)
       {
 	net->error= 2;			/* caller will close socket */
 #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:45:12 +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/protocol.cc b/sql/protocol.cc
--- a/sql/protocol.cc	2007-10-19 14:37:20 +04:00
+++ b/sql/protocol.cc	2007-10-30 14:45:12 +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,164 +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]);
 
-  thd->query_error=  1; // needed to catch query errors during replication
-  if (!err)
-  {
-    if (sql_errno)
-      err=ER(sql_errno);
-    else
-    {
-      if (net->report_error)
-      {
-        err= net->last_error;
-	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 */
-      }
-    }
-  }
+  DBUG_PRINT("enter",("sql_errno: %d  err: %s", sql_errno, err));
 
-  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);
-
-  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.
@@ -251,7 +116,7 @@ net_printf_error(THD *thd, uint errcode,
 #ifndef EMBEDDED_LIBRARY
 void
 net_send_ok(THD *thd,
-            ulong server_status, uint total_warn_count,
+            uint server_status, uint total_warn_count,
             ha_rows affected_rows, ulonglong id, const char *message)
 {
   NET *net= &thd->net;
@@ -288,11 +153,15 @@ net_send_ok(THD *thd,
     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));
 
+  thd->main_da.can_overwrite_status= FALSE;
+
   DBUG_VOID_RETURN;
 }
 
@@ -302,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().
@@ -321,17 +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_ASSERT(thd->net.report_error == 0);
+  DBUG_ENTER("net_send_eof");
   /* Set to TRUE if no active vio, to work well in case of --init-file */
-  thd->net.eof_sent= 1;
   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->main_da.can_overwrite_status= FALSE;
     DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
   }
   DBUG_VOID_RETURN;
@@ -343,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)
   {
@@ -352,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);
     /*
@@ -361,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
@@ -454,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.
@@ -502,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
@@ -666,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-10-19 14:37:20 +04:00
+++ b/sql/protocol.h	2007-10-30 14:45:12 +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,14 +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 net_send_ok(THD *thd, ulong server_status,
+
+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 send_eof(THD *thd);
+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-10-19 14:37:20 +04:00
+++ b/sql/repl_failsafe.cc	2007-10-30 14:45:12 +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);
@@ -881,7 +881,7 @@ bool load_master_data(THD* thd)
 	goto err;
       }
       /* Clear the result of mysql_create_db */
-      thd->main_da.reset();
+      thd->main_da.reset_diagnostics_area();
 
       if (mysql_select_db(&mysql, db) ||
 	  mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) ||
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:45:12 +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:45:12 +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:45:12 +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-10-19 14:37:20 +04:00
+++ b/sql/slave.cc	2007-10-30 14:45:12 +03:00
@@ -995,7 +995,10 @@ static int create_table_from_dump(THD* t
       goto err;
     }
     else
-      thd->main_da.reset(); /* clear the result of mysql_rm_table */
+    {
+      /* 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 */
@@ -1017,7 +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(); /* cleanup from CREATE_TABLE */
+  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))
@@ -1433,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);
 }
 
@@ -1721,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
@@ -2533,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:45:12 +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-10-19 14:37:20 +04:00
+++ b/sql/sp_head.cc	2007-10-30 14:45:12 +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;
@@ -1245,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;
@@ -2320,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);
 }
@@ -2513,7 +2513,7 @@ sp_head::show_routine_code(THD *thd)
   }
 
   if (!res)
-    send_eof(thd);
+    my_eof(thd);
 
   DBUG_RETURN(res);
 }
@@ -2641,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());
 }
 
 
@@ -2707,17 +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;
 
-    thd->main_da.reset();
-    thd->net.eof_sent= FALSE;
+    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:45:12 +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-10-19 14:37:20 +04:00
+++ b/sql/sql_acl.cc	2007-10-30 14:45:13 +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;
   }
 
@@ -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:45:13 +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_cache.cc b/sql/sql_cache.cc
--- a/sql/sql_cache.cc	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_cache.cc	2007-10-30 14:45:13 +03:00
@@ -1403,7 +1403,7 @@ def_week_frmt: %lu",                    
 
   thd->limit_found_rows = query->found_rows();
   thd->status_var.last_query_cost= 0.0;
-  thd->net.eof_sent= TRUE;
+  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-19 14:37:21 +04:00
+++ b/sql/sql_class.cc	2007-10-30 14:45:13 +03:00
@@ -353,33 +353,91 @@ 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 */
-  DBUG_ASSERT(! thd->net.report_error);
-  /* Only allowed to report success if has not yet sent EOF */
-  DBUG_ASSERT(! thd->net.eof_sent);
-  DBUG_ASSERT(! is_set);
-
-  server_status= thd->server_status;
-  total_warn_count= thd->total_warn_count;
-  affected_rows= affected_rows_arg;
-  last_insert_id= last_insert_id_arg;
+
+  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)
-  {
-    /**
-      Store the message in a permanent buffer till statement end.
-      We know that OK and ERROR statuses are mutually
-      exclusive, so we can reuse the buffer.
-    */
-    strmake(thd->net.last_error, message_arg, sizeof(thd->net.last_error));
-    message= thd->net.last_error;
-  }
+    strmake(m_message, message_arg, sizeof(m_message));
   else
-    message= NULL;
-  is_set= TRUE;
+    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;
 }
 
 
@@ -461,7 +519,6 @@ THD::THD()
   net.vio=0;
 #endif
   client_capabilities= 0;                       // minimalistic client
-  net.report_error= 0;                          // If error on boot
 #ifdef HAVE_QUERY_CACHE
   query_cache_init_query(&net);                 // If error on boot
 #endif
@@ -528,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
@@ -1335,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)
@@ -1396,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()
@@ -1419,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
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_class.h	2007-10-30 14:45:13 +03:00
@@ -968,20 +968,87 @@ 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:
-  /** Public for convenience of access. Please use methods to change */
+  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;
+  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
@@ -994,35 +1061,22 @@ public:
     The reason for the difference in the life cycle is legacy:
     ROW_COUNT() is a non-standard replacement for GET DIAGNOSTICS.
   */
-  ha_rows    affected_rows;
+  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      last_insert_id;
+  ulong      m_last_insert_id;
   /** The total number of warnings */
-  uint	     total_warn_count;
-  /** A note sent with the OK packet to the user, if any. */
-  const char *message;
+  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, net.report_error, net.sqlstate
+    - net.last_error, net.last_errno
   */
-  bool is_set;
-public:
-  void set_success_status(THD *thd, ha_rows affected_rows_arg,
-                          ulong last_insert_id_arg,
-                          const char *message);
-
-  void reset()
-  {
-    is_set= FALSE;
-  }
-
-  Diagnostics_area() { reset(); }
 };
 
 
@@ -1745,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;
   }
@@ -1954,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);
 
   /**
@@ -1962,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;
@@ -1991,6 +2046,14 @@ my_ok(THD *thd, ha_rows affected_rows= 0
   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
@@ -2088,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();
 };
 
 
@@ -2588,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-19 14:37:21 +04:00
+++ b/sql/sql_connect.cc	2007-10-30 14:45:13 +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,14 +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);
   }
-  net_send_ok(thd, thd->server_status, thd->total_warn_count,
-              0, 0, 0);
+  my_ok(thd);
   DBUG_RETURN(0);
 #else
 
@@ -350,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 
@@ -381,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 */
@@ -428,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);
         }
       }
 
@@ -463,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])
@@ -477,34 +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);
         }
       }
-      net_send_ok(thd, thd->server_status, thd->total_warn_count,
-                  0, 0, 0);
       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 */
 }
 
@@ -668,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))
@@ -687,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 ?
@@ -695,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 */
   {
@@ -755,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_
@@ -764,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)
@@ -792,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 ||
@@ -808,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 */
@@ -816,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)
@@ -853,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 */
@@ -881,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);
 }
 
@@ -942,10 +956,11 @@ bool login_connection(THD *thd)
   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() */
@@ -989,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);
   }
 }
 
@@ -1029,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();
diff -Nrup a/sql/sql_delete.cc b/sql/sql_delete.cc
--- a/sql/sql_delete.cc	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_delete.cc	2007-10-30 14:45:13 +03:00
@@ -112,7 +112,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
         !(table->triggers && table->triggers->has_delete_triggers()))))
   {
     /* Check if error when evaluating the conds */
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       delete select;
       free_underlaid_joins(thd, select_lex);
@@ -168,14 +168,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     delete select;
     free_underlaid_joins(thd, select_lex);
     thd->row_count_func= 0;
-    if (! thd->net.report_error)
+    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(thd->net.report_error);                 // Nothing to delete
+    DBUG_RETURN(thd->is_error());                 // Nothing to delete
   }
 
   /* If running in safe sql mode, don't allow updates without keys */
@@ -262,10 +262,10 @@ 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())
   {
     bool do_delete_record= !select || !select->skip_record();
-    if (thd->net.report_error)
+    if (thd->is_error())
     {
       error= 1;
       break;
@@ -403,7 +403,7 @@ cleanup:
     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());
 }
 
 
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:45:13 +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_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:45:13 +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-19 14:37:21 +04:00
+++ b/sql/sql_handler.cc	2007-10-30 14:45:13 +03:00
@@ -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:45:13 +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-10-19 14:37:21 +04:00
+++ b/sql/sql_insert.cc	2007-10-30 14:45:14 +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
@@ -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,7 +2266,9 @@ pthread_handler_t handle_delayed_insert(
   thd->thread_stack= (char*) &thd;
   if (init_thr_lock() || thd->store_globals())
   {
-    strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
+    /* 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();
     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
   {
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_parse.cc	2007-10-30 14:45:14 +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;
+
 }
 
 
@@ -396,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;
@@ -405,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]) ||
@@ -432,28 +437,12 @@ pthread_handler_t handle_bootstrap(void 
     mysql_reset_thd_for_next_command(thd);
     mysql_parse(thd, thd->query, length, & found_semicolon);
 
-    if (thd->net.report_error)
-    {
-      DBUG_ASSERT(! thd->net.eof_sent);
-      DBUG_ASSERT(! thd->main_da.is_set);
-      /* The query failed, send error to log and abort bootstrap */
-      net_send_error(thd);
-      thd->fatal_error();
-      break;
-    }
-    else if (!thd->net.eof_sent)
-    {
-      DBUG_ASSERT(thd->main_da.is_set);
-
-      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);
-    }
+    bootstrap_error= thd->is_error();
+    net_end_statement(thd);
 
     close_thread_tables(thd);			// Free tables
 
-    if (thd->is_fatal_error)
+    if (bootstrap_error)
       break;
 
     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
@@ -463,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;
@@ -684,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)
@@ -695,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);
   }
@@ -840,7 +830,7 @@ bool dispatch_command(enum enum_server_c
     tbl_name= strmake(db.str, packet + 1, db_len)+1;
     strmake(tbl_name, packet + db_len + 2, tbl_len);
     if (mysql_table_dump(thd, &db, tbl_name) == 0)
-      thd->net.eof_sent= 1;
+      thd->main_da.disable_status();
     break;
   }
   case COM_CHANGE_USER:
@@ -927,15 +917,9 @@ bool dispatch_command(enum enum_server_c
     /* Clear variables that are allocated */
     thd->user_connect= 0;
     res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
-    thd->net.eof_sent= 1;
 
     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;
@@ -1007,18 +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;
 
-      if (!thd->net.report_error && !thd->net.eof_sent)
-      {
-        DBUG_ASSERT(thd->main_da.is_set);
-        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);
-      }
+      net_end_statement(thd);
+      query_cache_end_of_result(thd);
       /*
         Multiple queries exits, execute them individually
       */
@@ -1121,7 +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
-    net->eof_sent= TRUE;                        // Don't send anything back
+    thd->main_da.disable_status();              // Don't send anything back
     error=TRUE;					// End server
     break;
 
@@ -1237,8 +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);
-    close_connection(thd, 0, 1);
+    my_eof(thd);
     close_thread_tables(thd);			// Free before kill
     kill_mysql();
     error=TRUE;
@@ -1251,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]);
@@ -1279,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
     {
@@ -1292,7 +1268,7 @@ bool dispatch_command(enum enum_server_c
 #ifndef EMBEDDED_LIBRARY
     VOID(my_net_write(net, (uchar*) buff, length));
     VOID(net_flush(net));
-    thd->net.eof_sent= 1;
+    thd->main_da.disable_status();
 #endif
     break;
   }
@@ -1325,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));
@@ -1343,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
@@ -1373,22 +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 && !thd->net.eof_sent)
+  if (thd->killed_errno() && !thd->main_da.is_set())
     thd->send_kill_message();
-  if (thd->net.report_error)
-  {
-    DBUG_ASSERT(! thd->net.eof_sent);
-    net_send_error(thd);
-  }
-  else if (! thd->net.eof_sent)
-  {
-    DBUG_ASSERT(thd->main_da.is_set);
 
-    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);
-  }
+  net_end_statement(thd);
+  query_cache_end_of_result(thd);
 
   log_slow_statement(thd);
 
@@ -3960,7 +3925,7 @@ create_sp_error:
         }
 	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
         }
       }
@@ -4553,7 +4518,7 @@ finish:
     */
     start_waiting_global_read_lock(thd);
   }
-  DBUG_RETURN(res || thd->net.report_error);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 
@@ -4593,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
@@ -5277,8 +5243,7 @@ void mysql_reset_thd_for_next_command(TH
   thd->total_warn_count=0;			// Warnings for this query
   thd->rand_used= 0;
   thd->sent_row_count= thd->examined_row_count= 0;
-  thd->net.eof_sent= FALSE;
-  thd->main_da.reset();
+  thd->main_da.reset_diagnostics_area();
 
   /*
     Because we come here only for start of top-statements, binlog format is
@@ -5498,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
@@ -5516,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));
 
@@ -6336,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,
@@ -7298,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_prepare.cc b/sql/sql_prepare.cc
--- a/sql/sql_prepare.cc	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_prepare.cc	2007-10-30 14:45:14 +03:00
@@ -251,7 +251,7 @@ static bool send_prep_stmt(Prepared_stat
                                              &stmt->lex->param_list,
                                              Protocol::SEND_EOF));
   /** Flag that a response has already been sent */
-  net->eof_sent= 1;
+  stmt->thd->main_da.disable_status();
   DBUG_RETURN(res);
 }
 #else
@@ -263,7 +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->net.eof_sent= 1;
+  thd->main_da.disable_status();
 
   return 0;
 }
@@ -2520,7 +2520,7 @@ void mysql_stmt_close(THD *thd, char *pa
   DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE));
   (void) stmt->deallocate();
 
-  thd->net.eof_sent= 1;
+  thd->main_da.disable_status();
 
   DBUG_VOID_RETURN;
 }
@@ -2587,7 +2587,7 @@ void mysql_stmt_get_longdata(THD *thd, c
 
   status_var_increment(thd->status_var.com_stmt_send_long_data);
 
-  thd->net.eof_sent= 1;
+  thd->main_da.disable_status();
 #ifndef EMBEDDED_LIBRARY
   /* Minimal size of long data packet is 6 bytes */
   if (packet_length < MYSQL_LONG_DATA_HEADER)
@@ -2663,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;
 }
 
@@ -2862,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();
@@ -3100,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_repl.cc b/sql/sql_repl.cc
--- a/sql/sql_repl.cc	2007-10-19 14:37:21 +04:00
+++ b/sql/sql_repl.cc	2007-10-30 14:45:14 +03:00
@@ -340,7 +340,7 @@ void mysql_binlog_send(THD* thd, char* l
 
   bzero((char*) &log,sizeof(log));
 
-  DBUG_ASSERT(thd->net.report_error == 0);
+  DBUG_ASSERT(thd->is_error() == 0);
 
 #ifndef DBUG_OFF
   if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2))
@@ -737,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;
@@ -1447,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;
@@ -1484,7 +1484,7 @@ bool show_binlog_info(THD* thd)
     if (protocol->write())
       DBUG_RETURN(TRUE);
   }
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 }
 
@@ -1566,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-19 14:37:22 +04:00
+++ b/sql/sql_select.cc	2007-10-30 14:45:14 +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"));
@@ -1030,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"));
@@ -1161,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"));
@@ -1184,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"));
@@ -1614,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);
       /*
@@ -1621,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) ||
@@ -2097,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;
@@ -2306,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();
@@ -2332,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 +9303,7 @@ Field *create_tmp_field(THD *thd, TABLE 
     result= item_sum->create_tmp_field(group, table, convert_blob_length);
     if (!result)
     {
-      DBUG_ASSERT(thd->net.report_error);
+      DBUG_ASSERT(thd->is_error());
       thd->fatal_error();
       my_error(ER_UNKNOWN_ERROR, MYF(0));
     }
@@ -10713,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);
 }
 
 
@@ -10867,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)
@@ -10899,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 &&
@@ -10929,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;
@@ -16024,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:45:14 +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-10-19 14:37:22 +04:00
+++ b/sql/sql_show.cc	2007-10-30 14:45:14 +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);
 }
 
@@ -787,7 +788,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST 
   if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
     DBUG_VOID_RETURN;
 
-  send_eof(thd);
+  my_eof(thd);
 
   DBUG_VOID_RETURN;
 }
@@ -1737,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;
 }
 
@@ -2902,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;
@@ -3247,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.
@@ -3399,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)
@@ -3600,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;
     }
@@ -4071,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;
     }
@@ -4263,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();
@@ -4296,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);
   }
@@ -4401,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);
   }
@@ -4484,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);
   }
@@ -4679,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);
   }
@@ -5217,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);
   }
@@ -6719,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-10-19 14:37:22 +04:00
+++ b/sql/sql_table.cc	2007-10-30 14:45:15 +03:00
@@ -4155,9 +4155,10 @@ static bool mysql_admin_table(THD* thd, 
         tmp_disable_binlog(thd); // binlogging is done by caller if wanted
         result_code= mysql_recreate_table(thd, table);
         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);
@@ -4269,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);
@@ -4357,7 +4360,7 @@ send_result_message:
       goto err;
   }
 
-  send_eof(thd);
+  my_eof(thd);
   DBUG_RETURN(FALSE);
 
  err:
@@ -7061,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_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:45:15 +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-10-19 14:37:22 +04:00
+++ b/sql/sql_update.cc	2007-10-30 14:45:15 +03:00
@@ -844,7 +844,7 @@ int mysql_update(THD *thd,
   }
   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 */
diff -Nrup a/sql/sql_view.cc b/sql/sql_view.cc
--- a/sql/sql_view.cc	2007-10-19 14:37:22 +04:00
+++ b/sql/sql_view.cc	2007-10-30 14:45:15 +03:00
@@ -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);
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:45:15 +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:45:15 +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:45:15 +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-10-19 14:37:22 +04:00
+++ b/sql/unireg.cc	2007-10-30 14:45:15 +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.report_error= 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:45:15 +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:45:15 +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.2582)konstantin30 Oct