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

Merge branch '10.2-server' into 10.3-serg

This commit is contained in:
Sergei Golubchik
2018-08-10 14:24:53 +02:00
40 changed files with 763 additions and 296 deletions

View File

@@ -1,6 +1,10 @@
sudo: true
language: c
cache:
apt: true
ccache: true
services: docker
addons:
hosts:
- mariadb.example.com
@@ -9,12 +13,8 @@ before_script:
# Disable services enabled by default
- sudo /etc/init.d/mysql stop
before_install:
- chmod +x .travis/script.sh
- chmod +x .travis/gen-ssl.sh
- chmod +x .travis/build/build.sh
- chmod +x .travis/build/docker-entrypoint.sh
- chmod -R +x .travis/*
- chmod 777 .travis/build/
- export PROJ_PATH=`pwd`
- export ENTRYPOINT=$PROJ_PATH/.travis/sql
@@ -24,6 +24,8 @@ before_install:
matrix:
allow_failures:
- env: DB=build
- env: SERVER_BRANCH=10.4
- env: SERVER_BRANCH=10.4 TEST_OPTION=--ps-protocol
include:
- env: DB=build
- env: DB=mysql:5.7
@@ -32,8 +34,14 @@ matrix:
- env: DB=mariadb:10.1
- env: DB=mariadb:10.2
- env: DB=mariadb:10.3
- env: SERVER_BRANCH=10.3
- env: SERVER_BRANCH=10.3 TEST_OPTION=--ps-protocol
- env: SERVER_BRANCH=10.4
- env: SERVER_BRANCH=10.4 TEST_OPTION=--ps-protocol
script:
- if [ "$DB" = "build" ] ; then .travis/build/build.sh; fi
- if [ "$DB" = "build" ] ; then docker build -t build:latest --label build .travis/build/; fi
- .travis/script.sh
- if [ -z "$DB" ] ; then .travis/server-replace-submodule.sh; fi
- if [ -n "$DB" ] ; then .travis/script.sh; fi

View File

@@ -24,7 +24,7 @@ get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)
# do not inherit include directories from the parent project
SET_PROPERTY(DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNITTEST
FOREACH(V WITH_MYSQLCOMPAT WITH_MSI WITH_SIGNCODE WITH_RTC WITH_UNIT_TESTS
WITH_DYNCOL WITH_EXTERNAL_ZLIB WITH_CURL WITH_SQLITE WITH_SSL
INSTALL_LAYOUT WITH_TEST_SRCPKG)
SET(${V} ${${OPT}${V}})

View File

@@ -85,6 +85,9 @@ extern const char *mariadb_client_errors[]; /* Error messages */
#define CR_AUTH_PLUGIN_CANNOT_LOAD 2059
#define CR_DUPLICATE_CONNECTION_ATTR 2060
#define CR_AUTH_PLUGIN_ERR 2061
/* Always last, if you add new error codes please update the
value for CR_MYSQL_LAST_ERROR */
#define CR_MYSQL_LAST_ERROR CR_AUTH_PLUGIN_ERR
/*
* MariaDB Connector/C errors:
@@ -96,5 +99,8 @@ extern const char *mariadb_client_errors[]; /* Error messages */
#define CR_FILE_NOT_FOUND 5004
#define CR_FILE_READ 5005
#define CR_BULK_WITHOUT_PARAMETERS 5006
#define CR_INVALID_STMT 5007
/* Always last, if you add new error codes please update the
value for CR_MARIADB_LAST_ERROR */
#define CR_MARIADB_LAST_ERROR CR_INVALID_STMT
#endif

View File

