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);
|
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)
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
@@ -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));
|
||||||
|
@@ -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 */
|
||||||
{
|
{
|
||||||
|
@@ -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));
|
||||||
|
|
||||||
|
@@ -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,13 +124,11 @@ 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
|
||||||
@@ -137,35 +136,29 @@ my_bool my_thread_init(void)
|
|||||||
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)
|
||||||
|
@@ -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);
|
||||||
|
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;
|
return 1;
|
||||||
|
packet+= max_len;
|
||||||
|
len-= max_len;
|
||||||
}
|
}
|
||||||
|
/* write last remaining packet, size can be zero */
|
||||||
int3store(buff, len);
|
int3store(buff, len);
|
||||||
buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++);
|
buff[3]= (uchar)net->pkt_nr++;
|
||||||
if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE))
|
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,8 +740,13 @@ ulong my_net_read(NET *net)
|
|||||||
return len;
|
return len;
|
||||||
#ifdef HAVE_COMPRESS
|
#ifdef HAVE_COMPRESS
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (net->remain_in_buf)
|
if (net->remain_in_buf)
|
||||||
|
{
|
||||||
|
/* restore 0 character */
|
||||||
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
|
net->buff[net->buf_length - net->remain_in_buf]=net->save_char;
|
||||||
|
}
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (net->remain_in_buf)
|
if (net->remain_in_buf)
|
||||||
@@ -759,9 +784,7 @@ ulong my_net_read(NET *net)
|
|||||||
{
|
{
|
||||||
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;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
net->buf_length+=len;
|
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->save_char= net->read_pos[len]; /* Must be saved */
|
||||||
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
|
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_ENTER("vio_read");
|
||||||
DBUG_PRINT("enter", ("sd=%d size=%d", vio->sd, size));
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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},
|
||||||
|
@@ -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. */
|
||||||
|
@@ -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");
|
||||||
|
|
||||||
rc= mysql_query(mysql, "SET @a:=1");
|
|
||||||
check_mysql_rc(rc, mysql);
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
mysql_thread_end();
|
rc= mysql_query(mysql, "CREATE TABLE t_conc27(a int)");
|
||||||
rc= mysql_query(mysql, "SET @a:=2");
|
|
||||||
check_mysql_rc(rc, mysql);
|
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;
|
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},
|
||||||
|
Reference in New Issue
Block a user