diff options
author | sasha@mysql.sashanet.com <> | 2001-01-19 22:40:16 -0700 |
---|---|---|
committer | sasha@mysql.sashanet.com <> | 2001-01-19 22:40:16 -0700 |
commit | 634ba86ad7b781b62cbfc6545baa369145e1b37e (patch) | |
tree | 1a867ce93f7bc873347f776d08ae6607a8ba554a | |
parent | 45fa68611af37c2c474371645a1d4ccf2f97d1b3 (diff) | |
download | mariadb-git-634ba86ad7b781b62cbfc6545baa369145e1b37e.tar.gz |
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''
-rw-r--r-- | client/mysqltest.c | 45 | ||||
-rw-r--r-- | include/mysql.h | 4 | ||||
-rw-r--r-- | libmysql/libmysql.c | 65 | ||||
-rw-r--r-- | mysql-test/r/dirty-close.result | 4 | ||||
-rw-r--r-- | mysql-test/t/dirty-close.test | 10 | ||||
-rw-r--r-- | mysys/my_vsnprintf.c | 39 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 |
7 files changed, 159 insertions, 10 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index 5ea4194fc03..992583bb230 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -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"); @@ -1231,8 +1244,14 @@ 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; diff --git a/include/mysql.h b/include/mysql.h index 5c2646b592d..fbc30b0373f 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -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); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 5f4604701ae..52c76c4043a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -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) diff --git a/mysql-test/r/dirty-close.result b/mysql-test/r/dirty-close.result new file mode 100644 index 00000000000..f85b057eefa --- /dev/null +++ b/mysql-test/r/dirty-close.result @@ -0,0 +1,4 @@ +n +1 +2 +3 diff --git a/mysql-test/t/dirty-close.test b/mysql-test/t/dirty-close.test new file mode 100644 index 00000000000..69ee7162314 --- /dev/null +++ b/mysql-test/t/dirty-close.test @@ -0,0 +1,10 @@ +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; diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c index ac89e3bcf1a..030846ea63b 100644 --- a/mysys/my_vsnprintf.c +++ b/mysys/my_vsnprintf.c @@ -24,7 +24,6 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; - for (; *fmt ; fmt++) { if (fmt[0] != '%') @@ -38,10 +37,14 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) fmt++; while (isdigit(*fmt) || *fmt == '.' || *fmt == '-') fmt++; + if(*fmt == 'l') + fmt++; if (*fmt == 's') /* String parameter */ { reg2 char *par = va_arg(ap, char *); - uint plen = (uint) strlen(par); + uint plen; + if(!par) par = (char*)"(null)"; + plen = (uint) strlen(par); if ((uint) (end-to) > plen) /* Replace if possible */ { to=strmov(to,par); @@ -68,3 +71,35 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) *to='\0'; /* End of errmessage */ return (uint) (to - start); } + +#ifdef MAIN +static void my_printf(const char * fmt, ...) +{ + char buf[32]; + int n; + va_list ar; + va_start(ar, fmt); + n = my_vsnprintf(buf, sizeof(buf),fmt, ar); + printf(buf); + printf("n=%d, strlen=%d\n", n, strlen(buf)); + va_end(ar); +} + +int main() +{ + + my_printf("Hello\n"); + my_printf("Hello int, %d\n", 1); + my_printf("Hello string '%s'\n", "I am a string"); + my_printf("Hello hack hack hack hack hack hack hack %d\n", 1); + my_printf("Hello %d hack %d\n", 1, 4); + my_printf("Hello %d hack hack hack hack hack %d\n", 1, 4); + my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack"); + my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1); + my_printf("Hello %u\n", 1); + my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\ + `%-.64s' (%-.64s)", 1, 0,0,0,0); + return 0; +} +#endif + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d41ae6230a..1b46cc51bfc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -408,7 +408,7 @@ pthread_handler_decl(handle_one_connection,arg) { sql_print_error(ER(ER_NEW_ABORTING_CONNECTION), thd->thread_id,(thd->db ? thd->db : "unconnected"), - thd->user, + thd->user ? thd->user : "unauthenticated", (thd->host ? thd->host : thd->ip ? thd->ip : "unknown"), (net->last_errno ? ER(net->last_errno) : ER(ER_UNKNOWN_ERROR))); |