@@ -98,7 +98,7 @@ struct st_ma_pvio_methods
ssize_t (*write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t (*async_write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int (*wait_io_or_timeout)(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool (*blocking)(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
int (*blocking)(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool (*connect)(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
my_bool (*close)(MARIADB_PVIO *pvio);
int (*fast_send)(MARIADB_PVIO *pvio);

View File

@@ -33,4 +33,23 @@ size_t ma_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
my_bool *error);
char *ma_ll2str(long long val,char *dst, int radix);
#define MAX_ENV_SIZE 1024
static inline my_bool ma_check_env_str(const char *env)
{
unsigned int i;
if (!env)
return 1;
for (i=0; i < MAX_ENV_SIZE; i++)
{
if (env[i] == 0)
break;
}
if (i >= MAX_ENV_SIZE)
return 1;
return 0;
}
#endif

View File

@@ -524,6 +524,9 @@ extern const char *ma_get_type(TYPELIB *typelib,uint nr);
extern my_bool ma_init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
size_t init_alloc, size_t alloc_increment);
extern my_bool ma_dynstr_append(DYNAMIC_STRING *str, const char *append);
extern my_bool ma_dynstr_append_quoted(DYNAMIC_STRING *str,
const char *append, size_t len,
char quote);
my_bool ma_dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
size_t length);
extern my_bool ma_dynstr_set(DYNAMIC_STRING *str, const char *init_str);

View File

@@ -225,7 +225,7 @@ void mariadb_dyncol_free(DYNAMIC_COLUMN *str);
/* conversion of values to 3 base types */
enum enum_dyncol_func_result
mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
MARIADB_CHARSET_INFO *cs, my_bool quote);
MARIADB_CHARSET_INFO *cs, char quote);
enum enum_dyncol_func_result
mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
enum enum_dyncol_func_result

View File

@@ -37,8 +37,8 @@
#define SET_CLIENT_STMT_ERROR(a, b, c, d) \
{ \
(a)->last_errno= (b);\
strncpy((a)->sqlstate, (c), sizeof((a)->sqlstate));\
strncpy((a)->last_error, (d) ? (d) : ER((b)), sizeof((a)->last_error));\
strncpy((a)->sqlstate, (c), SQLSTATE_LENGTH);\
strncpy((a)->last_error, (d) ? (d) : ER((b)), MYSQL_ERRMSG_SIZE - 1);\
}
#define CLEAR_CLIENT_STMT_ERROR(a) \

View File

@@ -124,8 +124,8 @@ extern unsigned int mariadb_deinitialize_ssl;
#define SET_CLIENT_ERROR(a, b, c, d) \
{ \
(a)->net.last_errno= (b);\
strncpy((a)->net.sqlstate, (c), sizeof((a)->net.sqlstate));\
strncpy((a)->net.last_error, (d) ? (d) : ER((b)), sizeof((a)->net.last_error));\
strncpy((a)->net.sqlstate, (c), SQLSTATE_LENGTH);\
strncpy((a)->net.last_error, (d) ? (d) : ER((b)), MYSQL_ERRMSG_SIZE - 1);\
}
/* For mysql_async.c */
@@ -409,8 +409,8 @@ typedef struct character_set
{
unsigned int number; /* character set number */
unsigned int state; /* character set state */
const char *csname; /* collation name */
const char *name; /* character set name */
const char *csname; /* character set name */
const char *name; /* collation name */
const char *comment; /* comment */
const char *dir; /* character set directory */
unsigned int mbminlen; /* min. length for multibyte strings */

View File

@@ -65,7 +65,7 @@ static char *get_password(FILE *file, char *buffer, int length)
!CharsProcessed)
break;
#else
inChar= fgetc(file);
inChar= (char)fgetc(file);
#endif
switch(inChar) {

View File

@@ -1408,7 +1408,7 @@ static void map_charset_name(const char *cs_name, my_bool target_cs, char *buffe
if (target_cs)
{
strncat(buffer, "//TRANSLIT", buff_len);
strncat(buffer, "//TRANSLIT", buff_len - strlen(buffer));
}
}
/* }}} */

View File

@@ -237,11 +237,11 @@ static void load_env_plugins(MYSQL *mysql)
{
char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
/* no plugins to load */
if (!s)
if (ma_check_env_str(s))
return;
free_env= plugs= strdup(s);
free_env= strdup(s);
plugs= s= free_env;
do {
if ((s= strchr(plugs, ';')))
@@ -365,7 +365,7 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
char errbuf[1024];
#endif
char dlpath[FN_REFLEN+1];
void *sym, *dlhandle;
void *sym, *dlhandle = NULL;
struct st_mysql_client_plugin *plugin;
char *env_plugin_dir= getenv("MARIADB_PLUGIN_DIR");
@@ -448,6 +448,8 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
return plugin;
err:
if (dlhandle)
dlclose(dlhandle);
pthread_mutex_unlock(&LOCK_load_client_plugin);
my_set_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, SQLSTATE_UNKNOWN,
ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);

View File

@@ -231,12 +231,7 @@ static my_bool _mariadb_read_options_from_file(MYSQL *mysql,
key= ptr;
for ( ; isspace(end[-1]) ; end--) ;
*end= 0;
if (!value)
{
if (!key)
key= ptr;
}
else
if (value)
{
/* Remove pre- and end space */
char *value_end;

View File

@@ -1333,7 +1333,9 @@ static char *dtoa(double dd, int mode, int ndigits, int *decpt, int *sign,
*sign= 0;
/* If infinity, set decpt to DTOA_OVERFLOW, if 0 set it to 1 */
/* coverity[assign_where_compare_meant] */
if (((word0(&u) & Exp_mask) == Exp_mask && (*decpt= DTOA_OVERFLOW)) ||
/* coverity[assign_where_compare_meant] */
(!dval(&u) && (*decpt= 1)))
{
/* Infinity, NaN, 0 */

View File

@@ -142,7 +142,7 @@ const char *client_errors[]=
/* 2057 */ "The number of parameters in bound buffers differs from number of columns in resultset",
/* 2059 */ "Can't connect twice. Already connected",
/* 2058 */ "Plugin %s could not be loaded: %s",
/* 2059 */ "An attribute with same name already exists"
/* 2059 */ "An attribute with same name already exists",
/* 2060 */ "Plugin doesn't support this function",
""
};
@@ -157,6 +157,7 @@ const char *mariadb_client_errors[] =
/* 5004 */ "File '%s' not found (Errcode: %d)",
/* 5005 */ "Error reading file '%s' (Errcode: %d)",
/* 5006 */ "Bulk operation without parameters is not supported",
/* 5007 */ "Invalid statement handle",
""
};

View File

@@ -108,6 +108,7 @@ MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql)
ma_file= (MA_FILE *)malloc(sizeof(MA_FILE));
if (!ma_file)
{
fclose(fp);
my_set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return NULL;
}

View File

@@ -549,7 +549,6 @@ ulong ma_net_read(NET *net)
return packet_error;
if (_mariadb_uncompress((unsigned char*) net->buff + net->where_b, &packet_length, &complen))
{
len= packet_error;
net->error=2; /* caller will close socket */
net->last_errno=ER_NET_UNCOMPRESS_ERROR;
break;

View File

@@ -102,10 +102,10 @@ MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo)
return NULL;
}
/* coverity[var_deref_op] */
if (!(pvio= (MARIADB_PVIO *)calloc(1, sizeof(MARIADB_PVIO))))
{
PVIO_SET_ERROR(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
my_set_error(cinfo->mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
return NULL;
}
@@ -399,8 +399,10 @@ end:
void ma_pvio_close(MARIADB_PVIO *pvio)
{
/* free internal structures and close connection */
if (pvio)
{
#ifdef HAVE_TLS
if (pvio && pvio->ctls)
if (pvio->ctls)
{
ma_pvio_tls_close(pvio->ctls);
free(pvio->ctls);
@@ -414,6 +416,7 @@ void ma_pvio_close(MARIADB_PVIO *pvio)
free(pvio);
}
}
/* }}} */
/* {{{ my_bool ma_pvio_get_handle */
@@ -459,6 +462,8 @@ ma_pvio_wait_async(struct mysql_async_context *b, enum enum_pvio_io_event event,
/* {{{ ma_pvio_wait_io_or_timeout */
int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout)
{
if (pvio)
{
if (IS_PVIO_ASYNC_ACTIVE(pvio))
return ma_pvio_wait_async(pvio->mysql->options.extension->async_context,
@@ -467,6 +472,7 @@ int ma_pvio_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout)
if (pvio && pvio->methods->wait_io_or_timeout)
return pvio->methods->wait_io_or_timeout(pvio, is_read, timeout);
}
return 1;
}
/* }}} */
@@ -484,7 +490,7 @@ my_bool ma_pvio_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
my_bool ma_pvio_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
{
if (pvio && pvio->methods->blocking)
return pvio->methods->blocking(pvio, block, previous_mode);
return pvio->methods->blocking(pvio, block, previous_mode) != 0;
return 1;
}
/* }}} */

View File

@@ -198,42 +198,90 @@ double my_atod(const char *number, const char *end, int *error)
my_bool str_to_TIME(const char *str, size_t length, MYSQL_TIME *tm)
{
my_bool is_time=0, is_date=0, has_time_frac=0;
char *p= (char *)str;
if ((p= strchr(str, '-')) && p <= str + length)
is_date= 1;
if ((p= strchr(str, ':')) && p <= str + length)
is_time= 1;
if ((p= strchr(str, '.')) && p <= str + length)
has_time_frac= 1;
p= (char *)str;
char *start= alloca(length + 1);
my_bool is_date= 0, is_time= 0;
memset(tm, 0, sizeof(MYSQL_TIME));
if (!start)
goto error;
tm->time_type= MYSQL_TIMESTAMP_NONE;
memcpy(start, str, length);
start[length]= '\0';
while (length && isspace(*start)) start++, length--;
if (!length)
goto error;
/* negativ value? */
if (*start == '-')
{
tm->neg= 1;
start++;
length--;
}
if (!length)
return 1;
/* Determine time type:
MYSQL_TIMESTAMP_DATE: [-]YY[YY].MM.DD
MYSQL_TIMESTAMP_DATETIME: [-]YY[YY].MM.DD hh:mm:ss.mmmmmm
MYSQL_TIMESTAMP_TIME: [-]hh:mm:ss.mmmmmm
*/
if (strchr(start, '-'))
{
if (tm->neg)
goto error;
tm->time_type= MYSQL_TIMESTAMP_DATE;
if (sscanf(start, "%d-%d-%d", &tm->year, &tm->month, &tm->day) < 3)
goto error;
is_date= 1;
if (!(start= strchr(start, ' ')))
goto check;
}
if (!strchr(start, ':'))
goto check;
is_time= 1;
if (tm->time_type== MYSQL_TIMESTAMP_DATE)
tm->time_type= MYSQL_TIMESTAMP_DATETIME;
else
tm->time_type= MYSQL_TIMESTAMP_TIME;
if (strchr(start, '.')) /* fractional seconds */
{
if (sscanf(start, "%d:%d:%d.%ld", &tm->hour, &tm->minute,
&tm->second,&tm->second_part) < 4)
goto error;
} else {
if (sscanf(start, "%d:%d:%d", &tm->hour, &tm->minute,
&tm->second) < 3)
goto error;
}
check:
if (tm->time_type == MYSQL_TIMESTAMP_NONE)
goto error;
if (is_date)
{
sscanf(str, "%d-%d-%d", &tm->year, &tm->month, &tm->day);
p= strchr(str, ' ');
if (!p)
{
tm->time_type= MYSQL_TIMESTAMP_DATE;
return 0;
}
}
if (has_time_frac)
{
sscanf(p, "%d:%d:%d.%ld", &tm->hour, &tm->minute, &tm->second, &tm->second_part);
tm->time_type= (is_date) ? MYSQL_TIMESTAMP_DATETIME : MYSQL_TIMESTAMP_TIME;
return 0;
if (tm->year < 69)
tm->year+= 2000;
else if (tm->year < 100)
tm->year+= 1900;
if (tm->day > 31 || tm->month > 12)
goto error;
}
if (is_time)
{
sscanf(p, "%d:%d:%d", &tm->hour, &tm->minute, &tm->second);
tm->time_type= (is_date) ? MYSQL_TIMESTAMP_DATETIME : MYSQL_TIMESTAMP_TIME;
return 0;
if (tm->minute > 59 || tm->second > 59)
goto error;
}
return 0;
error:
tm->time_type= MYSQL_TIMESTAMP_ERROR;
return 1;
}
@@ -394,7 +442,8 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon
len < field->length && len < r_param->buffer_length)
{
ma_bmove_upp(buffer + field->length, buffer + len, len);
memset((char*) buffer, '0', field->length - len);
/* coverity [bad_memset] */
memset((void*) buffer, (int) '0', field->length - len);
len= field->length;
}
convert_froma_string(r_param, buffer, len);
@@ -612,7 +661,8 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl
if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
break;
ma_bmove_upp(buff + field->length, buff + length, length);
memset((char*) buff, '0', field->length - length);
/* coverity [bad_memset] */
memset((void*) buff, (int) '0', field->length - length);
length= field->length;
}
@@ -711,7 +761,8 @@ static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, d
if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
break;
ma_bmove_upp(buff + field->length, buff + length, length);
memset((char*) buff, '0', field->length - length);
/* coverity [bad_memset] */
memset((void*) buff, (int) '0', field->length - length);
length= field->length;
}
convert_froma_string(r_param, buff, length);

View File

@@ -92,6 +92,36 @@ my_bool ma_dynstr_append(DYNAMIC_STRING *str, const char *append)
return ma_dynstr_append_mem(str,append,strlen(append));
}
my_bool ma_dynstr_append_quoted(DYNAMIC_STRING *str,
const char *append, size_t len,
char quote)
{
size_t additional= str->alloc_increment;
size_t lim= additional;
uint i;
if (ma_dynstr_realloc(str, len + additional + 2))
return TRUE;
str->str[str->length++]= quote;
for (i= 0; i < len; i++)
{
register char c= append[i];
if (c == quote || c == '\\')
{
if (!lim)
{
if (ma_dynstr_realloc(str, additional))
return TRUE;
lim= additional;
}
lim--;
str->str[str->length++]= '\\';
}
str->str[str->length++]= c;
}
str->str[str->length++]= quote;
return FALSE;
}
my_bool ma_dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
size_t length)

View File

@@ -34,7 +34,7 @@ size_t mariadb_time_to_string(const MYSQL_TIME *tm, char *time_str, size_t len,
return 0;
if (digits == AUTO_SEC_PART_DIGITS)
digits= MIN((tm->second_part) ? SEC_PART_DIGITS : 0, 15);
digits= (tm->second_part) ? SEC_PART_DIGITS : 0;
switch(tm->time_type) {
case MYSQL_TIMESTAMP_DATE:

View File

@@ -130,7 +130,7 @@ const char *ma_pvio_tls_get_protocol_version(MARIADB_TLS *ctls)
return tls_protocol_version[version];
}
static char ma_hex2int(char c)
static signed char ma_hex2int(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
@@ -161,7 +161,7 @@ static my_bool ma_pvio_tls_compare_fp(const char *cert_fp,
for(c= (char *)cert_fp; c < cert_fp + cert_fp_len; c++)
{
char d1, d2;
signed char d1, d2;
if (*p == ':')
p++;
if (p - fp > (int)fp_len -1)

View File

@@ -1681,7 +1681,10 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str,
goto err;
}
if (!column_count)
{
free(columns_order);
return ER_DYNCOL_OK;
}
memset(str->str, 0, fmt->fixed_hdr);
str->length= fmt->fixed_hdr;
@@ -2755,7 +2758,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan,
new_hdr->header_size + new_hdr->nmpool_size;
for (i= 0, j= 0; i < add_column_count || j < hdr->column_count; i++)
{
size_t UNINIT_VAR(first_offset);
size_t first_offset= 0;
uint start= j, end;
/*
@@ -3612,7 +3615,6 @@ end:
create_new_string:
/* There is no columns from before, so let's just add the new ones */
rc= ER_DYNCOL_OK;
free(alloc_plan);
if (not_null != 0)
rc= dynamic_column_create_many_internal_fmt(str, add_column_count,
(uint*)column_keys, values,
@@ -3887,10 +3889,9 @@ mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
return ER_DYNCOL_RESOURCE;
}
if (quote)
rc= ma_dynstr_append_mem(str, &quote, 1);
rc= ma_dynstr_append_quoted(str, from, len, quote);
else
rc= ma_dynstr_append_mem(str, from, len);
if (quote)
rc= ma_dynstr_append_mem(str, &quote, 1);
if (alloc)
free(alloc);
if (rc)
@@ -3946,7 +3947,7 @@ mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val)
break;
case DYN_COL_UINT:
*ll= (longlong)val->x.ulong_value;
if (val->x.ulong_value > ULONGLONG_MAX)
if (*ll > (longlong)ULONGLONG_MAX)
rc= ER_DYNCOL_TRUNCATED;
break;
case DYN_COL_DOUBLE:

View File

@@ -229,7 +229,7 @@ restart:
}
else
{
strcpy(net->sqlstate, SQLSTATE_UNKNOWN);
strncpy(net->sqlstate, SQLSTATE_UNKNOWN, SQLSTATE_LENGTH);
}
ma_strmake(net->last_error,(char*) pos,
min(len,sizeof(net->last_error)-1));
@@ -947,7 +947,8 @@ int mthd_my_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
if (len > (ulong) (end_pos - pos) || pos > end_pos)
{
mysql->net.last_errno=CR_UNKNOWN_ERROR;
strcpy(mysql->net.last_error,ER(mysql->net.last_errno));
strncpy(mysql->net.last_error,ER(mysql->net.last_errno),
MYSQL_ERRMSG_SIZE - 1);
return -1;
}
row[field] = (char*) pos;
@@ -984,6 +985,7 @@ mysql_init(MYSQL *mysql)
{
memset((char*) (mysql), 0, sizeof(*(mysql)));
mysql->net.pvio= 0;
mysql->free_me= 0;
mysql->net.extension= 0;
}
@@ -1189,8 +1191,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
uint port, const char *unix_socket, unsigned long client_flag)
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
char *end, *end_pkt, *host_info,
*charset_name= NULL;
char *end, *end_pkt, *host_info;
MA_PVIO_CINFO cinfo= {NULL, NULL, 0, -1, NULL};
MARIADB_PVIO *pvio= NULL;
char *scramble_data;
@@ -1385,9 +1386,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
}
/* Save connection information */
if (!user) user="";
if (!passwd) passwd="";
if (!(mysql->host_info= strdup(host_info ? host_info : "")) ||
if (!(mysql->host_info= strdup(host_info)) ||
!(mysql->host= strdup(cinfo.host ? cinfo.host : "")) ||
!(mysql->user=strdup(user)) ||
!(mysql->passwd=strdup(passwd)))
@@ -1489,7 +1489,8 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
{
net->last_errno=CR_CANT_READ_CHARSET;
sprintf(net->last_error,ER(net->last_errno),
charset_name ? charset_name : "unknown",
mysql->options.charset_name ? mysql->options.charset_name :
"unknown",
"compiled_in");
goto error;
}
@@ -1606,6 +1607,7 @@ my_bool STDCALL mariadb_reconnect(MYSQL *mysql)
}
mysql_init(&tmp_mysql);
tmp_mysql.free_me= 0;
tmp_mysql.options=mysql->options;
if (mysql->extension->conn_hdlr)
{
@@ -1721,13 +1723,6 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
*s_db= mysql->db;
int rc;
if (!user)
user="";
if (!passwd)
passwd="";
if (!db)
db="";
if (mysql->options.charset_name)
mysql->charset =mysql_find_charset_name(mysql->options.charset_name);
else
@@ -1778,8 +1773,11 @@ mysql_select_db(MYSQL *mysql, const char *db)
{
int error;
if (!db)
return 1;
if ((error=ma_simple_command(mysql, COM_INIT_DB, db,
db ? (uint) strlen(db) : 0,0,0)))
(uint) strlen(db),0,0)))
return(error);
free(mysql->db);
mysql->db=strdup(db);
@@ -1978,21 +1976,7 @@ mysql_send_query(MYSQL* mysql, const char* query, unsigned long length)
return ma_simple_command(mysql, COM_QUERY, query, length, 1,0);
}
int mthd_my_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
ulong length;
if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error)
{
return(1);
}
free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0)
int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
{
size_t item_len;
mysql->affected_rows= net_field_length_ll(&pos);
@@ -2117,6 +2101,23 @@ get_info:
}
return(0);
}
int mthd_my_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
ulong length;
if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error)
{
return(1);
}
free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0)
return ma_read_ok_packet(mysql, pos, length);
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{
int error=mysql_handle_local_infile(mysql, (char *)pos);
@@ -2292,12 +2293,14 @@ mysql_fetch_row(MYSQL_RES *res)
if (!res)
return 0;
if (res->handle)
{
if (res->handle->status != MYSQL_STATUS_USE_RESULT &&
res->handle->status != MYSQL_STATUS_GET_RESULT)
return 0;
}
if (!res->data)
{ /* Unbufferred fetch */
if (!res->eof)
if (!res->eof && res->handle)
{
if (!(res->handle->methods->db_read_one_row(res->handle,res->field_count,res->row, res->lengths)))
{
@@ -2657,7 +2660,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
mysql->options.named_pipe=1; /* Force named pipe */
break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
if (!arg1 || test(*(my_bool*) arg1))
if (!arg1 || test(*(unsigned int*) arg1))
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
else
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
@@ -2745,6 +2748,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
if(!(mysql->options.extension= (struct st_mysql_options_extension *)
calloc(1, sizeof(struct st_mysql_options_extension))))
{
free(ctxt);
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto end;
}
@@ -3145,9 +3149,6 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
if (!(elements= va_arg(ap, unsigned int *)))
goto error;
if (!elements)
goto error;
*elements= 0;
if (!mysql->options.extension ||
@@ -3531,6 +3532,7 @@ static void mysql_once_init()
}
#ifdef _WIN32
static INIT_ONCE init_once= INIT_ONCE_STATIC_INIT;
BOOL CALLBACK win_init_once(
PINIT_ONCE InitOnce,
PVOID Parameter,
@@ -3539,6 +3541,8 @@ BOOL CALLBACK win_init_once(
return !mysql_once_init();
return TRUE;
}
#else
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
#endif
int STDCALL mysql_server_init(int argc __attribute__((unused)),
@@ -3546,11 +3550,9 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)),
char **groups __attribute__((unused)))
{
#ifdef _WIN32
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
BOOL ret = InitOnceExecuteOnce(&init_once, win_init_once, NULL, NULL);
return ret? 0: 1;
#else
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
return pthread_once(&init_once, mysql_once_init);
#endif
}
@@ -3571,6 +3573,11 @@ void STDCALL mysql_server_end(void)
#endif
mysql_client_init= 0;
ma_init_done= 0;
#ifdef WIN32
init_once = (INIT_ONCE)INIT_ONCE_STATIC_INIT;
#else
init_once = (pthread_once_t)PTHREAD_ONCE_INIT;
#endif
}
my_bool STDCALL mysql_thread_init(void)

View File

@@ -88,12 +88,18 @@ void stmt_set_error(MYSQL_STMT *stmt,
...)
{
va_list ap;
const char *error= NULL;
if (error_nr >= CR_MIN_ERROR && error_nr <= CR_MYSQL_LAST_ERROR)
error= ER(error_nr);
else if (error_nr >= CER_MIN_ERROR && error_nr <= CR_MARIADB_LAST_ERROR)
error= CER(error_nr);
stmt->last_errno= error_nr;
ma_strmake(stmt->sqlstate, sqlstate, SQLSTATE_LENGTH);
va_start(ap, format);
vsnprintf(stmt->last_error, MYSQL_ERRMSG_SIZE,
format ? format : ER(error_nr), ap);
format ? format : error ? error : "", ap);
va_end(ap);
return;
}
@@ -869,7 +875,7 @@ unsigned char* mysql_stmt_execute_generate_bulk_request(MYSQL_STMT *stmt, size_t
if (!stmt->param_count)
{
stmt_set_error(stmt, CR_BULK_WITHOUT_PARAMETERS, "IM001",
CER(CR_BULK_WITHOUT_PARAMETERS), "Bulk operation");
CER(CR_BULK_WITHOUT_PARAMETERS));
return NULL;
}
@@ -1328,15 +1334,18 @@ static my_bool net_stmt_close(MYSQL_STMT *stmt, my_bool remove)
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{
my_bool rc;
if (stmt && stmt->mysql && stmt->mysql->net.pvio)
my_bool rc= 1;
if (stmt)
{
if (stmt->mysql && stmt->mysql->net.pvio)
mysql_stmt_internal_reset(stmt, 1);
rc= net_stmt_close(stmt, 1);
free(stmt->extension);
free(stmt);
}
return(rc);
}
@@ -1854,6 +1863,12 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
for (i=0; i < stmt->field_count; i++)
{
memcpy(&stmt->fields[i], &mysql->fields[i], sizeof(MYSQL_FIELD));
/* since all pointers will be incorrect if another statement will
be executed, so we need to allocate memory and copy the
information */
stmt->fields[i].extension= 0; /* not in use yet */
if (mysql->fields[i].db)
stmt->fields[i].db= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].db);
if (mysql->fields[i].table)
@@ -1866,7 +1881,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
stmt->fields[i].org_name= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].org_name);
if (mysql->fields[i].catalog)
stmt->fields[i].catalog= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].catalog);
stmt->fields[i].def= mysql->fields[i].def ? ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].def) : NULL;
if (mysql->fields[i].def)
stmt->fields[i].def= ma_strdup_root(fields_ma_alloc_root, mysql->fields[i].def);
}
}
@@ -1891,7 +1907,8 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
*/
/* preferred is buffered read */
mysql_stmt_store_result(stmt);
if (mysql_stmt_store_result(stmt))
return 1;
stmt->mysql->status= MYSQL_STATUS_STMT_RESULT;
} else
{
@@ -1970,8 +1987,9 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
{
ma_free_root(&stmt->result.alloc, MYF(MY_KEEP_PREALLOC));
stmt->result_cursor= stmt->result.data= 0;
stmt->result.rows= 0;
}
/* CONC-344: set row count to zero */
stmt->result.rows= 0;
if (stmt->array_size > 0)
request= (char *)mysql_stmt_execute_generate_bulk_request(stmt, &request_len);
else
@@ -2305,17 +2323,23 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
const char *stmt_str,
size_t length)
{
MYSQL *mysql= stmt->mysql;
my_bool emulate_cmd= !(!(stmt->mysql->server_capabilities & CLIENT_MYSQL) &&
(stmt->mysql->extension->mariadb_server_capabilities &
(MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32))) || mysql->net.compress;
MYSQL *mysql;
my_bool emulate_cmd;
if (!stmt)
return 1;
mysql= stmt->mysql;
if (!mysql)
{
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
goto fail;
return 1;
}
emulate_cmd= !(!(stmt->mysql->server_capabilities & CLIENT_MYSQL) &&
(stmt->mysql->extension->mariadb_server_capabilities &
(MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32))) || mysql->net.compress;
/* Server versions < 10.2 don't support execute_direct, so we need to
emulate it */
if (emulate_cmd)
@@ -2323,7 +2347,6 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
int rc;
/* avoid sending close + prepare in 2 packets */
if ((rc= mysql_stmt_prepare(stmt, stmt_str, (unsigned long)length)))
return rc;
return mysql_stmt_execute(stmt);
@@ -2332,13 +2355,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
if (ma_multi_command(mysql, COM_MULTI_ENABLED))
{
SET_CLIENT_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0);
goto fail;
}
if (!stmt->mysql)
{
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
return(1);
return 1;
}
if (length == (size_t) -1)
@@ -2422,6 +2439,8 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
/* read execute response packet */
return stmt_read_execute_response(stmt);
fail:
/* check if we need to set error message */
if (!mysql_stmt_errno(stmt))
SET_CLIENT_STMT_ERROR(stmt, mysql->net.last_errno, mysql->net.sqlstate,
mysql->net.last_error);
do {

View File

@@ -39,6 +39,13 @@
#define HAVE_OPENSSL_1_1_API
#endif
#if OPENSSL_VERSION_NUMBER < 0x10000000L
#define SSL_OP_NO_TLSv1_1 0L
#define SSL_OP_NO_TLSv1_2 0L
#define CRYPTO_THREADID_set_callback CRYPTO_set_id_callback
#define CRYPTO_THREADID_get_callback CRYPTO_get_id_callback
#endif
#ifdef HAVE_TLS_SESSION_CACHE
#undef HAVE_TLS_SESSION_CACHE
#endif

View File

@@ -10,6 +10,7 @@ static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
extern void read_user_name(char *name);
extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer);
extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length);
typedef struct {
int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
@@ -357,7 +358,7 @@ static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
*buf= mysql->net.read_pos;
/* was it a request to change plugins ? */
if (**buf == 254)
if (pkt_len && **buf == 254)
return (int)packet_error; /* if yes, this plugin shan't continue */
/*
@@ -577,7 +578,6 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
errno);
return 1;
}
if (mysql->net.read_pos[0] == 254)
{
/* The server asked to use a different authentication plugin */
@@ -632,6 +632,8 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
net->read_pos[0] should always be 0 here if the server implements
the protocol correctly
*/
return mysql->net.read_pos[0] != 0;
if (mysql->net.read_pos[0] == 0)
return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length);
return 1;
}

