1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Reworked compressed and protocol implementation,

including fixes for conc-31 and conc-34
- Added win64 fixes in protocol (changed ulong to size_t)

modified:
  include/my_sys.h
  include/mysql_com.h
  include/violite.h
  libmariadb/libmariadb.c
  libmariadb/my_compress.c
  libmariadb/my_stmt.c
  libmariadb/my_thr_init.c
  libmariadb/net.c
  libmariadb/violite.c
  unittest/libmariadb/basic-t.c
  unittest/libmariadb/charset.c
  unittest/libmariadb/thread.c
unknown:
  xx
  libmariadb/libmariadb.so.1
  mariadb_config/mariadb_config
  mariadb_config/mariadb_config.c
  unittest/libmariadb/basic-t
  unittest/libmariadb/charset
  unittest/libmariadb/connection
  unittest/libmariadb/cursor
  unittest/libmariadb/errors
  unittest/libmariadb/fetch
  unittest/libmariadb/logs
  unittest/libmariadb/misc
  unittest/libmariadb/ps
  unittest/libmariadb/ps_bugs
  unittest/libmariadb/ps_new
  unittest/libmariadb/result
  unittest/libmariadb/sp
  unittest/libmariadb/sqlite3
  unittest/libmariadb/ssl
  unittest/libmariadb/thread
  unittest/libmariadb/view
This commit is contained in:
holzboote@googlemail.com
2013-07-01 05:00:34 +02:00
parent 71e3fc726f
commit dc16f2d32e
12 changed files with 254 additions and 129 deletions

View File

@@ -616,9 +616,9 @@ void load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv); int *argc, char ***argv);
void free_defaults(char **argv); void free_defaults(char **argv);
void print_defaults(const char *conf_file, const char **groups); void print_defaults(const char *conf_file, const char **groups);
my_bool my_compress(unsigned char *, ulong *, ulong *); my_bool my_compress(unsigned char *, size_t *, size_t *);
my_bool my_uncompress(unsigned char *, ulong *, ulong *); my_bool my_uncompress(unsigned char *, size_t *, size_t *);
unsigned char *my_compress_alloc(const unsigned char *packet, ulong *len, ulong *complen); unsigned char *my_compress_alloc(const unsigned char *packet, size_t *len, size_t *complen);
ulong checksum(const unsigned char *mem, uint count); ulong checksum(const unsigned char *mem, uint count);
#if defined(_MSC_VER) && !defined(_WIN32) #if defined(_MSC_VER) && !defined(_WIN32)

View File

@@ -317,7 +317,7 @@ int net_flush(NET *net);
int my_net_write(NET *net,const char *packet, size_t len); int my_net_write(NET *net,const char *packet, size_t len);
int net_write_command(NET *net,unsigned char command,const char *packet, int net_write_command(NET *net,unsigned char command,const char *packet,
size_t len); size_t len);
int net_real_write(NET *net,const char *packet,unsigned long len); int net_real_write(NET *net,const char *packet, size_t len);
unsigned long my_net_read(NET *net); unsigned long my_net_read(NET *net);
struct rand_struct { struct rand_struct {

View File

@@ -69,11 +69,8 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
* vio_read and vio_write should have the same semantics * vio_read and vio_write should have the same semantics
* as read(2) and write(2). * as read(2) and write(2).
*/ */
int vio_read( Vio* vio, size_t vio_read(Vio* vio, gptr buf, size_t size);
gptr buf, int size); size_t vio_write(Vio* vio, const gptr buf, size_t size);
int vio_write( Vio* vio,
const gptr buf,
int size);
/* /*
* Whenever the socket is set to blocking mode or not. * Whenever the socket is set to blocking mode or not.
*/ */

View File

@@ -417,7 +417,7 @@ restart:
my_set_error(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, 0); my_set_error(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, 0);
} }
mysql->server_status= ~SERVER_MORE_RESULTS_EXIST; mysql->server_status&= ~SERVER_MORE_RESULTS_EXIST;
DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno, DBUG_PRINT("error",("Got error: %d (%s)", net->last_errno,
net->last_error)); net->last_error));

View File

