From 287906e972266e9f629a8b53a7f6c46f22bac11a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Jan 2003 19:46:15 +0400 Subject: [PATCH 1/4] Fix for the QUOTE() function. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/func_str.result | 3 +++ mysql-test/t/func_str.test | 1 + sql/item_strfunc.cc | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index a55a5f46496..652ac3eb519 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -61,6 +61,7 @@ paul@teton.kitebird.com pem@mysql.com peter@linux.local peter@mysql.com +ram@mysql.r18.ru ram@ram.(none) ranger@regul.home.lan root@x3.internalnet diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 69e37d7b911..9e8f2b90f07 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -155,6 +155,9 @@ quote(concat('abc\'', '\\cba')) select quote(1/0), quote('\0\Z'); quote(1/0) quote('\0\Z') NULL '\0\Z' +select length(quote(concat(char(0),"test"))); +length(quote(concat(char(0),"test"))) +8 select reverse(""); reverse("") diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 717b9c86a07..f95cd901dfb 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -64,6 +64,7 @@ select decode(encode("abcdef","monty"),"monty")="abcdef"; select quote('\'\"\\test'); select quote(concat('abc\'', '\\cba')); select quote(1/0), quote('\0\Z'); +select length(quote(concat(char(0),"test"))); # # Wrong usage of functions diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index af533eefe9a..1d058a7d810 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2134,7 +2134,7 @@ String *Item_func_quote::val_str(String *str) */ to= (char*) str->ptr() + new_length - 1; *to--= '\''; - for (start= (char*) arg->ptr() ; end-- != start; to--) + for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) { /* We can't use the bitmask here as we want to replace \O and ^Z with 0 From 2d89861033074d5f801d7fc3a5720f20f9e03e6c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Jan 2003 15:17:16 +0200 Subject: [PATCH 2/4] Added support for max_allowed_packet in option files read by mysql_option() Extended max_allowed_packet for clients to 1G Fixed bug in sending compressed rows >= 16M Fix bug in skiping too long packets from clients. Added checking of wrong command number sent by client. include/mysql.h: Added max_allowed_packet as option parameter. include/mysql_com.h: Added COM_END to be able to check for wrong commands. libmysql/libmysql.c: Extended max_allowed_packet for clients to 1G Added support for max_allowed_packet in option files read by mysql_option() mysys/my_compress.c: Debugging output sql/net_pkg.cc: Fixed wrong handling of blobs >= 16M sql/net_serv.cc: Changed MAX_THREE_BYTES -> MAX_PACKET_LENGTH More DEBUG output and more comments Fixed bug in sending compressed rows >= 16M Optimized sending of big packets (fewer memcpy and compress data in bigger blocks) Fix bug in skiping too long packets from clients. (old code didn't always work for big packets) sql/sql_class.h: Changed type of variable sql/sql_parse.cc: Added checking of wrong command number sent by client. Changed handling of too big packets to make code safer tests/big_record.pl: E --- include/mysql.h | 1 + include/mysql_com.h | 16 +-- libmysql/libmysql.c | 14 ++- mysql-test/r/packet.result | 25 ++++ mysql-test/t/packet.test | 31 +++++ mysys/my_compress.c | 41 ++++--- sql/net_pkg.cc | 2 +- sql/net_serv.cc | 237 +++++++++++++++++++++++-------------- sql/sql_class.h | 2 +- sql/sql_parse.cc | 24 ++-- tests/big_record.pl | 57 +++++---- 11 files changed, 301 insertions(+), 149 deletions(-) create mode 100644 mysql-test/r/packet.result create mode 100644 mysql-test/t/packet.test diff --git a/include/mysql.h b/include/mysql.h index d581df91f64..8d497720a23 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -119,6 +119,7 @@ struct st_mysql_options { char *ssl_ca; /* PEM CA file */ char *ssl_capath; /* PEM directory of CA-s? */ char *ssl_cipher; /* cipher to use */ + unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; /* diff --git a/include/mysql_com.h b/include/mysql_com.h index a7e73405ac0..963c1212794 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -34,14 +34,14 @@ #define MYSQL_SERVICENAME "MySql" #endif /* __WIN__ */ -enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, - COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,COM_REFRESH, - COM_SHUTDOWN,COM_STATISTICS, - COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL, - COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT, - COM_CHANGE_USER, COM_BINLOG_DUMP, - COM_TABLE_DUMP, COM_CONNECT_OUT, - COM_REGISTER_SLAVE}; +enum enum_server_command { + COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, + COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS, + COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING, + COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP, + COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, + COM_END /* Must be last! */ +}; #define NOT_NULL_FLAG 1 /* Field can't be NULL */ #define PRI_KEY_FLAG 2 /* Field is part of a primary key */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 49c110c738d..152177c0fbe 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -60,7 +60,7 @@ static my_bool mysql_client_init=0; uint mysql_port=0; my_string mysql_unix_port=0; ulong net_buffer_length=8192; -ulong max_allowed_packet=16*1024*1024L; +ulong max_allowed_packet= 1024L*1024L*1024L; ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT; @@ -713,8 +713,8 @@ static const char *default_options[]= "character-sets-dir", "default-character-set", "interactive-timeout", "connect-timeout", "local-infile", "disable-local-infile", "replication-probe", "enable-reads-from-master", "repl-parse-query", - "ssl-cipher", - NullS + "ssl-cipher", "max-allowed-packet", + NullS }; static TYPELIB option_types={array_elements(default_options)-1, @@ -868,6 +868,9 @@ static void mysql_read_default_options(struct st_mysql_options *options, case 25: /* repl-parse-query */ options->rpl_parse= 1; break; + case 27: + options->max_allowed_packet= atoi(opt_arg); + break; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); } @@ -1908,6 +1911,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql->server_version,mysql->server_capabilities, mysql->server_status, client_flag)); + /* This needs to be changed as it's not useful with big packets */ int3store(buff+2,max_allowed_packet); if (user && user[0]) strmake(buff+5,user,32); /* Max user name */ @@ -1935,6 +1939,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, goto error; if (client_flag & CLIENT_COMPRESS) /* We will use compression */ net->compress=1; + if (mysql->options.max_allowed_packet) + net->max_packet_size= mysql->options.max_allowed_packet; if (db && mysql_select_db(mysql,db)) goto error; if (mysql->options.init_command) @@ -2302,7 +2308,7 @@ mysql_real_query(MYSQL *mysql, const char *query, ulong length) { DBUG_ENTER("mysql_real_query"); DBUG_PRINT("enter",("handle: %lx",mysql)); - DBUG_PRINT("query",("Query = \"%s\"",query)); + DBUG_PRINT("query",("Query = '%-.4096s'",query)); if (mysql_send_query(mysql,query,length)) DBUG_RETURN(-1); diff --git a/mysql-test/r/packet.result b/mysql-test/r/packet.result new file mode 100644 index 00000000000..e994e4d63da --- /dev/null +++ b/mysql-test/r/packet.result @@ -0,0 +1,25 @@ +set global max_allowed_packet=100; +set max_allowed_packet=100; +set global net_buffer_length=100; +set net_buffer_length=100; +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +len +1024 +select repeat('a',200); +repeat('a',200) +NULL +select @@net_buffer_length, @@max_allowed_packet; +@@net_buffer_length @@max_allowed_packet +1024 80 +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +Got a packet bigger than 'max_allowed_packet' +set global max_allowed_packet=default; +set max_allowed_packet=default; +set global net_buffer_length=default; +set net_buffer_length=default; +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +len +100 +select length(repeat('a',200)); +length(repeat('a',200)) +200 diff --git a/mysql-test/t/packet.test b/mysql-test/t/packet.test new file mode 100644 index 00000000000..5c4e7efcaf3 --- /dev/null +++ b/mysql-test/t/packet.test @@ -0,0 +1,31 @@ + +# +# Check protocol handling +# + +connect (con1,localhost,root,,); + +connection con1; +set global max_allowed_packet=100; +set max_allowed_packet=100; +set global net_buffer_length=100; +set net_buffer_length=100; +# Have to be > 1024 as min value of net_buffer_length is 1024 +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +# Should return NULL as 200 is bigger than max_allowed_packet +select repeat('a',200); + +# +# Connection 2 should get error for too big packets +# +connect (con2,localhost,root,,); +connection con2; +select @@net_buffer_length, @@max_allowed_packet; +--error 1153 +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +set global max_allowed_packet=default; +set max_allowed_packet=default; +set global net_buffer_length=default; +set net_buffer_length=default; +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +select length(repeat('a',200)); diff --git a/mysys/my_compress.c b/mysys/my_compress.c index 1e46584d525..dd076311188 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -32,24 +32,28 @@ my_bool my_compress(byte *packet, ulong *len, ulong *complen) { + DBUG_ENTER("my_compress"); if (*len < MIN_COMPRESS_LENGTH) + { *complen=0; + DBUG_PRINT("note",("Packet too short: Not compressed")); + } else { byte *compbuf=my_compress_alloc(packet,len,complen); if (!compbuf) - return *complen ? 0 : 1; + DBUG_RETURN(*complen ? 0 : 1); memcpy(packet,compbuf,*len); my_free(compbuf,MYF(MY_WME)); } - return 0; + DBUG_RETURN(0); } byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen) { byte *compbuf; - *complen = *len * 120 / 100 + 12; - if (!(compbuf = (byte *) my_malloc(*complen,MYF(MY_WME)))) + *complen= *len * 120 / 100 + 12; + if (!(compbuf= (byte *) my_malloc(*complen,MYF(MY_WME)))) return 0; /* Not enough memory */ if (compress((Bytef*) compbuf,(ulong *) complen, (Bytef*) packet, (uLong) *len ) != Z_OK) @@ -59,31 +63,36 @@ byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen) } if (*complen >= *len) { - *complen=0; - my_free(compbuf,MYF(MY_WME)); + *complen= 0; + my_free(compbuf, MYF(MY_WME)); + DBUG_PRINT("note",("Packet got longer on compression; Not compressed")); return 0; } - swap(ulong,*len,*complen); /* *len is now packet length */ + swap(ulong, *len, *complen); /* *len is now packet length */ return compbuf; } my_bool my_uncompress (byte *packet, ulong *len, ulong *complen) { + DBUG_ENTER("my_uncompress"); if (*complen) /* If compressed */ { - byte *compbuf = (byte *) my_malloc (*complen,MYF(MY_WME)); + byte *compbuf= (byte *) my_malloc(*complen,MYF(MY_WME)); + int error; if (!compbuf) - return 1; /* Not enough memory */ - if (uncompress((Bytef*) compbuf, complen, (Bytef*) packet, *len) != Z_OK) + DBUG_RETURN(1); /* Not enough memory */ + if ((error=uncompress((Bytef*) compbuf, complen, (Bytef*) packet, *len)) + != Z_OK) { /* Probably wrong packet */ - my_free (compbuf,MYF(MY_WME)); - return 1; + DBUG_PRINT("error",("Can't uncompress packet, error: %d",error)); + my_free(compbuf, MYF(MY_WME)); + DBUG_RETURN(1); } - *len = *complen; - memcpy(packet,compbuf,*len); - my_free(compbuf,MYF(MY_WME)); + *len= *complen; + memcpy(packet, compbuf, *len); + my_free(compbuf, MYF(MY_WME)); } - return 0; + DBUG_RETURN(0); } #endif /* HAVE_COMPRESS */ diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 8bb601cebcf..afedba6a259 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -222,7 +222,7 @@ net_store_length(char *pkg, ulonglong length) } *packet++=254; int8store(packet,length); - return (char*) packet+9; + return (char*) packet+8; } char * diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 49454c9df2c..19f68e0b631 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -73,9 +73,9 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; #include "thr_alarm.h" #define TEST_BLOCKING 8 -#define MAX_THREE_BYTES (256L*256L*256L-1) +#define MAX_PACKET_LENGTH (256L*256L*256L-1) -static int net_write_buff(NET *net,const char *packet,ulong len); +static my_bool net_write_buff(NET *net,const char *packet,ulong len); /* Init with packet info */ @@ -131,12 +131,16 @@ static my_bool net_realloc(NET *net, ulong length) { uchar *buff; ulong pkt_length; + DBUG_ENTER("net_realloc"); + DBUG_PRINT("enter",("length: %lu", length)); + if (length >= net->max_packet_size) { - DBUG_PRINT("error",("Packet too large (%lu)", length)); + DBUG_PRINT("error",("Packet too large. Max sixe: %lu", + net->max_packet_size)); net->error=1; net->last_errno=ER_NET_PACKET_TOO_LARGE; - return 1; + DBUG_RETURN(1); } pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); /* @@ -151,11 +155,11 @@ static my_bool net_realloc(NET *net, ulong length) #ifdef MYSQL_SERVER net->last_errno=ER_OUT_OF_RESOURCES; #endif - return 1; + DBUG_RETURN(1); } net->buff=net->write_pos=buff; net->buff_end=buff+(net->max_packet=pkt_length); - return 0; + DBUG_RETURN(0); } /* Remove unwanted characters from connection */ @@ -217,13 +221,13 @@ my_net_write(NET *net,const char *packet,ulong len) { uchar buff[NET_HEADER_SIZE]; /* - Big packets are handled by splitting them in packets of MAX_THREE_BYTES - length. The last packet is always a packet that is < MAX_THREE_BYTES. - (The last packet may even have a lengt of 0) + Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH + length. The last packet is always a packet that is < MAX_PACKET_LENGTH. + (The last packet may even have a length of 0) */ - while (len >= MAX_THREE_BYTES) + while (len >= MAX_PACKET_LENGTH) { - const ulong z_size = MAX_THREE_BYTES; + const ulong z_size = MAX_PACKET_LENGTH; int3store(buff, z_size); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) || @@ -238,7 +242,7 @@ my_net_write(NET *net,const char *packet,ulong len) if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) return 1; DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE); - return net_write_buff(net,packet,len); + return test(net_write_buff(net,packet,len)); } /* @@ -256,64 +260,107 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) ulong length=len+1; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; + DBUG_ENTER("net_write_command"); + DBUG_PRINT("enter",("length: %lu", len)); + buff[4]=command; /* For first packet */ - if (length >= MAX_THREE_BYTES) + if (length >= MAX_PACKET_LENGTH) { /* Take into account that we have the command in the first header */ - len= MAX_THREE_BYTES -1; + len= MAX_PACKET_LENGTH -1; do { - int3store(buff, MAX_THREE_BYTES); + int3store(buff, MAX_PACKET_LENGTH); buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff, header_size) || net_write_buff(net,packet,len)) - return 1; + DBUG_RETURN(1); packet+= len; - length-= MAX_THREE_BYTES; - len=MAX_THREE_BYTES; - header_size=NET_HEADER_SIZE; - } while (length >= MAX_THREE_BYTES); + length-= MAX_PACKET_LENGTH; + len= MAX_PACKET_LENGTH; + header_size= NET_HEADER_SIZE; + } while (length >= MAX_PACKET_LENGTH); len=length; /* Data left to be written */ } int3store(buff,length); buff[3]= (uchar) net->pkt_nr++; - return test(net_write_buff(net,(char*) buff,header_size) || - net_write_buff(net,packet,len) || net_flush(net)); + DBUG_RETURN(test(net_write_buff(net,(char*) buff,header_size) || + net_write_buff(net,packet,len) || net_flush(net))); } /* Caching the data in a local buffer before sending it. - One can force the buffer to be flushed with 'net_flush'. + SYNOPSIS + net_write_buff() + net Network handler + packet Packet to send + len Length of packet + + DESCRIPTION + Fill up net->buffer and send it to the client when full. + + If the rest of the to-be-sent-packet is bigger than buffer, + send it in one big block (to avoid copying to internal buffer). + If not, copy the rest of the data to the buffer and return without + sending data. + + NOTES + The cached buffer can be sent as it is with 'net_flush()'. + + In this code we have to be careful to not send a packet longer than + MAX_PACKET_LENGTH to net_real_write() if we are using the compressed protocol + as we store the length of the compressed packet in 3 bytes. + + RETURN + 0 ok + 1 */ -static int +static my_bool net_write_buff(NET *net,const char *packet,ulong len) { - ulong left_length=(ulong) (net->buff_end - net->write_pos); + ulong left_length; + if (net->compress && net->max_packet > MAX_PACKET_LENGTH) + left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff); + else + left_length= (ulong) (net->buff_end - net->write_pos); if (len > left_length) { - memcpy((char*) net->write_pos,packet,left_length); - if (net_real_write(net,(char*) net->buff,net->max_packet)) - return 1; - net->write_pos=net->buff; - packet+=left_length; - len-= left_length; - left_length= net->max_packet; - - /* Send out rest of the blocks as full sized blocks */ - while (len > left_length) + if (net->write_pos != net->buff) { - if (net_real_write(net, packet, left_length)) + /* Fill up already used packet and write it */ + memcpy((char*) net->write_pos,packet,left_length); + if (net_real_write(net,(char*) net->buff, + (ulong) (net->write_pos - net->buff) + left_length)) return 1; + net->write_pos= net->buff; packet+= left_length; len-= left_length; } + if (net->compress) + { + /* + We can't have bigger packets than 16M with compression + Because the uncompressed length is stored in 3 bytes + */ + left_length= MAX_PACKET_LENGTH; + while (len > left_length) + { + if (net_real_write(net, packet, left_length)) + return 1; + packet+= left_length; + len-= left_length; + } + } + if (len > net->max_packet) + return net_real_write(net, packet, len) ? 1 : 0; + /* Send out rest of the blocks as full sized blocks */ } memcpy((char*) net->write_pos,packet,len); - net->write_pos+=len; + net->write_pos+= len; return 0; } @@ -364,11 +411,7 @@ net_real_write(NET *net,const char *packet,ulong len) memcpy(b+header_length,packet,len); if (my_compress((byte*) b+header_length,&len,&complen)) - { - DBUG_PRINT("warning", - ("Compression error; Continuing without compression")); complen=0; - } int3store(&b[NET_HEADER_SIZE],complen); int3store(b,len); b[3]=(uchar) (net->compress_pkt_nr++); @@ -469,28 +512,15 @@ net_real_write(NET *net,const char *packet,ulong len) *****************************************************************************/ #ifndef NO_ALARM -/* - Help function to clear the commuication buffer when we get a too - big packet -*/ -static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) +static my_bool net_safe_read(NET *net, char *buff, uint32 length, + thr_alarm_t *alarmed) { - ALARM alarm_buff; uint retry_count=0; - my_bool old_mode; - uint32 old=remain; - - if (!thr_alarm_in_use(&alarmed)) + while (length > 0) { - if (!thr_alarm(alarmed,net->read_timeout,&alarm_buff) || - vio_blocking(net->vio, TRUE, &old_mode) < 0) - return; /* Can't setup, abort */ - } - while (remain > 0) - { - ulong length; - if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L) + int tmp; + if ((tmp=vio_read(net->vio,(char*) net->buff, length)) <= 0) { my_bool interrupted = vio_should_retry(net->vio); if (!thr_got_alarm(&alarmed) && interrupted) @@ -498,17 +528,60 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) if (retry_count++ < net->retry_count) continue; } - return; + return 1; } - remain -= (uint32) length; - if (!remain && old==MAX_THREE_BYTES && - (length=vio_read(net->vio,(char*) net->buff,NET_HEADER_SIZE))) - { - old=remain= uint3korr(net->buff); - net->pkt_nr++; - } - statistic_add(bytes_received,length,&LOCK_bytes_received); + length-= tmp; } + return 0; +} + +/* + Help function to clear the commuication buffer when we get a too big packet. + + SYNOPSIS + my_net_skip_rest() + net Communication handle + remain Bytes to read + alarmed Parameter for thr_alarm() + alarm_buff Parameter for thr_alarm() + + RETURN VALUES + 0 Was able to read the whole packet + 1 Got mailformed packet from client +*/ + +static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, + ALARM *alarm_buff) +{ + uint32 old=remain; + DBUG_ENTER("my_net_skip_rest"); + DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain)); + + if (!thr_alarm_in_use(&alarmed)) + { + my_bool old_mode; + if (!thr_alarm(alarmed,net->read_timeout, alarm_buff) || + vio_blocking(net->vio, TRUE, &old_mode) < 0) + DBUG_RETURN(1); /* Can't setup, abort */ + } + for (;;) + { + while (remain > 0) + { + uint length= min(remain, net->max_packet); + if (net_safe_read(net, (char*) net->buff, length, alarmed)) + DBUG_RETURN(1); + statistic_add(bytes_received, length, &LOCK_bytes_received); + remain -= (uint32) length; + } + if (old != MAX_PACKET_LENGTH) + break; + if (net_safe_read(net, (char*) net->buff, NET_HEADER_SIZE, alarmed)) + DBUG_RETURN(1); + old=remain= uint3korr(net->buff); + net->pkt_nr++; + } + DBUG_RETURN(0); } #endif /* NO_ALARM */ @@ -607,9 +680,8 @@ my_real_read(NET *net, ulong *complen) continue; } #endif - DBUG_PRINT("error",("Couldn't read packet: remain: %lu errno: %d length: %ld alarmed: %d", - remain,vio_errno(net->vio), length, - thr_got_alarm(&alarmed))); + DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld", + remain, vio_errno(net->vio), length)); len= packet_error; net->error=2; /* Close socket */ #ifdef MYSQL_SERVER @@ -667,19 +739,12 @@ my_real_read(NET *net, ulong *complen) { if (net_realloc(net,helping)) { -#ifdef MYSQL_SERVER -#ifndef NO_ALARM - if (net->compress) - { - len= packet_error; - goto end; - } - my_net_skip_rest(net, (uint32) len, &alarmed); - len=0; -#endif -#else - len= packet_error; /* Return error */ +#if defined(MYSQL_SERVER) && !defined(NO_ALARM) + if (!net->compress && + !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) + net->error= 3; /* Successfully skiped packet */ #endif + len= packet_error; /* Return error and close connection */ goto end; } } @@ -723,7 +788,7 @@ my_net_read(NET *net) { #endif len = my_real_read(net,&complen); - if (len == MAX_THREE_BYTES) + if (len == MAX_PACKET_LENGTH) { /* First packet of a multi-packet. Concatenate the packets */ ulong save_pos = net->where_b; @@ -733,7 +798,7 @@ my_net_read(NET *net) net->where_b += len; total_length += len; len = my_real_read(net,&complen); - } while (len == MAX_THREE_BYTES); + } while (len == MAX_PACKET_LENGTH); if (len != packet_error) len+= total_length; net->where_b = save_pos; @@ -791,7 +856,7 @@ my_net_read(NET *net) else start_of_packet+= read_length + NET_HEADER_SIZE; - if (read_length != MAX_THREE_BYTES) /* last package */ + if (read_length != MAX_PACKET_LENGTH) /* last package */ { multi_byte_packet= 0; /* No last zero len packet */ break; diff --git a/sql/sql_class.h b/sql/sql_class.h index 8c4a7b83ebf..af80c3e31ac 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -358,7 +358,7 @@ public: uint client_capabilities; /* What the client supports */ /* Determines if which non-standard SQL behaviour should be enabled */ uint sql_mode; - uint max_client_packet_length; + ulong max_client_packet_length; ulong master_access; /* Global privileges from mysql.user */ ulong db_access; /* Privileges for current db */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0f072a73ac6..599c31d43ca 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -75,7 +75,8 @@ const char *command_name[]={ "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB", "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist", "Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user", - "Binlog Dump","Table Dump", "Connect Out", "Register Slave" + "Binlog Dump","Table Dump", "Connect Out", "Register Slave", + "Error" // Last command number }; bool volatile abort_slave = 0; @@ -209,7 +210,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, !(thd->client_capabilities & CLIENT_LONG_PASSWORD),&ur); DBUG_PRINT("info", - ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", + ("Capabilities: %d packet_length: %ld Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_client_packet_length, thd->host_or_ip, thd->priv_user, passwd[0] ? "yes": "no", @@ -882,20 +883,22 @@ bool do_command(THD *thd) net_new_transaction(net); if ((packet_length=my_net_read(net)) == packet_error) { - DBUG_PRINT("info",("Got error reading command from socket %s", - vio_description(net->vio) )); - return TRUE; - } - else if (!packet_length) - { + DBUG_PRINT("info",("Got error %d reading command from socket %s", + net->error, + vio_description(net->vio))); + /* Check if we can continue without closing the connection */ + if (net->error != 3) + DBUG_RETURN(TRUE); // We have to close it. send_error(net,net->last_errno,NullS); - net->error=0; + net->error= 0; DBUG_RETURN(FALSE); } else { packet=(char*) net->read_pos; command = (enum enum_server_command) (uchar) packet[0]; + if (command >= COM_END) + command= COM_END; // Wrong command DBUG_PRINT("info",("Command on %s = %d (%s)", vio_description(net->vio), command, command_name[command])); @@ -1025,7 +1028,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); mysql_log.write(thd,command,"%s",thd->query); - DBUG_PRINT("query",("%s",thd->query)); + DBUG_PRINT("query",("%-.4096s",thd->query)); /* thd->query_length is set by mysql_parse() */ mysql_parse(thd,thd->query,packet_length); if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1223,6 +1226,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_CONNECT: // Impossible here case COM_TIME: // Impossible from client case COM_DELAYED_INSERT: + case COM_END: default: send_error(net, ER_UNKNOWN_COM_ERROR); break; diff --git a/tests/big_record.pl b/tests/big_record.pl index 52d3dca5f7b..08547b50823 100755 --- a/tests/big_record.pl +++ b/tests/big_record.pl @@ -1,58 +1,69 @@ #!/usr/bin/perl -# This is a test with stores big records in a blob +# This is a test with stores big records in a blob. # Note that for the default test the mysql server should have been -# started with at least 'mysqld -O max_allowed_packet=200k' - -$host= shift || ""; -$test_db="test"; -$opt_user=$opt_password=""; +# started with at least 'mysqld -O max_allowed_packet=30M' and you should have +# at least 256M memory in your computer. use DBI; -$|= 1; # Autoflush +use Getopt::Long; -$table="test_big_record"; -$rows=20; # Test of blobs up to ($rows-1)*10000+1 bytes +$opt_host=""; +$opt_user=$opt_password=""; +$opt_db="test"; +$opt_rows=200; # Test of blobs up to ($rows-1)*100000+1 bytes +$opt_compress=0; +$opt_table="test_big_record"; + +GetOptions("host=s","db=s","user=s", "password=s", "table=s", "rows=i", + "compress") || die "Aborted"; print "Connection to database $test_db\n"; -$dbh = DBI->connect("DBI:mysql:$test_db:$host",$opt_user,$opt_password) || die "Can't connect: $DBI::errstr\n"; +$extra_options=""; +$extra_options.=":mysql_compression=1" if ($opt_compress); -$dbh->do("drop table if exists $table"); +$dbh = DBI->connect("DBI:mysql:$opt_db:$host$extra_options",$opt_user,$opt_password) || die "Can't connect: $DBI::errstr\n"; -print "Creating table $table\n"; +$dbh->do("drop table if exists $opt_table"); + +print "Creating table $opt_table\n"; ($dbh->do("\ -CREATE TABLE $table ( +CREATE TABLE $opt_table ( auto int(5) unsigned NOT NULL DEFAULT '0' auto_increment, - test mediumblob, + test longblob, PRIMARY KEY (auto))")) or die $DBI::errstr; -print "Inserting $rows records\n"; +print "Inserting $opt_rows records\n"; -for ($i=0 ; $i < $rows ; $i++) +$|=1; # Flush output to stdout to be able to monitor process + +for ($i=0 ; $i < $opt_rows ; $i++) { - $tmp= chr(65+$i) x ($i*10000+1); + $tmp= chr(65+($i % 16)) x ($i*100000+1); + print $i," ",length($tmp),"\n"; $tmp= $dbh->quote($tmp); - $dbh->do("insert into $table (test) values ($tmp)") or die $DBI::errstr; + $dbh->do("insert into $opt_table (test) values ($tmp)") or die $DBI::errstr; } -print "Testing records\n"; +print "Reading records\n"; + +$sth=$dbh->prepare("select * from $opt_table", { "mysql_use_result" => 1}) or die $dbh->errstr; -$sth=$dbh->prepare("select * from $table") or die $dbh->errstr; $sth->execute() or die $sth->errstr; $i=0; while (($row = $sth->fetchrow_arrayref)) { print $row->[0]," ",length($row->[1]),"\n"; - die "Record $i had wrong data in blob" if ($row->[1] ne (chr(65+$i)) x ($i*10000+1)); + die "Record $i had wrong data in blob" if ($row->[1] ne (chr(65+($i % 16)) x ($i*100000+1))); $i++; } -die "Didn't get all rows from server" if ($i != $rows); +die "Didn't get all rows from server" if ($i != $opt_rows); -$dbh->do("drop table $table") or die $DBI::errstr; +$dbh->do("drop table $opt_table") or die $DBI::errstr; print "Test ok\n"; exit 0; From 79fba6da8f099566bbf711b592aab60909b1f66d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Jan 2003 18:19:48 +0200 Subject: [PATCH 3/4] Changed shared lib version to 12 as some structures has changed --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 195cf6be4e1..9e3a8ffc516 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 # See the libtool docs for information on how to do shared lib versions. -SHARED_LIB_VERSION=11:0:0 +SHARED_LIB_VERSION=12:0:0 # Set all version vars based on $VERSION. How do we do this more elegant ? # Remember that regexps needs to quote [ and ] since this is run through m4 From e3c7f4d85ec4caf59fc408cf5643e5dc64e9a3d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 5 Jan 2003 20:18:49 +0200 Subject: [PATCH 4/4] A lot of portability fixes. Added rename table for BDB. This fixes a bug in ALTER TABLE with BDB tables. BUILD/SETUP.sh: Enabled uninitalized warnings for debug builds. Build-tools/Do-compile: Added options --no-mysqltest and --no-benchmarks Log time before each stage Removed warnings on some OS (at least hpux11) acinclude.m4: Fixed call to wrong function configure.in: Don't use -O3 as compiler option with aCC innobase/include/univ.i: Removed compiler warning (on Hpux11) innobase/os/os0file.c: Removed compiler warning (on Hpux11) innobase/trx/trx0sys.c: Removed compiler warning (on Hpux11) innobase/trx/trx0trx.c: Removed compiler warning (on Hpux11) innobase/ut/ut0ut.c: Removed compiler warning (with gcc) myisam/mi_check.c: Added missing 'static' myisam/mi_test1.c: Added missing 'static' mysys/my_getopt.c: Added missing 'static' sql/ha_berkeley.cc: Added rename table. This fixes a bug in ALTER TABLE with BDB tables. Fixed compilation problem on OSF1 sql/ha_berkeley.h: Added rename table. This fixes a bug in ALTER TABLE with BDB tables. sql/mini_client.cc: Added reinterpret cast to avoid some warnings. sql/sql_parse.cc: Added reinterpret cast to avoid some warnings. Removed usage of strnlen() as this gave portability problems. sql/sql_union.cc: Added reinterpret cast to avoid some warnings. sql/table.cc: Added reinterpret cast to avoid some warnings. tools/mysqlmanager.c: Added missing 'static' --- BUILD/SETUP.sh | 2 +- Build-tools/Do-compile | 53 ++++++++++++++++++++++++++++++++--------- acinclude.m4 | 2 +- configure.in | 5 +++- innobase/include/univ.i | 1 + innobase/os/os0file.c | 2 +- innobase/trx/trx0sys.c | 6 ++--- innobase/trx/trx0trx.c | 2 +- innobase/ut/ut0ut.c | 1 - myisam/mi_check.c | 2 +- myisam/mi_test1.c | 2 +- mysys/my_getopt.c | 4 ++-- sql/ha_berkeley.cc | 24 +++++++++++++++++-- sql/ha_berkeley.h | 1 + sql/mini_client.cc | 11 ++++++--- sql/sql_parse.cc | 11 +++++---- sql/sql_union.cc | 2 +- sql/table.cc | 2 +- tools/mysqlmanager.c | 2 +- 19 files changed, 99 insertions(+), 36 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 859150c3954..9a092b84a8f 100644 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -48,7 +48,7 @@ fast_cflags="-O3 -fno-omit-frame-pointer" # this is one is for someone who thinks 1% speedup is worth not being # able to backtrace reckless_cflags="-O3 -fomit-frame-pointer " -debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -O1" +debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS -DSAFEMALLOC -DPEDANTIC_SAFEMALLOC -DSAFE_MUTEX -O1 -Wuninitialized" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti" diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 52c1951f48f..4351a4f69f4 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -8,7 +8,7 @@ use Getopt::Long; $opt_distribution=$opt_user=$opt_config_env=""; $opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix=""; $opt_tmp=$opt_version_suffix=""; -$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=0; +$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=0; $opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=0; GetOptions( @@ -30,7 +30,9 @@ GetOptions( "no-crash-me", "no-perl", "no-strip", - "no-test|no-mysqltest", + "no-test", + "no-mysqltest", + "no-benchmark", "perl-files=s", "perl-options=s", "raid", @@ -148,6 +150,7 @@ select STDOUT; $|=1; info("Compiling MySQL$opt_version_suffix at $host$opt_suffix, stage: $opt_stage\n"); +log_timestamp(); if (-x "$host/bin/mysqladmin") { @@ -161,6 +164,7 @@ kill_all("mysqlmanager"); if ($opt_stage == 0) { + log_timestamp(); print "$host: Removing old distribution\n" if ($opt_debug); if (!$opt_use_old_distribution) { @@ -209,6 +213,7 @@ safe_cd("$pwd/$host/$ver"); if ($opt_stage <= 1) { # Fix files if this is in another timezone than the build host + log_timestamp(); unlink("config.cache"); unlink("bdb/build_unix/config.cache"); unlink("innobase/config.cache"); @@ -252,6 +257,7 @@ if ($opt_stage <= 1) if ($opt_stage <= 2) { my ($command); + log_timestamp(); unlink($opt_distribution) if ($opt_delete && !$opt_use_old_distribution); $command=$make; $command.= " $opt_make_options" if (defined($opt_make_options) && $opt_make_options ne ""); @@ -264,6 +270,7 @@ if ($opt_stage <= 2) if ($opt_stage <= 3) { my $flags= ""; + log_timestamp(); log_system("rm -fr mysql-3* mysql-4* $pwd/$host/*.tar.gz"); log_system("nm -n sql/mysqld | gzip -9 -v 2>&1 > sql/mysqld.sym.gz | cat"); @@ -292,6 +299,7 @@ if (!defined($tar_file)) # if ($opt_stage <= 4 && !$opt_no_test) { + log_timestamp(); rm_all(<$pwd/$host/test/*>); safe_cd("$pwd/$host/test"); safe_system("gunzip < $tar_file | $tar xf -"); @@ -305,8 +313,9 @@ $ENV{"LD_LIBRARY_PATH"}= "$test_dir/lib:" . $ENV{"LD_LIBRARY_PATH"}; # # Run the test suite # -if ($opt_stage <= 5 && !$opt_no_test) +if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest) { + log_timestamp(); system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir); safe_cd("${test_dir}/mysql-test"); check_system("./mysql-test-run --warnings --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful"); @@ -315,7 +324,7 @@ if ($opt_stage <= 5 && !$opt_no_test) # # Start the server if we are going to run any of the benchmarks # -if (!$opt_no_test) +if (!$opt_no_test && !$opt_no_benchmark) { my $extra; safe_cd($test_dir); @@ -339,8 +348,10 @@ if (!$opt_no_test) # # Compile and install the required Perl modules # -if ($opt_stage <= 7 && $opt_perl_files && !$opt_no_perl && !$opt_no_test) +if ($opt_stage <= 7 && $opt_perl_files && !$opt_no_perl && !$opt_no_test && + !$opt_no_benchmark) { + log_timestamp(); safe_cd($test_dir); rm_all("perl"); safe_system("mkdir perl"); @@ -376,6 +387,7 @@ if ($opt_stage <= 7 && $opt_perl_files && !$opt_no_perl && !$opt_no_test) # if ($opt_stage <= 8 && !$opt_no_test && !$opt_no_crash_me) { + log_timestamp(); safe_cd("$test_dir/sql-bench"); log_system("rm -f limits/mysql.cfg"); safe_system("perl ./crash-me --force --batch-mode $connect_option"); @@ -384,8 +396,9 @@ if ($opt_stage <= 8 && !$opt_no_test && !$opt_no_crash_me) # # Run sql-bench Benchmarks # -if ($opt_stage <= 9 && !$opt_no_test) +if ($opt_stage <= 9 && !$opt_no_test && !$opt_no_benchmark) { + log_timestamp(); safe_cd("$test_dir/sql-bench"); log_system("rm -f output/*"); $tmp= $opt_fast_benchmark ? "--fast --user root --small-test" : ""; @@ -469,7 +482,13 @@ Do not run the "crash-me" test Do not strip the binaries included in the binary distribution --no-test -Do not run any tests +Do not run any tests. + +--no-benchmark +Do not run the benchmark test (written in perl) + +--no-mysqltest +Do not run the the mysql-test-run test (Same as 'make test') --perl-files=list of files Compile and install the given perl modules. @@ -532,6 +551,7 @@ sub abort my($mail_header_file); print LOG "\n$message\n"; print "$host: $message\n" if ($opt_debug); + print LOG "Aborting\n"; close LOG; if ($opt_user) @@ -547,7 +567,6 @@ sub abort unlink($mail_header_file); unlink("$log.mail"); } - print LOG "Aborting\n"; exit 1; } @@ -689,9 +708,10 @@ sub rm_all sub kill_all { my ($pattern) = @_; - my ($USER,$BSD,$LINUX, $pscmd, $user, $pid); + my ($USER,$BSD,$LINUX, $pscmd, $user, $os, $pid); $user=$ENV{'USER'}; - $BSD = -f '/vmunix' || $ENV{"OS"} eq "SunOS4" || $^O eq 'darwin'; + $os=defined($ENV{'OS'}) ? $ENV{'OS'} : "unknown"; + $BSD = -f '/vmunix' || $os eq "SunOS4" || $^O eq 'darwin'; $LINUX = $^O eq 'linux'; $pscmd = $BSD ? "/bin/ps -auxww" : $LINUX ? "/bin/ps axuw" : "/bin/ps -ef"; @@ -707,7 +727,7 @@ sub kill_all { chop($cand); ($pid_user, $pid) = split(' ', $cand); - next if $pid == $$; + next if $pid eq $$; next process if (! ($cand =~ $pattern) || $pid_user ne $user); print LOG "Killing $_\n"; &killpid($pid); @@ -730,3 +750,14 @@ sub killpid } print LOG "$pid will not die!\n"; } + +# +# return the current date as a string (YYYY-MM-DD HH:MM:SS) +# +sub log_timestamp +{ + my @ta=localtime(time()); + print LOG sprintf("%4d-%02d-%02d %02d:%02d:%02d\n", + $ta[5]+1900, $ta[4]+1, $ta[3], $ta[2], $ta[1], $ta[0]); + +} diff --git a/acinclude.m4 b/acinclude.m4 index 7436b5136a5..cf0233fa38f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -623,7 +623,7 @@ main() FILE *file=fopen("conftestval", "w"); f = (float) ll; fprintf(file,"%g\n",f); - close(file); + fclose(file); exit (0); }], ac_cv_conv_longlong_to_float=`cat conftestval`, ac_cv_conv_longlong_to_float=0, ifelse([$2], , , ac_cv_conv_longlong_to_float=$2))])dnl if test "$ac_cv_conv_longlong_to_float" = "1" -o "$ac_cv_conv_longlong_to_float" = "yes" diff --git a/configure.in b/configure.in index 9e3a8ffc516..0375cc61235 100644 --- a/configure.in +++ b/configure.in @@ -879,6 +879,7 @@ int main() # MAX_C_OPTIMIZE="-O3" +MAX_CXX_OPTIMIZE="-O3" case $SYSTEM_TYPE in *solaris2.7*) @@ -946,6 +947,8 @@ case $SYSTEM_TYPE in then CFLAGS="$CFLAGS +DD64 -DHAVE_BROKEN_INLINE" CXXFLAGS="$CXXFLAGS +DD64 +O2" + MAX_C_OPTIMIZE="" + MAX_CXX_OPTIMIZE="" fi ;; *rhapsody*) @@ -1404,7 +1407,7 @@ if test "$ac_cv_prog_cxx_g" = "yes" then DEBUG_CXXFLAGS="-g" DEBUG_OPTIMIZE_CXX="-O" - OPTIMIZE_CXXFLAGS="-O3" + OPTIMIZE_CXXFLAGS="$MAX_CXX_OPTIMIZE" else DEBUG_CXXFLAGS="-g" DEBUG_OPTIMIZE_CXX="" diff --git a/innobase/include/univ.i b/innobase/include/univ.i index 43130549eae..bf606efcf64 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -57,6 +57,7 @@ of the 32-bit x86 assembler in mutex operations. */ Microsoft Visual C++ */ #if !defined(__GNUC__) && !defined(__WIN__) +#undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */ #define UNIV_MUST_NOT_INLINE #endif diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 9eae358c7fb..fa5482a8cd1 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -2127,7 +2127,7 @@ os_aio_simulated_handle( ulint offs; ulint lowest_offset; byte* combined_buf; - byte* combined_buf2; + byte* combined_buf2= 0; /* Remove warning */ ibool ret; ulint n; ulint i; diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index 33c962772e8..0c10040847e 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -472,9 +472,9 @@ trx_sys_update_mysql_binlog_offset( if (0 != ut_memcmp(sys_header + field + TRX_SYS_MYSQL_LOG_NAME, file_name, 1 + ut_strlen(file_name))) { - mlog_write_string(sys_header + field - + TRX_SYS_MYSQL_LOG_NAME, - file_name, 1 + ut_strlen(file_name), mtr); + mlog_write_string((byte*) (sys_header + field + + TRX_SYS_MYSQL_LOG_NAME), + (byte*) file_name, 1 + ut_strlen(file_name), mtr); } if (mach_read_from_4(sys_header + field diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index f0077f941de..d2219ed019f 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -99,7 +99,7 @@ trx_create( trx->mysql_log_file_name = NULL; trx->mysql_log_offset = 0; - trx->mysql_master_log_file_name = ""; + trx->mysql_master_log_file_name = (char*) ""; trx->mysql_master_log_pos = 0; trx->ignore_duplicates_in_insert = FALSE; diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index ff5d11d84ed..bb5eb662cd7 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -197,7 +197,6 @@ ut_get_year_month_day( *month = (ulint)cal_tm.wMonth; *day = (ulint)cal_tm.wDay; #else - struct tm cal_tm; struct tm* cal_tm_ptr; time_t tm; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index d1165899bea..540f3c92ad3 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3650,7 +3650,7 @@ void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, } -ha_checksum mi_byte_checksum(const byte *buf, uint length) +static ha_checksum mi_byte_checksum(const byte *buf, uint length) { ha_checksum crc; const byte *end=buf+length; diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index bcb9cd172ec..8ea97c8e489 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -57,7 +57,7 @@ int main(int argc,char *argv[]) } -int run_test(const char *filename) +static int run_test(const char *filename) { MI_INFO *file; int i,j,error,deleted,rec_length,uniques=0; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index b2ee6e0f373..21adb9374ce 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -572,7 +572,7 @@ static longlong eval_num_suffix (char *argument, int *error, char *option_name) In case of an error, set error value in *err. */ -longlong getopt_ll (char *arg, const struct my_option *optp, int *err) +static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) { longlong num; @@ -596,7 +596,7 @@ longlong getopt_ll (char *arg, const struct my_option *optp, int *err) values. */ -static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err) +static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { ulonglong num; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 06acf4fa2e3..2154fbd7a32 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -1921,6 +1921,26 @@ int ha_berkeley::delete_table(const char *name) DBUG_RETURN(error); } +int ha_berkeley::rename_table(const char * from, const char * to) +{ + int error; + char from_buff[FN_REFLEN]; + char to_buff[FN_REFLEN]; + + if ((error= db_create(&file, db_env, 0))) + my_errno= error; + else + { + /* On should not do a file->close() after rename returns */ + error= file->rename(file, + fn_format(from_buff, from, "", ha_berkeley_ext, 2 | 4), + NULL, fn_format(to_buff, to, "", ha_berkeley_ext, + 2 | 4), 0); + } + return error; +} + + /* How many seeks it will take to read through the table This is to be comparable to the number returned by records_in_range so @@ -2080,7 +2100,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt) free(stat); stat=0; } - if (key_file[i]->stat(key_file[i], (void*) &stat, 0, 0)) + if ((key_file[i]->stat)(key_file[i], (void*) &stat, 0, 0)) goto err; /* purecov: inspected */ share->rec_per_key[i]= (stat->bt_ndata / (stat->bt_nkeys ? stat->bt_nkeys : 1)); @@ -2093,7 +2113,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt) free(stat); stat=0; } - if (file->stat(file, (void*) &stat, 0, 0)) + if ((file->stat)(file, (void*) &stat, 0, 0)) goto err; /* purecov: inspected */ } pthread_mutex_lock(&share->mutex); diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index f2a81d123f1..d2dc5e3216d 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -152,6 +152,7 @@ class ha_berkeley: public handler int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); int delete_table(const char *name); + int rename_table(const char* from, const char* to); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 5600983817b..38b3c22b91b 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -542,10 +542,13 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, bzero((char*) &UNIXaddr,sizeof(UNIXaddr)); UNIXaddr.sun_family = AF_UNIX; strmov(UNIXaddr.sun_path, unix_socket); - if (mc_sock_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr), + if (mc_sock_connect(sock, + my_reinterpret_cast(struct sockaddr *) (&UNIXaddr), + sizeof(UNIXaddr), mysql->options.connect_timeout) <0) { - DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno)); + DBUG_PRINT("error",("Got error %d on connect to local server", + socket_errno)); net->last_errno=CR_CONNECTION_ERROR; sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno); goto error; @@ -632,7 +635,9 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, my_gethostbyname_r_free(); } sock_addr.sin_port = (ushort) htons((ushort) port); - if (mc_sock_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), + if (mc_sock_connect(sock, + my_reinterpret_cast(struct sockaddr *) (&sock_addr), + sizeof(sock_addr), mysql->options.connect_timeout) <0) { DBUG_PRINT("error",("Got error %d on connect to '%s'", diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 599c31d43ca..a0336d0b50b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -497,7 +497,8 @@ check_connections(THD *thd) { vio_in_addr(net->vio,&thd->remote.sin_addr); thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors); - thd->host[strnlen(thd->host, HOSTNAME_LENGTH)]= 0; + /* Cut very long hostnames to avoid possible overflows */ + thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0; if (connect_errors > max_connect_errors) return(ER_HOST_IS_BLOCKED); } @@ -2012,7 +2013,8 @@ mysql_execute_command(void) goto error; } walk->lock_type= auxi->lock_type; - auxi->table= (TABLE *) walk; // Remember corresponding table + // Store address to table as we need it later + auxi->table= my_reinterpret_cast(TABLE *) (walk); } if (add_item_to_list(new Item_null())) { @@ -2025,7 +2027,8 @@ mysql_execute_command(void) break; /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) - auxi->table= ((TABLE_LIST*) auxi->table)->table; + auxi->table= (my_reinterpret_cast(TABLE_LIST*) (auxi->table))->table; + if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) { @@ -3321,7 +3324,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) } else aux->shared=1; // Mark that it's used twice - aux->table=(TABLE *) cursor; + aux->table= my_reinterpret_cast(TABLE *) (cursor); } } } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8cead6596b4..4e36ccafefc 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -52,7 +52,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { if (cursor->do_redirect) // False if CUBE/ROLLUP { - cursor->table= ((TABLE_LIST*) cursor->table)->table; + cursor->table= (my_reinterpret_cast(TABLE_LIST*) (cursor->table))->table; cursor->do_redirect= 0; } } diff --git a/sql/table.cc b/sql/table.cc index 62163819599..7e284c89871 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -144,7 +144,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, bzero((char*) keyinfo,n_length); outparam->key_info=keyinfo; outparam->max_key_length= outparam->total_key_length= 0; - key_part= (KEY_PART_INFO*) (keyinfo+keys); + key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys); strpos=disk_buff+6; ulong *rec_per_key; diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c index e6fab63c5b3..790a5d56b5a 100644 --- a/tools/mysqlmanager.c +++ b/tools/mysqlmanager.c @@ -1241,7 +1241,7 @@ static void handle_child(int __attribute__((unused)) sig) signal(SIGCHLD,handle_child); } -struct manager_thd* manager_thd_new(Vio* vio) +static struct manager_thd* manager_thd_new(Vio* vio) { struct manager_thd* tmp; if (!(tmp=(struct manager_thd*)my_malloc(sizeof(*tmp),