View File

@@ -96,8 +96,8 @@ static int auth_old_password(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_SERVER_HANDSHAKE_ERR;
/* save it in MYSQL */
memmove(mysql->scramble_buff, pkt, pkt_len);
mysql->scramble_buff[pkt_len] = 0;
memmove(mysql->scramble_buff, pkt, pkt_len - 1);
mysql->scramble_buff[pkt_len - 1] = 0;
}
if (mysql && mysql->passwd[0])

View File

@@ -117,6 +117,8 @@ char *load_pub_key_file(const char *filename, int *pub_key_size)
FILE *fp= NULL;
char *buffer= NULL;
unsigned char error= 1;
size_t bytes_read= 0;
long fsize= 0;
if (!pub_key_size)
return NULL;
@@ -127,15 +129,21 @@ char *load_pub_key_file(const char *filename, int *pub_key_size)
if (fseek(fp, 0, SEEK_END))
goto end;
*pub_key_size= ftell(fp);
fsize= ftell(fp);
if (fsize < 0)
goto end;
rewind(fp);
if (!(buffer= malloc(*pub_key_size + 1)))
if (!(buffer= malloc(fsize + 1)))
goto end;
if (!fread(buffer, *pub_key_size, 1, fp))
bytes_read= fread(buffer, 1, (size_t)fsize, fp);
if (bytes_read < (size_t)fsize)
goto end;
*pub_key_size= (int)bytes_read;
error= 0;
end:

