You've already forked mariadb-connector-c
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:
@@ -616,9 +616,9 @@ void load_defaults(const char *conf_file, const char **groups,
|
||||
int *argc, char ***argv);
|
||||
void free_defaults(char **argv);
|
||||
void print_defaults(const char *conf_file, const char **groups);
|
||||
my_bool my_compress(unsigned char *, ulong *, ulong *);
|
||||
my_bool my_uncompress(unsigned char *, ulong *, ulong *);
|
||||
unsigned char *my_compress_alloc(const unsigned char *packet, ulong *len, ulong *complen);
|
||||
my_bool my_compress(unsigned char *, size_t *, size_t *);
|
||||
my_bool my_uncompress(unsigned char *, size_t *, size_t *);
|
||||
unsigned char *my_compress_alloc(const unsigned char *packet, size_t *len, size_t *complen);
|
||||
ulong checksum(const unsigned char *mem, uint count);
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_WIN32)
|
||||
|
@@ -317,7 +317,7 @@ int net_flush(NET *net);
|
||||
int my_net_write(NET *net,const char *packet, size_t len);
|
||||
int net_write_command(NET *net,unsigned char command,const char *packet,
|
||||
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);
|
||||
|
||||
struct rand_struct {
|
||||
|
@@ -69,11 +69,8 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
|
||||
* vio_read and vio_write should have the same semantics
|
||||
* as read(2) and write(2).
|
||||
*/
|
||||
int vio_read( Vio* vio,
|
||||
gptr buf, int size);
|
||||
int vio_write( Vio* vio,
|
||||
const gptr buf,
|
||||
int size);
|
||||
size_t vio_read(Vio* vio, gptr buf, size_t size);
|
||||
size_t vio_write(Vio* vio, const gptr buf, size_t size);
|
||||
/*
|
||||
* Whenever the socket is set to blocking mode or not.
|
||||
*/
|
||||
|
@@ -417,7 +417,7 @@ restart:
|
||||
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,
|
||||
net->last_error));
|
||||
|
@@ -29,7 +29,7 @@
|
||||
** *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)
|
||||
*complen=0;
|
||||
@@ -39,12 +39,13 @@ my_bool my_compress(unsigned char *packet, ulong *len, ulong *complen)
|
||||
if (!compbuf)
|
||||
return *complen ? 0 : 1;
|
||||
memcpy(packet,compbuf,*len);
|
||||
my_free(compbuf,MYF(MY_WME)); }
|
||||
my_free(compbuf,MYF(MY_WME));
|
||||
}
|
||||
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;
|
||||
*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 */
|
||||
{
|
||||
|
@@ -1436,8 +1436,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
|
||||
DBUG_PRINT("info",("request_len=%ld", request_len));
|
||||
|
||||
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)
|
||||
my_free(request, MYF(0));
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
#include <dbug.h>
|
||||
|
||||
#ifdef THREAD
|
||||
#ifdef USE_TLS
|
||||
@@ -123,13 +124,11 @@ static long thread_id=0;
|
||||
my_bool my_thread_init(void)
|
||||
{
|
||||
struct st_my_thread_var *tmp;
|
||||
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
pthread_mutex_lock(&THR_LOCK_lock);
|
||||
#endif
|
||||
#if !defined(_WIN32) || defined(USE_TLS)
|
||||
my_bool rc= 0;
|
||||
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 */
|
||||
}
|
||||
/* We must have many calloc() here because these are freed on
|
||||
@@ -137,35 +136,29 @@ my_bool my_thread_init(void)
|
||||
if (!(tmp=(struct st_my_thread_var *)
|
||||
calloc(1,sizeof(struct st_my_thread_var))))
|
||||
{
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
return 1;
|
||||
}
|
||||
pthread_setspecific(THR_KEY_mysys,tmp);
|
||||
|
||||
#else
|
||||
tmp= &THR_KEY_mysys;
|
||||
if (tmp->initialized) /* Already initialized */
|
||||
{
|
||||
#if !defined(_WIN32) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
tmp= &THR_KEY_mysys;
|
||||
#endif
|
||||
tmp->id= ++thread_id;
|
||||
|
||||
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
|
||||
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);
|
||||
#endif
|
||||
tmp->initialized= TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 !defined(DBUG_OFF)
|
||||
|
@@ -110,11 +110,12 @@ int my_net_init(NET *net, Vio* vio)
|
||||
return 1;
|
||||
if (net_buffer_length > max_allowed_packet)
|
||||
max_allowed_packet=net_buffer_length;
|
||||
net->max_packet_size= 0xFFFFFF;
|
||||
net->buff_end=net->buff+(net->max_packet=net_buffer_length);
|
||||
net->vio = vio;
|
||||
net->error=0; net->return_status=0;
|
||||
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->last_error[0]= net->sqlstate[0] =0;
|
||||
|
||||
@@ -173,7 +174,7 @@ static my_bool net_realloc(NET *net, size_t length)
|
||||
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)
|
||||
{
|
||||
my_socket sd= vio->sd;
|
||||
@@ -185,7 +186,7 @@ static int net_check_if_data_available(Vio *vio)
|
||||
FD_SET(sd, &sockset);
|
||||
|
||||
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)
|
||||
return 0;
|
||||
return FD_ISSET(sd, &sockset);
|
||||
@@ -196,7 +197,7 @@ static int net_check_if_data_available(Vio *vio)
|
||||
|
||||
void net_clear(NET *net)
|
||||
{
|
||||
#if defined(DBUG_OFF) || defined(USE_NET_CLEAR)
|
||||
#if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
|
||||
int available= 0;
|
||||
size_t count; /* One may get 'unused' warning */
|
||||
bool is_blocking=vio_is_blocking(net->vio);
|
||||
@@ -204,7 +205,7 @@ void net_clear(NET *net)
|
||||
DBUG_ENTER("net_clear");
|
||||
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",
|
||||
count,vio_description(net->vio)));
|
||||
@@ -235,7 +236,7 @@ void net_clear(NET *net)
|
||||
#else
|
||||
DBUG_ENTER("net_clear");
|
||||
#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;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@@ -253,6 +254,8 @@ int net_flush(NET *net)
|
||||
(uint) (net->write_pos - net->buff));
|
||||
net->write_pos=net->buff;
|
||||
}
|
||||
if (net->compress)
|
||||
net->pkt_nr= net->compress_pkt_nr;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@@ -273,17 +276,24 @@ int
|
||||
my_net_write(NET *net, const char *packet, size_t len)
|
||||
{
|
||||
uchar buff[NET_HEADER_SIZE];
|
||||
if (len >= MAX_PACKET_LENGTH)
|
||||
while (len >= MAX_PACKET_LENGTH)
|
||||
{
|
||||
net->error=1;
|
||||
net->last_errno=ER_NET_PACKET_TOO_LARGE;
|
||||
const ulong max_len= MAX_PACKET_LENGTH;
|
||||
int3store(buff,max_len);
|
||||
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;
|
||||
}
|
||||
/* write last remaining packet, size can be zero */
|
||||
int3store(buff, len);
|
||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
||||
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 net_write_buff(net,packet,len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -327,7 +337,13 @@ net_write_command(NET *net, uchar command,
|
||||
static int
|
||||
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)
|
||||
{
|
||||
@@ -341,6 +357,19 @@ net_write_buff(NET *net,const char *packet, size_t len)
|
||||
len-=left_length;
|
||||
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)
|
||||
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 */
|
||||
|
||||
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;
|
||||
thr_alarm_t alarmed;
|
||||
#if !defined(_WIN32) && !defined(__EMX__) && !defined(OS2)
|
||||
@@ -371,16 +400,14 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
ulong complen;
|
||||
size_t complen;
|
||||
uchar *b;
|
||||
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))))
|
||||
{
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_OUT_OF_RESOURCES;
|
||||
net->error=2;
|
||||
#endif
|
||||
net->reading_or_writing=0;
|
||||
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,len);
|
||||
b[3]=(uchar) (net->pkt_nr++);
|
||||
b[3]=(uchar) (net->compress_pkt_nr++);
|
||||
len+= header_length;
|
||||
packet= (char*) b;
|
||||
}
|
||||
#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;
|
||||
#endif /* MYSQL_SERVER */
|
||||
|
||||
pos=(char*) packet; end=pos+len;
|
||||
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);
|
||||
#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));
|
||||
#endif /* EXTRA_DEBUG */
|
||||
net->error=2; /* Close socket */
|
||||
net->last_errno= (interrupted ?
|
||||
ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@@ -459,10 +481,8 @@ net_real_write(NET *net,const char *packet,ulong len)
|
||||
}
|
||||
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
|
||||
net->error=2; /* Close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
|
||||
ER_NET_ERROR_ON_WRITE);
|
||||
#endif /* MYSQL_SERVER */
|
||||
break;
|
||||
}
|
||||
pos+=length;
|
||||
@@ -648,7 +668,7 @@ my_real_read(NET *net, size_t *complen)
|
||||
#endif
|
||||
goto end;
|
||||
}
|
||||
net->pkt_nr++;
|
||||
net->compress_pkt_nr= ++net->pkt_nr;
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (net->compress)
|
||||
{
|
||||
@@ -692,7 +712,7 @@ end:
|
||||
|
||||
ulong my_net_read(NET *net)
|
||||
{
|
||||
ulong len,complen;
|
||||
size_t len,complen;
|
||||
|
||||
#ifdef HAVE_COMPRESS
|
||||
if (!net->compress)
|
||||
@@ -720,8 +740,13 @@ ulong my_net_read(NET *net)
|
||||
return len;
|
||||
#ifdef HAVE_COMPRESS
|
||||
}
|
||||
else
|
||||
{
|
||||
if (net->remain_in_buf)
|
||||
{
|
||||
/* restore 0 character */
|
||||
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
if (net->remain_in_buf)
|
||||
@@ -759,9 +784,7 @@ ulong my_net_read(NET *net)
|
||||
{
|
||||
len= packet_error;
|
||||
net->error=2; /* caller will close socket */
|
||||
#ifdef MYSQL_SERVER
|
||||
net->last_errno=ER_NET_UNCOMPRESS_ERROR;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
net->buf_length+=len;
|
||||
@@ -772,6 +795,7 @@ ulong my_net_read(NET *net)
|
||||
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;
|
||||
}
|
||||
|
@@ -186,9 +186,9 @@ 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_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
|
||||
@@ -219,19 +219,19 @@ int vio_read(Vio * vio, gptr buf, int size)
|
||||
r = read(vio->sd, buf, size);
|
||||
#endif /* _WIN32 */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
if ((size_t)r == -1)
|
||||
{
|
||||
DBUG_PRINT("vio_error", ("Got error %d during read",socket_errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_PRINT("exit", ("%u", (uint)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_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
||||
#ifdef HAVE_OPENSSL
|
||||
@@ -259,12 +259,12 @@ int vio_write(Vio * vio, const gptr buf, int size)
|
||||
r = write(vio->sd, buf, size);
|
||||
#endif /* _WIN32 */
|
||||
#ifndef DBUG_OFF
|
||||
if (r < 0)
|
||||
if ((size_t)r == -1)
|
||||
{
|
||||
DBUG_PRINT("vio_error", ("Got error on write: %d",socket_errno));
|
||||
}
|
||||
#endif /* DBUG_OFF */
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_PRINT("exit", ("%u", (uint)r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
@@ -530,7 +530,32 @@ static int test_reconnect_maxpackage(MYSQL *my)
|
||||
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[] = {
|
||||
{"test_compressed", test_compressed, 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},
|
||||
{"use_utf8", use_utf8, TEST_CONNECTION_NEW, 0, opt_utf8, NULL},
|
||||
|
@@ -543,6 +543,7 @@ static int test_bug30472(MYSQL *mysql)
|
||||
}
|
||||
/* Retrieve character set information. */
|
||||
|
||||
mysql_set_character_set(mysql, "latin1");
|
||||
bug30472_retrieve_charset_info(mysql,
|
||||
character_set_name_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(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_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");
|
||||
@@ -580,6 +582,7 @@ static int test_bug30472(MYSQL *mysql)
|
||||
/* Call mysql_change_user() with the same username, password, database. */
|
||||
|
||||
rc= mysql_change_user(mysql, username, password, (schema) ? schema : "test");
|
||||
mysql_set_character_set(mysql, "latin1");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
/* Retrieve character set information. */
|
||||
|
@@ -36,22 +36,105 @@ static int basic_connect(MYSQL *mysql)
|
||||
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)
|
||||
{
|
||||
|
||||
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, "SET @a:=1");
|
||||
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t_conc27");
|
||||
check_mysql_rc(rc, mysql);
|
||||
|
||||
mysql_thread_end();
|
||||
rc= mysql_query(mysql, "SET @a:=2");
|
||||
rc= mysql_query(mysql, "CREATE TABLE t_conc27(a int)");
|
||||
check_mysql_rc(rc, mysql);
|
||||
mysql_thread_end();
|
||||
|
||||
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);
|
||||
|
||||
res= mysql_store_result(mysql);
|
||||
FAIL_IF(!res, "invalid result");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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[] = {
|
||||
{"basic_connect", basic_connect, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||
{"test_conc_27", test_conc_27, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||
|
Reference in New Issue
Block a user