@@ -29,7 +29,7 @@
** *complen is 0 if the packet wasn't compressed ** *complen is 0 if the packet wasn't compressed
*/ */
my_bool my_compress(unsigned char *packet, ulong *len, ulong *complen) my_bool my_compress(unsigned char *packet, size_t *len, size_t *complen)
{ {
if (*len < MIN_COMPRESS_LENGTH) if (*len < MIN_COMPRESS_LENGTH)
*complen=0; *complen=0;
@@ -39,12 +39,13 @@ my_bool my_compress(unsigned char *packet, ulong *len, ulong *complen)
if (!compbuf) if (!compbuf)
return *complen ? 0 : 1; return *complen ? 0 : 1;
memcpy(packet,compbuf,*len); memcpy(packet,compbuf,*len);
my_free(compbuf,MYF(MY_WME)); } my_free(compbuf,MYF(MY_WME));
}
return 0; return 0;
} }
unsigned char *my_compress_alloc(const unsigned char *packet, ulong *len, ulong *complen) unsigned char *my_compress_alloc(const unsigned char *packet, size_t *len, size_t *complen)
{ {
unsigned char *compbuf; unsigned char *compbuf;
*complen = *len * 120 / 100 + 12; *complen = *len * 120 / 100 + 12;
@@ -67,7 +68,7 @@ unsigned char *my_compress_alloc(const unsigned char *packet, ulong *len, ulong
} }
my_bool my_uncompress (unsigned char *packet, ulong *len, ulong *complen) my_bool my_uncompress (unsigned char *packet, size_t *len, size_t *complen)
{ {
if (*complen) /* If compressed */ if (*complen) /* If compressed */
{ {

View File

@@ -1436,8 +1436,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
DBUG_PRINT("info",("request_len=%ld", request_len)); DBUG_PRINT("info",("request_len=%ld", request_len));
ret= test(simple_command(stmt->mysql, MYSQL_COM_STMT_EXECUTE, request, request_len, 1, stmt) || ret= test(simple_command(stmt->mysql, MYSQL_COM_STMT_EXECUTE, request, request_len, 1, stmt) ||
(stmt->mysql->methods->db_read_stmt_result && stmt->mysql->methods->db_read_stmt_result(stmt->mysql))); (stmt->mysql && stmt->mysql->methods->db_read_stmt_result && stmt->mysql->methods->db_read_stmt_result(stmt->mysql)));
if (request) if (request)
my_free(request, MYF(0)); my_free(request, MYF(0));

View File

@@ -22,6 +22,7 @@
#include "mysys_priv.h" #include "mysys_priv.h"
#include <m_string.h> #include <m_string.h>
#include <dbug.h>
#ifdef THREAD #ifdef THREAD
#ifdef USE_TLS #ifdef USE_TLS
@@ -123,49 +124,41 @@ static long thread_id=0;
my_bool my_thread_init(void) my_bool my_thread_init(void)
{ {
struct st_my_thread_var *tmp; struct st_my_thread_var *tmp;
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX) my_bool rc= 0;
pthread_mutex_lock(&THR_LOCK_lock);
#endif
#if !defined(_WIN32) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys)) if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{ {
pthread_mutex_unlock(&THR_LOCK_lock); DBUG_PRINT("info", ("my_thread_init was already called. Thread id: %lu",
pthread_self()));
return 0; /* Safequard */ return 0; /* Safequard */
} }
/* We must have many calloc() here because these are freed on /* We must have many calloc() here because these are freed on
pthread_exit */ pthread_exit */
if (!(tmp=(struct st_my_thread_var *) if (!(tmp=(struct st_my_thread_var *)
calloc(1,sizeof(struct st_my_thread_var)))) calloc(1,sizeof(struct st_my_thread_var))))
{ {
pthread_mutex_unlock(&THR_LOCK_lock);
return 1; return 1;
} }
pthread_setspecific(THR_KEY_mysys,tmp); pthread_setspecific(THR_KEY_mysys,tmp);
#else
tmp= &THR_KEY_mysys;
if (tmp->initialized) /* Already initialized */ if (tmp->initialized) /* Already initialized */
{ {
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_unlock(&THR_LOCK_lock);
#endif
return 0; return 0;
} }
tmp= &THR_KEY_mysys;
#endif
tmp->id= ++thread_id;
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL); pthread_cond_init(&tmp->suspend, NULL);
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX) pthread_mutex_lock(&THR_LOCK_lock);
tmp->id= ++thread_id;
pthread_mutex_unlock(&THR_LOCK_lock); pthread_mutex_unlock(&THR_LOCK_lock);
#endif
tmp->initialized= TRUE; tmp->initialized= TRUE;
return 0; return 0;
} }
void my_thread_end(void) void my_thread_end(void)
{ {
struct st_my_thread_var *tmp=my_thread_var; struct st_my_thread_var *tmp=
my_pthread_getspecific(struct st_my_thread_var *, THR_KEY_mysys);
if (tmp && tmp->initialized) if (tmp && tmp->initialized)
{ {
#if !defined(DBUG_OFF) #if !defined(DBUG_OFF)

View File

@@ -110,11 +110,12 @@ int my_net_init(NET *net, Vio* vio)
return 1; return 1;
if (net_buffer_length > max_allowed_packet) if (net_buffer_length > max_allowed_packet)
max_allowed_packet=net_buffer_length; max_allowed_packet=net_buffer_length;
net->max_packet_size= 0xFFFFFF;
net->buff_end=net->buff+(net->max_packet=net_buffer_length); net->buff_end=net->buff+(net->max_packet=net_buffer_length);
net->vio = vio; net->vio = vio;
net->error=0; net->return_status=0; net->error=0; net->return_status=0;
net->read_timeout=(uint) net_read_timeout; /* Timeout for read */ net->read_timeout=(uint) net_read_timeout; /* Timeout for read */
net->pkt_nr=0; net->compress_pkt_nr= net->pkt_nr= 0;
net->write_pos=net->read_pos = net->buff; net->write_pos=net->read_pos = net->buff;
net->last_error[0]= net->sqlstate[0] =0; net->last_error[0]= net->sqlstate[0] =0;
@@ -173,7 +174,7 @@ static my_bool net_realloc(NET *net, size_t length)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#if defined(DBUG_OFF) || defined(USE_NET_CLEAR) #if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
static int net_check_if_data_available(Vio *vio) static int net_check_if_data_available(Vio *vio)
{ {
my_socket sd= vio->sd; my_socket sd= vio->sd;
@@ -185,7 +186,7 @@ static int net_check_if_data_available(Vio *vio)
FD_SET(sd, &sockset); FD_SET(sd, &sockset);
memset(&tv, 0, sizeof(tv)); memset(&tv, 0, sizeof(tv));
rc= select(sd + 1, &sockset, NULL, NULL, &tv); rc= select((int)(sd + 1), &sockset, NULL, NULL, &tv);
if (rc <= 0) if (rc <= 0)
return 0; return 0;
return FD_ISSET(sd, &sockset); return FD_ISSET(sd, &sockset);
@@ -196,7 +197,7 @@ static int net_check_if_data_available(Vio *vio)
void net_clear(NET *net) void net_clear(NET *net)
{ {
#if defined(DBUG_OFF) || defined(USE_NET_CLEAR) #if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
int available= 0; int available= 0;
size_t count; /* One may get 'unused' warning */ size_t count; /* One may get 'unused' warning */
bool is_blocking=vio_is_blocking(net->vio); bool is_blocking=vio_is_blocking(net->vio);
@@ -204,7 +205,7 @@ void net_clear(NET *net)
DBUG_ENTER("net_clear"); DBUG_ENTER("net_clear");
while ((available= net_check_if_data_available(net->vio)) > 0) while ((available= net_check_if_data_available(net->vio)) > 0)
{ {
if ((count= vio_read(net->vio, (char *)net->buff, net->max_packet))) if ((long)(count= vio_read(net->vio, (char *)net->buff, net->max_packet)) > 0)
{ {
DBUG_PRINT("info",("skipped %d bytes from file: %s", DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio))); count,vio_description(net->vio)));
@@ -235,7 +236,7 @@ void net_clear(NET *net)
#else #else
DBUG_ENTER("net_clear"); DBUG_ENTER("net_clear");
#endif #endif
net->pkt_nr=0; /* Ready for new command */ net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff; net->write_pos=net->buff;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -253,6 +254,8 @@ int net_flush(NET *net)
(uint) (net->write_pos - net->buff)); (uint) (net->write_pos - net->buff));
net->write_pos=net->buff; net->write_pos=net->buff;
} }
if (net->compress)
net->pkt_nr= net->compress_pkt_nr;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@@ -273,17 +276,24 @@ int
my_net_write(NET *net, const char *packet, size_t len) my_net_write(NET *net, const char *packet, size_t len)
{ {
uchar buff[NET_HEADER_SIZE]; uchar buff[NET_HEADER_SIZE];
if (len >= MAX_PACKET_LENGTH) while (len >= MAX_PACKET_LENGTH)
{ {
net->error=1; const ulong max_len= MAX_PACKET_LENGTH;
net->last_errno=ER_NET_PACKET_TOO_LARGE; int3store(buff,max_len);
return 1; buff[3]= (uchar)net->pkt_nr++;
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE) ||
net_write_buff(net, packet, max_len))
return 1;
packet+= max_len;
len-= max_len;
} }
int3store(buff,len); /* write last remaining packet, size can be zero */
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); int3store(buff, len);
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) buff[3]= (uchar)net->pkt_nr++;
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE) ||
net_write_buff(net, packet, len))
return 1; return 1;
return net_write_buff(net,packet,len); return 0;
} }
int int
@@ -327,7 +337,13 @@ net_write_command(NET *net, uchar command,
static int static int
net_write_buff(NET *net,const char *packet, size_t len) net_write_buff(NET *net,const char *packet, size_t len)
{ {
size_t left_length=(size_t) (net->buff_end - net->write_pos); size_t left_length;
if (net->max_packet > MAX_PACKET_LENGTH &&
net->compress)
left_length= (size_t)(MAX_PACKET_LENGTH - (net->write_pos - net->buff));
else
left_length=(size_t) (net->buff_end - net->write_pos);
if (len > left_length) if (len > left_length)
{ {
@@ -341,6 +357,19 @@ net_write_buff(NET *net,const char *packet, size_t len)
len-=left_length; len-=left_length;
net->write_pos= net->buff; net->write_pos= net->buff;
} }
if (net->compress)
{
/* uncompressed length is stored in 3 bytes,so
packet can't be > 0xFFFFFF */
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) if (len > net->max_packet)
return(test(net_real_write(net, packet, len))); return(test(net_real_write(net, packet, len)));
} }
@@ -352,9 +381,9 @@ net_write_buff(NET *net,const char *packet, size_t len)
/* Read and write using timeouts */ /* Read and write using timeouts */
int int
net_real_write(NET *net,const char *packet,ulong len) net_real_write(NET *net,const char *packet,size_t len)
{ {
int length; size_t length;
char *pos,*end; char *pos,*end;
thr_alarm_t alarmed; thr_alarm_t alarmed;
#if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2) #if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2)
@@ -371,16 +400,14 @@ net_real_write(NET *net,const char *packet,ulong len)
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
if (net->compress) if (net->compress)
{ {
ulong complen; size_t complen;
uchar *b; uchar *b;
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE, if (!(b=(uchar*) my_malloc(len + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
MYF(MY_WME)))) MYF(MY_WME))))
{ {
#ifdef MYSQL_SERVER
net->last_errno=ER_OUT_OF_RESOURCES; net->last_errno=ER_OUT_OF_RESOURCES;
net->error=2; net->error=2;
#endif
net->reading_or_writing=0; net->reading_or_writing=0;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@@ -394,25 +421,18 @@ net_real_write(NET *net,const char *packet,ulong len)
} }
int3store(&b[NET_HEADER_SIZE],complen); int3store(&b[NET_HEADER_SIZE],complen);
int3store(b,len); int3store(b,len);
b[3]=(uchar) (net->pkt_nr++); b[3]=(uchar) (net->compress_pkt_nr++);
len+= header_length; len+= header_length;
packet= (char*) b; packet= (char*) b;
} }
#endif /* HAVE_COMPRESS */ #endif /* HAVE_COMPRESS */
/* DBUG_DUMP("net",packet,len); */
#ifdef MYSQL_SERVER
thr_alarm_init(&alarmed);
if (net_blocking)
thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
#else
alarmed=0; alarmed=0;
#endif /* MYSQL_SERVER */
pos=(char*) packet; end=pos+len; pos=(char*) packet; end=pos+len;
while (pos != end) while (pos != end)
{ {
if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0) if ((long) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
{ {
my_bool interrupted = vio_should_retry(net->vio); my_bool interrupted = vio_should_retry(net->vio);
#if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2)) #if (!defined(_WIN32) && !defined(__EMX__) && !defined(OS2))
@@ -432,6 +452,8 @@ net_real_write(NET *net,const char *packet,ulong len)
my_progname,vio_errno(net->vio)); my_progname,vio_errno(net->vio));
#endif /* EXTRA_DEBUG */ #endif /* EXTRA_DEBUG */
net->error=2; /* Close socket */ net->error=2; /* Close socket */
net->last_errno= (interrupted ?
ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE);
goto end; goto end;
} }
} }
@@ -459,10 +481,8 @@ net_real_write(NET *net,const char *packet,ulong len)
} }
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
net->error=2; /* Close socket */ net->error=2; /* Close socket */
#ifdef MYSQL_SERVER
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
ER_NET_ERROR_ON_WRITE); ER_NET_ERROR_ON_WRITE);
#endif /* MYSQL_SERVER */
break; break;
} }
pos+=length; pos+=length;
@@ -648,7 +668,7 @@ my_real_read(NET *net, size_t *complen)
#endif #endif
goto end; goto end;
} }
net->pkt_nr++; net->compress_pkt_nr= ++net->pkt_nr;
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
if (net->compress) if (net->compress)
{ {
@@ -692,7 +712,7 @@ end:
ulong my_net_read(NET *net) ulong my_net_read(NET *net)
{ {
ulong len,complen; size_t len,complen;
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
if (!net->compress) if (!net->compress)
@@ -720,58 +740,62 @@ ulong my_net_read(NET *net)
return len; return len;
#ifdef HAVE_COMPRESS #ifdef HAVE_COMPRESS
} }
if (net->remain_in_buf) else
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
for (;;)
{ {
if (net->remain_in_buf) if (net->remain_in_buf)
{ {
uchar *pos = net->buff + net->buf_length - net->remain_in_buf; /* restore 0 character */
if (net->remain_in_buf >= 4) net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
{
net->length = uint3korr(pos);
if (net->length <= net->remain_in_buf - 4)
{
/* We have a full packet */
len=net->length;
net->remain_in_buf -= net->length + 4;
net->read_pos=pos + 4;
break; /* We have a full packet */
}
}
/* Move data down to read next data packet after current one */
if (net->buf_length != net->remain_in_buf)
{
memmove(net->buff,pos,net->remain_in_buf);
net->buf_length=net->remain_in_buf;
}
net->where_b=net->buf_length;
} }
else for (;;)
{ {
net->where_b=0; if (net->remain_in_buf)
net->buf_length=0; {
} uchar *pos = net->buff + net->buf_length - net->remain_in_buf;
if (net->remain_in_buf >= 4)
{
net->length = uint3korr(pos);
if (net->length <= net->remain_in_buf - 4)
{
/* We have a full packet */
len=net->length;
net->remain_in_buf -= net->length + 4;
net->read_pos=pos + 4;
break; /* We have a full packet */
}
}
/* Move data down to read next data packet after current one */
if (net->buf_length != net->remain_in_buf)
{
memmove(net->buff,pos,net->remain_in_buf);
net->buf_length=net->remain_in_buf;
}
net->where_b=net->buf_length;
}
else
{
net->where_b=0;
net->buf_length=0;
}
if ((len = my_real_read(net,(size_t *)&complen)) == packet_error) if ((len = my_real_read(net,(size_t *)&complen)) == packet_error)
break; break;
if (my_uncompress((unsigned char*) net->buff + net->where_b, &len, &complen)) if (my_uncompress((unsigned char*) net->buff + net->where_b, &len, &complen))
{ {
len= packet_error; len= packet_error;
net->error=2; /* caller will close socket */ net->error=2; /* caller will close socket */
#ifdef MYSQL_SERVER net->last_errno=ER_NET_UNCOMPRESS_ERROR;
net->last_errno=ER_NET_UNCOMPRESS_ERROR; break;
#endif }
break; net->buf_length+=len;
net->remain_in_buf+=len;
}
if (len != packet_error)
{
net->save_char= net->read_pos[len]; /* Must be saved */
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
} }
net->buf_length+=len;
net->remain_in_buf+=len;
} }
if (len != packet_error)
{
net->save_char= net->read_pos[len]; /* Must be saved */
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
}
return len;
#endif #endif
return len;
} }

View File

@@ -186,12 +186,12 @@ int vio_errno(Vio *vio __attribute__((unused)))
} }
int vio_read(Vio * vio, gptr buf, int size) size_t vio_read(Vio * vio, gptr buf, size_t size)
{ {
int r; size_t r;
DBUG_ENTER("vio_read"); DBUG_ENTER("vio_read");
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size)); DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (vio->type == VIO_TYPE_SSL) if (vio->type == VIO_TYPE_SSL)
{ {
@@ -219,19 +219,19 @@ int vio_read(Vio * vio, gptr buf, int size)
r = read(vio->sd, buf, size); r = read(vio->sd, buf, size);
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (r < 0) if ((size_t)r == -1)
{ {
DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno)); DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
} }
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
DBUG_PRINT("exit", ("%d", r)); DBUG_PRINT("exit", ("%u", (uint)r));
DBUG_RETURN(r); DBUG_RETURN(r);
} }
int vio_write(Vio * vio, const gptr buf, int size) size_t vio_write(Vio * vio, const gptr buf, size_t size)
{ {
int r; size_t r;
DBUG_ENTER("vio_write"); DBUG_ENTER("vio_write");
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size)); DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
@@ -259,12 +259,12 @@ int vio_write(Vio * vio, const gptr buf, int size)
r = write(vio->sd, buf, size); r = write(vio->sd, buf, size);
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (r < 0) if ((size_t)r == -1)
{ {
DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno)); DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
} }
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
DBUG_PRINT("exit", ("%d", r)); DBUG_PRINT("exit", ("%u", (uint)r));
DBUG_RETURN(r); DBUG_RETURN(r);
} }