View File

@@ -38,7 +38,7 @@ ssize_t pvio_npipe_async_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t pvio_npipe_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t pvio_npipe_async_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
int pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool pvio_npipe_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
my_bool pvio_npipe_close(MARIADB_PVIO *pvio);
int pvio_npipe_fast_send(MARIADB_PVIO *pvio);
@@ -187,7 +187,7 @@ int pvio_npipe_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeo
return -1;
}
my_bool pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
int pvio_npipe_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
{
/* not supported */
DWORD flags= 0;

View File

@@ -36,7 +36,7 @@ int pvio_shm_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type);
ssize_t pvio_shm_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t pvio_shm_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int pvio_shm_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
int pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool pvio_shm_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
my_bool pvio_shm_close(MARIADB_PVIO *pvio);
int pvio_shm_shutdown(MARIADB_PVIO *pvio);
@@ -218,7 +218,7 @@ int pvio_shm_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout
return 0;
}
my_bool pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
int pvio_shm_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
{
/* not supported */
return 0;

View File

@@ -92,7 +92,7 @@ ssize_t pvio_socket_async_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
ssize_t pvio_socket_async_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t pvio_socket_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int pvio_socket_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
int pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
my_bool pvio_socket_close(MARIADB_PVIO *pvio);
int pvio_socket_fast_send(MARIADB_PVIO *pvio);
@@ -178,6 +178,7 @@ static int pvio_socket_end(void)
my_bool pvio_socket_change_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout)
{
struct timeval tm;
int rc= 0;
struct st_pvio_socket *csock= NULL;
if (!pvio)
return 1;
@@ -189,22 +190,22 @@ my_bool pvio_socket_change_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout ty
{
case PVIO_WRITE_TIMEOUT:
#ifndef _WIN32
setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tm, sizeof(tm));
rc= setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tm, sizeof(tm));
#else
setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(int));
rc= setsockopt(csock->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(int));
#endif
break;
case PVIO_READ_TIMEOUT:
#ifndef _WIN32
setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tm, sizeof(tm));
rc= setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tm, sizeof(tm));
#else
setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int));
rc= setsockopt(csock->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(int));
#endif
break;
default:
break;
}
return 0;
return rc;
}
/* {{{ pvio_socket_set_timeout */
@@ -564,7 +565,7 @@ int pvio_socket_wait_io_or_timeout(MARIADB_PVIO *pvio, my_bool is_read, int time
return rc;
}
my_bool pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
int pvio_socket_blocking(MARIADB_PVIO *pvio, my_bool block, my_bool *previous_mode)
{
my_bool is_blocking;
struct st_pvio_socket *csock;
@@ -887,6 +888,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
if (rc)
{
closesocket(csock->socket);
csock->socket= INVALID_SOCKET;
continue;
}
}
@@ -901,6 +903,7 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
if (pvio_socket_blocking(pvio, 0, 0) == SOCKET_ERROR)
{
closesocket(csock->socket);
csock->socket= INVALID_SOCKET;
continue;
}
break; /* success! */
@@ -936,21 +939,27 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
/* apply timeouts */
if (pvio->timeout[PVIO_CONNECT_TIMEOUT] > 0)
{
pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]);
pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]);
if (pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]) ||
pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_CONNECT_TIMEOUT]))
goto error;
}
else
{
if (pvio->timeout[PVIO_WRITE_TIMEOUT] > 0)
pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_WRITE_TIMEOUT]);
if (pvio_socket_change_timeout(pvio, PVIO_WRITE_TIMEOUT, pvio->timeout[PVIO_WRITE_TIMEOUT]))
goto error;
if (pvio->timeout[PVIO_READ_TIMEOUT] > 0)
pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_READ_TIMEOUT]);
if (pvio_socket_change_timeout(pvio, PVIO_READ_TIMEOUT, pvio->timeout[PVIO_READ_TIMEOUT]))
goto error;
}
return 0;
error:
/* close socket: MDEV-10891 */
if (csock->socket != INVALID_SOCKET)
{
closesocket(csock->socket);
csock->socket= INVALID_SOCKET;
}
if (pvio->data)
{
free((gptr)pvio->data);

View File

@@ -26,7 +26,7 @@ INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include
${CC_SOURCE_DIR}/unittest/libmariadb)
ADD_DEFINITIONS(-DLIBMARIADB)
SET(API_TESTS "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1")
SET(API_TESTS "conc336" "bulk1" "performance" "basic-t" "fetch" "charset" "logs" "cursor" "errors" "view" "ps" "ps_bugs" "sp" "result" "connection" "misc" "ps_new" "thread" "features-10_2" "bulk1")
IF(WITH_DYNCOL)
SET(API_TESTS ${API_TESTS} "dyncol")
ENDIF()

