Commit 634ba86a authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com
Browse files

client/mysqltest.c

    added send/reap/dirty_close
include/mysql.h
    mysql_send_query()/mysql_reap_query()
libmysql/libmysql.c
    mysql_send_query()/mysql_reap_query()
mysys/my_vsnprintf.c
    fixed critical bug that codedumped when connection aborted
sql/sql_parse.cc
    0
mysql-test/r/dirty-close.result
    New BitKeeper file ``mysql-test/r/dirty-close.result''
mysql-test/t/dirty-close.test
    New BitKeeper file ``mysql-test/t/dirty-close.test''
parent 45fa6861
Loading
Loading
Loading
Loading
+38 −7
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <violite.h>

#define MAX_QUERY  65536
#define PAD_SIZE	128
@@ -71,6 +72,8 @@
#define MIN_VAR_ALLOC	  32
#define BLOCK_STACK_DEPTH  32
#define MAX_EXPECTED_ERRORS 10
#define QUERY_SEND  1
#define QUERY_REAP  2

static int record = 0, verbose = 0, silent = 0, opt_sleep=0;
static char *db = 0, *pass=0;
@@ -147,14 +150,14 @@ struct st_query
	 Q_SLEEP, Q_INC, Q_DEC,Q_SOURCE,
	 Q_DISCONNECT,Q_LET, Q_ECHO, Q_WHILE, Q_END_BLOCK,
	 Q_SYSTEM, Q_RESULT, Q_REQUIRE, Q_SAVE_MASTER_POS,
	 Q_SYNC_WITH_MASTER, Q_ERROR,
	 Q_SYNC_WITH_MASTER, Q_ERROR, Q_SEND, Q_REAP, Q_DIRTY_CLOSE,
	 Q_UNKNOWN, Q_COMMENT, Q_COMMENT_WITH_COMMAND} type;
};

const char *command_names[] = {
"connection", "query","connect","sleep","inc","dec","source","disconnect",
"let","echo","while","end","system","result", "require", "save_master_pos",
 "sync_with_master", "error", 0
 "sync_with_master", "error", "send", "reap", "dirty_close", 0
};