View File

@@ -530,7 +530,32 @@ static int test_reconnect_maxpackage(MYSQL *my)
return OK; return OK;
} }
static int test_compressed(MYSQL *my)
{
int rc;
MYSQL *mysql= mysql_init(NULL);
MYSQL_RES *res;
char *query;
mysql_options(mysql, MYSQL_OPT_COMPRESS, (void *)1);
FAIL_IF(!mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname,
CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS), mysql_error(mysql));
mysql->reconnect= 1;
rc= mysql_query(mysql, "SHOW VARIABLES");
check_mysql_rc(rc, mysql);
if ((res= mysql_store_result(mysql)))
mysql_free_result(res);
mysql_close(mysql);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_compressed", test_compressed, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_reconnect_maxpackage", test_reconnect_maxpackage, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_reconnect_maxpackage", test_reconnect_maxpackage, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL}, {"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL},

View File

@@ -543,6 +543,7 @@ static int test_bug30472(MYSQL *mysql)
} }
/* Retrieve character set information. */ /* Retrieve character set information. */
mysql_set_character_set(mysql, "latin1");
bug30472_retrieve_charset_info(mysql, bug30472_retrieve_charset_info(mysql,
character_set_name_1, character_set_name_1,
character_set_client_1, character_set_client_1,
@@ -572,6 +573,7 @@ static int test_bug30472(MYSQL *mysql)
FAIL_UNLESS(strcmp(character_set_results_2, "utf8") == 0, "cs_result != ut8"); FAIL_UNLESS(strcmp(character_set_results_2, "utf8") == 0, "cs_result != ut8");
FAIL_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0, "collation != utf8_general_ci"); FAIL_UNLESS(strcmp(collation_connnection_2, "utf8_general_ci") == 0, "collation != utf8_general_ci");
diag("%s %s", character_set_name_1, character_set_name_2);
FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0, "cs_name1 = cs_name2"); FAIL_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0, "cs_name1 = cs_name2");
FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0, "cs_client1 = cs_client2"); FAIL_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0, "cs_client1 = cs_client2");
FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0, "cs_result1 = cs_result2"); FAIL_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0, "cs_result1 = cs_result2");
@@ -580,6 +582,7 @@ static int test_bug30472(MYSQL *mysql)
/* Call mysql_change_user() with the same username, password, database. */ /* Call mysql_change_user() with the same username, password, database. */
rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test"); rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
mysql_set_character_set(mysql, "latin1");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
/* Retrieve character set information. */ /* Retrieve character set information. */