View File

@@ -996,8 +996,79 @@ static int bulk_null_null(MYSQL *mysql)
return OK;
}
static int test_mdev16593(MYSQL *mysql)
{
int i;
int rc;
MYSQL_BIND bind[2];
unsigned int array_size= 2;
int val_a[2]= {1,2};
char indicators[2]= {STMT_INDICATOR_NULL, STMT_INDICATOR_NULL};
const char *testcase[]= {"MYSQL_TYPE_LONG", "MYSQL_TYPE_NULL", "STMT_INDICATOR_NULL"};
diag("waiting for server fix");
return SKIP;
for (i=0; i < 3; i++)
{
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key, b int)");
check_mysql_rc(rc, mysql);
memset(&bind, 0, sizeof(MYSQL_BIND));
switch (i) {
case 0:
bind[0].buffer_type= MYSQL_TYPE_LONG;
break;
case 1:
bind[0].buffer_type= MYSQL_TYPE_NULL;
break;
case 2:
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].u.indicator= indicators;
break;
}
bind[0].buffer= val_a;
bind[1].buffer_type= MYSQL_TYPE_LONG;
bind[1].buffer= val_a;
rc= mysql_stmt_prepare(stmt, SL("insert into t1 values(?,?)"));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_bind_param(stmt, bind);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rc= mysql_query(mysql, "COMMIT");
check_mysql_rc(rc, mysql);
diag("Insert id with buffer_type %s: %lld",
testcase[i],
mysql_stmt_insert_id(stmt));
rc= mysql_query(mysql, "SELECT max(a) FROM t1");
check_mysql_rc(rc, mysql);
res= mysql_store_result(mysql);
row= mysql_fetch_row(res);
diag("Max value for t1.a=%s", row[0]);
mysql_free_result(res);
mysql_stmt_close(stmt);
}
return OK;
}
struct my_tests_st my_tests[] = {
{"check_bulk", check_bulk, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_mdev16593", test_mdev16593, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"bulk_null_null", bulk_null_null, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_char_conv1", test_char_conv1, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_char_conv2", test_char_conv2, TEST_CONNECTION_NEW, 0, NULL, NULL},

View File

@@ -0,0 +1,45 @@
#include "my_test.h"
#define MAX_COUNT 2000
int main(int argc, char *argv[]) {
MYSQL *mysql;
int i;
if (argc > 1)
get_options(argc, argv);
get_envvars();
for (i = 0; i < MAX_COUNT; ++i) {
if (mysql_library_init(-1, NULL, NULL) != 0) {
diag("mysql_library_init failed");
return 1;
}
mysql = mysql_init(NULL);
if (!mysql) {
diag("mysql_init failed");
return 1;
}
if (!mysql_real_connect(mysql, hostname, username, password, schema, port, socketname, 0)) {
diag("mysql_real_connect failed: %s", mysql_error(mysql));
return 1;
}
if (mysql_query(mysql, "SELECT NULL LIMIT 0") != 0) {
diag("mysql_query failed: %s", mysql_error(mysql));
return 1;
}
mysql_close(mysql);
mysql_library_end();
}
return 0;
}

View File

@@ -1486,7 +1486,47 @@ static int test_conc327(MYSQL *unused __attribute__((unused)))
}
#endif
static int test_conc332(MYSQL *unused __attribute__((unused)))
{
int rc;
MYSQL *mysql= mysql_init(NULL);
int server_status1, server_status2;
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4");
my_test_connect(mysql, hostname, username, password, schema,
port, socketname, 0);
FAIL_IF(mysql_errno(mysql), "Error during connect");
mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status1);
diag("server_status: %d", server_status1);
if (server_status1 & SERVER_STATUS_AUTOCOMMIT)
rc= mysql_query(mysql, "SET autocommit= 0");
else
rc= mysql_query(mysql, "SET autocommit= 1");
check_mysql_rc(rc, mysql);
mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2);
diag("server_status after changing autocommit: %d", server_status2);
rc= mysql_change_user(mysql, username, password, schema);
check_mysql_rc(rc, mysql);
mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2);
diag("server_status after mysql_change_user: %d", server_status2);
if (server_status1 != server_status2)
{
diag("Expected server_status %d instead of %d", server_status1, server_status2);
mysql_close(mysql);
return FAIL;
}
mysql_close(mysql);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_conc332", test_conc332, TEST_CONNECTION_NONE, 0, NULL, NULL},
#ifndef WIN32
{"test_conc327", test_conc327, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},