TYPELIB command_typelib= {array_elements(command_names),"",
@@ -661,6 +664,15 @@ int close_connection(struct st_query* q)
  {
    if (!strcmp(con->name, name))
    {
      if(q->type == Q_DIRTY_CLOSE)
	{
	  if(con->mysql.net.vio)
	    {
	      vio_delete(con->mysql.net.vio);
	      con->mysql.net.vio = 0;
	    }
	}
		
      mysql_close(&con->mysql);
      DBUG_RETURN(0);
    }
@@ -1211,7 +1223,7 @@ void reject_dump(const char* record_file, char* buf, int size)
}


int run_query(MYSQL* mysql, struct st_query* q)
int run_query(MYSQL* mysql, struct st_query* q, int flags)
{
  MYSQL_RES* res = 0;
  MYSQL_FIELD* fields;
@@ -1220,6 +1232,7 @@ int run_query(MYSQL* mysql, struct st_query* q)
  unsigned long* lengths;
  char* val;
  int len;
  int q_error = 0 ;
  DYNAMIC_STRING *ds;
  DYNAMIC_STRING ds_tmp;
  DBUG_ENTER("run_query");
@@ -1232,7 +1245,13 @@ int run_query(MYSQL* mysql, struct st_query* q)
  else
    ds= &ds_res;
  
  if (mysql_query(mysql, q->query))
  if((flags & QUERY_SEND) &&
    (q_error = mysql_send_query(mysql, q->query)))
    die("At line %u: unable to send query '%s'", start_lineno, q->query);
  if(!(flags & QUERY_REAP))
    return 0;
  
  if (mysql_reap_query(mysql))
  {
    if (q->require_file)
      abort_not_supported_test();
@@ -1416,7 +1435,9 @@ int main(int argc, char** argv)
      switch (q->type) {
      case Q_CONNECT: do_connect(q); break;
      case Q_CONNECTION: select_connection(q); break;
      case Q_DISCONNECT: close_connection(q); break;
      case Q_DISCONNECT:
      case Q_DIRTY_CLOSE:	
	close_connection(q); break;
      case Q_SOURCE: do_source(q); break;
      case Q_SLEEP: do_sleep(q); break;
      case Q_INC: do_inc(q); break;
@@ -1425,15 +1446,25 @@ int main(int argc, char** argv)
      case Q_SYSTEM: do_system(q); break;
      case Q_LET: do_let(q); break;
      case Q_QUERY:
      case Q_REAP:	
      {
	int flags = QUERY_REAP;
	if(q->type == Q_QUERY)
	  flags |= QUERY_SEND;
	
	if (save_file[0])
	{
	  strmov(q->record_file,save_file);
	  q->require_file=require_file;
	  save_file[0]=0;
	}
	error |= run_query(&cur_con->mysql, q); break;
	error |= run_query(&cur_con->mysql, q, QUERY_SEND|QUERY_REAP);
	break;
      }
      case Q_SEND:
	q->query += q->first_word_len;
	error |= run_query(&cur_con->mysql, q, QUERY_SEND);
	break;
      case Q_RESULT:
	get_file_name(save_file,q);
	require_file=0;
+4 −0
Original line number Diff line number Diff line
@@ -229,8 +229,12 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
void		STDCALL mysql_close(MYSQL *sock);
int		STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int		STDCALL mysql_query(MYSQL *mysql, const char *q);
int		STDCALL mysql_send_query(MYSQL *mysql, const char *q);
int		STDCALL mysql_reap_query(MYSQL *mysql);
int		STDCALL mysql_real_query(MYSQL *mysql, const char *q,
					unsigned int length);
int		STDCALL mysql_real_send_query(MYSQL *mysql, const char *q,
					unsigned int len);
int		STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
int		STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
int		STDCALL mysql_shutdown(MYSQL *mysql);
+65 −0
Original line number Diff line number Diff line
@@ -1708,6 +1708,71 @@ mysql_query(MYSQL *mysql, const char *query)
  return mysql_real_query(mysql,query, (uint) strlen(query));
}

int STDCALL
mysql_send_query(MYSQL* mysql, const char* query)
{
  return mysql_real_send_query(mysql, query, strlen(query));
}

/* send the query and return so we can do something else */
/* needs to be followed by mysql_reap_query() when we want to
   finish processing it
*/  
int STDCALL
mysql_real_send_query(MYSQL* mysql, const char* query, uint len)
{
  return simple_command(mysql, COM_QUERY, query, len, 1);
}

int STDCALL
mysql_reap_query(MYSQL* mysql)
{
  uchar *pos;
  ulong field_count;
  MYSQL_DATA *fields;
  uint len;
  DBUG_ENTER("mysql_reap_query");
  DBUG_PRINT("enter",("handle: %lx",mysql));
  if((len = net_safe_read(mysql)) == packet_error)
    DBUG_RETURN(-1);
  free_old_query(mysql);			/* Free old result */
 get_info:
  pos=(uchar*) mysql->net.read_pos;
  if ((field_count= net_field_length(&pos)) == 0)
    {
      mysql->affected_rows= net_field_length_ll(&pos);
      mysql->insert_id=	  net_field_length_ll(&pos);
      if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
	{
	  mysql->server_status=uint2korr(pos); pos+=2;
	}
      if (pos < mysql->net.read_pos+len && net_field_length(&pos))
	mysql->info=(char*) pos;
      DBUG_RETURN(0);
    }
  if (field_count == NULL_LENGTH)		/* LOAD DATA LOCAL INFILE */
    {
      int error=send_file_to_server(mysql,(char*) pos);
      if ((len=net_safe_read(mysql)) == packet_error || error)
	DBUG_RETURN(-1);
      goto get_info;				/* Get info packet */
    }
  if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
    mysql->server_status|= SERVER_STATUS_IN_TRANS;

  mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
  if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
    DBUG_RETURN(-1);
  if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
				    (uint) field_count,0,
				    (my_bool) test(mysql->server_capabilities &
						   CLIENT_LONG_FLAG))))
    DBUG_RETURN(-1);
  mysql->status=MYSQL_STATUS_GET_RESULT;
  mysql->field_count=field_count;
  DBUG_RETURN(0);

}

int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length)
+4 −0
Original line number Diff line number Diff line
n
1
2
3
+10 −0
Original line number Diff line number Diff line
connect (con1,localhost,root,,test,0,mysql-master.sock);
connect (con2,localhost,root,,test,0,mysql-master.sock);
connection con1;
dirty_close con1;
connection con2;
drop table if exists t1;
create table t1 (n int);
insert into t1 values (1),(2),(3);
select * from t1;
drop table t1;
Loading