View File

@@ -36,22 +36,105 @@ static int basic_connect(MYSQL *mysql)
return OK; return OK;
} }
pthread_mutex_t LOCK_test;
#ifndef _WIN32
int thread_conc27(void);
#else
DWORD WINAPI thread_conc27(void);
#endif
#define THREAD_NUM 100
static int test_conc_27(MYSQL *mysql) static int test_conc_27(MYSQL *mysql)
{ {
int rc; int rc;
int i;
MYSQL_ROW row;
MYSQL_RES *res;
#ifndef _WIN32
pthread_t threads[THREAD_NUM];
#else
HANDLE hthreads[THREAD_NUM];
DWORD threads[THREAD_NUM];
#endif
mysql_thread_init(); rc= mysql_query(mysql, "DROP TABLE IF EXISTS t_conc27");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "SET @a:=1"); rc= mysql_query(mysql, "CREATE TABLE t_conc27(a int)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO t_conc27 VALUES(0)");
check_mysql_rc(rc, mysql);
pthread_mutex_init(&LOCK_test, NULL);
for (i=0; i < THREAD_NUM; i++)
{
#ifndef _WIN32
pthread_create(&threads[i], NULL, (void *)thread_conc27, NULL);
#else
hthreads[i]= CreateThread(NULL, 0, thread_conc27, NULL, 0, &threads[i]);
if (hthreads[i]==NULL)
diag("error while starting thread");
#endif
}
for (i=0; i < THREAD_NUM; i++)
{
#ifndef _WIN32
pthread_join(threads[i], NULL);
#else
WaitForSingleObject(hthreads[i], INFINITE);
#endif
}
pthread_mutex_destroy(&LOCK_test);
rc= mysql_query(mysql, "SELECT a FROM t_conc27");
check_mysql_rc(rc,mysql); check_mysql_rc(rc,mysql);
mysql_thread_end(); res= mysql_store_result(mysql);
rc= mysql_query(mysql, "SET @a:=2"); FAIL_IF(!res, "invalid result");
check_mysql_rc(rc,mysql);
mysql_thread_end(); row= mysql_fetch_row(res);
FAIL_IF(!row, "can't fetch row");
diag("row=%s", row[0]);
FAIL_IF(atoi(row[0]) != 100, "expected value 100");
mysql_free_result(res);
return OK; return OK;
} }
#ifndef _WIN32
int thread_conc27(void)
#else
DWORD WINAPI thread_conc27(void)
#endif
{
MYSQL *mysql;
int rc;
mysql_thread_init();
mysql= mysql_init(NULL);
if(!mysql_real_connect(mysql, hostname, username, password, schema,
port, socketname, 0))
{
diag("Error: %s", mysql_error(mysql));
mysql_close(mysql);
mysql_thread_end();
goto end;
}
pthread_mutex_lock(&LOCK_test);
rc= mysql_query(mysql, "UPDATE t_conc27 SET a=a+1");
check_mysql_rc(rc, mysql);
pthread_mutex_unlock(&LOCK_test);
mysql_close(mysql);
mysql_thread_end();
end:
mysql_thread_end();
return 0;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL},
{"test_conc_27", test_conc_27, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_conc_27", test_conc_27, TEST_CONNECTION_NEW, 0, NULL, NULL},