View File

@@ -253,12 +253,54 @@ static int dyncol_column_count(MYSQL *unused __attribute__((unused)))
return OK;
}
static int dyncol_nested(MYSQL *mysql __attribute__((unused)))
{
DYNAMIC_COLUMN col1, col2;
DYNAMIC_COLUMN_VALUE value[2];
MYSQL_LEX_STRING cols[2]= {{(char *)"0",1},{(char *)"1",1}};
DYNAMIC_STRING s;
mariadb_dyncol_init(&col1);
mariadb_dyncol_init(&col2);
memset(&value, 0, sizeof(DYNAMIC_COLUMN_VALUE));
value[0].type= DYN_COL_UINT;
value[0].x.ulong_value = 17;
mariadb_dyncol_create_many_named(&col1, 1, cols, value, 0);
if (mariadb_dyncol_check(&col1) != ER_DYNCOL_OK)
{
diag("Error while creating col1");
return FAIL;
}
value[1].type= DYN_COL_DYNCOL;
value[1].x.string.value.str= col1.str;
value[1].x.string.value.length= col1.length;
mariadb_dyncol_create_many_named(&col2, 2, cols, value, 0);
if (mariadb_dyncol_check(&col2) != ER_DYNCOL_OK)
{
diag("Error while creating col1");
return FAIL;
}
mariadb_dyncol_json(&col2, &s);
if (strcmp(s.str, "{\"0\":17,\"1\":{\"0\":17}}") != 0)
{
diag("%s != %s", s.str, "{\"0\":17,\"1\":{\"0\":17}}");
return FAIL;
}
return OK;
}
struct my_tests_st my_tests[] = {
{"mdev_x1", mdev_x1, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"mdev_4994", mdev_4994, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"create_dyncol_named", create_dyncol_named, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"create_dyncol_num", create_dyncol_num, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"dyncol_column_count", dyncol_column_count, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"dyncol_nested", dyncol_nested, TEST_CONNECTION_NEW, 0, NULL, NULL},
{NULL, NULL, 0, 0, NULL, 0}
};

View File

@@ -2209,7 +2209,7 @@ static int test_bind_negative(MYSQL *mysql)
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
my_bind[0].buffer= (void *)&my_val;
my_bind[0].length= &my_length;
my_bind[0].is_null= (char*)&my_null;
my_bind[0].is_null= &my_null;
rc= mysql_stmt_bind_param(stmt, my_bind);
check_stmt_rc(rc, stmt);
@@ -2400,12 +2400,12 @@ static int test_union_param(MYSQL *mysql)
my_bind[0].buffer= (char*) &my_val;
my_bind[0].buffer_length= 4;
my_bind[0].length= &my_length;
my_bind[0].is_null= (char*)&my_null;
my_bind[0].is_null= &my_null;
my_bind[1].buffer_type= MYSQL_TYPE_STRING;
my_bind[1].buffer= (char*) &my_val;
my_bind[1].buffer_length= 4;
my_bind[1].length= &my_length;
my_bind[1].is_null= (char*)&my_null;
my_bind[1].is_null= &my_null;
rc= mysql_stmt_bind_param(stmt, my_bind);
check_stmt_rc(rc, stmt);
@@ -3313,7 +3313,7 @@ ENGINE=InnoDB DEFAULT CHARSET=utf8");
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
my_bind[0].buffer= (void *)&my_val;
my_bind[0].length= &my_length;
my_bind[0].is_null= (char*)&my_null;
my_bind[0].is_null= &my_null;
my_val= 1;
rc= mysql_stmt_bind_param(stmt, my_bind);
check_stmt_rc(rc, stmt);
@@ -4637,7 +4637,6 @@ static int test_stmt_close(MYSQL *mysql)
FAIL_IF(mysql_stmt_param_count(stmt2) != 1, "param_count != 1");
rc= mysql_stmt_close(stmt1);
check_stmt_rc(rc, stmt1);
/*
Originally we were going to close all statements automatically in

View File

@@ -4654,15 +4654,47 @@ static int test_compress(MYSQL *mysql)
static int test_codbc138(MYSQL *mysql)
{
int rc;
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
MYSQL_TIME tm;
int i= 0;
rc= mysql_stmt_prepare(stmt, SL("SELECT DATE_ADD('2018-02-01', INTERVAL -188 DAY)"));
struct st_time_test {
const char *statement;
MYSQL_TIME tm;
} time_test[]= {
{"SELECT DATE_ADD('2018-02-01', INTERVAL -188 DAY)",
{2017,7,28,0,0,0,0L,0, MYSQL_TIMESTAMP_DATE}
},
{"SELECT '2001-02-03 11:12:13.123456'",
{2001,2,3,11,12,13,123456L,0, MYSQL_TIMESTAMP_DATETIME}
},
{"SELECT '-11:12:13'",
{0,0,0,11,12,13,0,1, MYSQL_TIMESTAMP_TIME}
},
{"SELECT ' '",
{0,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR}
},
{"SELECT '1--'",
{1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR}
},
{"SELECT '-2001-01-01'",
{1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR}
},
{"SELECT '-11:00'",
{1,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_ERROR}
},
{NULL, {0}}
};
while (time_test[i].statement)
{
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, SL(time_test[i].statement));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_store_result(stmt);
memset(bind, 0, sizeof(MYSQL_BIND));
bind[0].buffer_type= MYSQL_TYPE_DATETIME;
@@ -4671,26 +4703,89 @@ static int test_codbc138(MYSQL *mysql)
rc= mysql_stmt_bind_result(stmt, bind);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc, stmt);
diag("test: %s %d %d", time_test[i].statement, tm.time_type, time_test[i].tm.time_type);
if (time_test[i].tm.time_type == MYSQL_TIMESTAMP_ERROR)
{
FAIL_UNLESS(tm.time_type == MYSQL_TIMESTAMP_ERROR, "MYSQL_TIMESTAMP_ERROR expected");
}
else
FAIL_UNLESS(memcmp(&tm, &time_test[i].tm, sizeof(MYSQL_TIME)) == 0, "time_in != time_out");
mysql_stmt_close(stmt);
i++;
}
if (tm.year != 2017 && tm.day != 28 && tm.month != 7)
return OK;
}
static int test_conc334(MYSQL *mysql)
{
diag("Error: Expected 2017-07-02");
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
MYSQL_RES *result;
MYSQL_FIELD *field;
int rc;
rc= mysql_stmt_prepare(stmt, SL("SHOW ENGINES"));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
result= mysql_stmt_result_metadata(stmt);
if (!result)
{
diag("Coudn't retrieve result set");
mysql_stmt_close(stmt);
return FAIL;
}
if (tm.minute | tm.second || tm.second_part)
mysql_field_seek(result, 0);
while ((field= mysql_fetch_field(result)))
{
diag("Error: minute, second or second_part is not zero");
return FAIL;
FAIL_IF(field->name_length == 0, "Invalid name length (0)");
FAIL_IF(field->table_length == 0, "Invalid name length (0)");
}
mysql_free_result(result);
mysql_stmt_close(stmt);
return OK;
}
static int test_conc344(MYSQL *mysql)
{
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
int rc;
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE t1 (a int, b int)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1,1), (2,2),(3,3),(4,4),(5,5)");
check_mysql_rc(rc, mysql);
rc= mysql_stmt_prepare(stmt, SL("SELECT * FROM t1 ORDER BY a"));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
while (!mysql_stmt_fetch(stmt));
FAIL_IF(mysql_stmt_num_rows(stmt) != 5, "expected 5 rows");
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_fetch(stmt);
diag("num_rows: %lld", mysql_stmt_num_rows(stmt));
FAIL_IF(mysql_stmt_num_rows(stmt) != 1, "expected 1 row");
mysql_stmt_close(stmt);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_conc344", test_conc344, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_conc334", test_conc334, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_compress", test_compress, TEST_CONNECTION_NEW, CLIENT_COMPRESS, NULL, NULL},
{"test_codbc138", test_codbc138, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc208", test_conc208, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
@@ -4776,4 +4871,3 @@ int main(int argc, char **argv)
return(exit_status());
}

View File

@@ -30,7 +30,7 @@ static int test_view(MYSQL *mysql)
MYSQL_BIND my_bind[1];
char str_data[50];
ulong length = 0L;
long is_null = 0L;
my_bool is_null = 0;
const char *query=
"SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
@@ -84,7 +84,7 @@ static int test_view(MYSQL *mysql)
my_bind[0].buffer_length= 50;
my_bind[0].length= &length;
length= 4;
my_bind[0].is_null= (char*)&is_null;
my_bind[0].is_null= &is_null;
rc= mysql_stmt_bind_param(stmt, my_bind);
check_stmt_rc(rc, stmt);
@@ -301,7 +301,7 @@ static int test_view_insert(MYSQL *mysql)
MYSQL_BIND my_bind[1];
int my_val = 0;
ulong my_length = 0L;
long my_null = 0L;
my_bool my_null = 0;
const char *query=
"insert into v1 values (?)";
@@ -328,7 +328,7 @@ static int test_view_insert(MYSQL *mysql)
my_bind[0].buffer_type = MYSQL_TYPE_LONG;
my_bind[0].buffer = (char *)&my_val;
my_bind[0].length = &my_length;
my_bind[0].is_null = (char*)&my_null;
my_bind[0].is_null = &my_null;
rc= mysql_stmt_bind_param(insert_stmt, my_bind);
check_stmt_rc(rc, select_stmt);