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

changed plugin library types from SHARED to MODULE

Fixed float/double/decimal converion for prepared statements:
  since _gcvt (Windows) and gcvt (*nix) deliver different results
  we use now dtoa.c from server package, which is licensed under
  LGPL.
This commit is contained in:
Georg Richter
2016-03-11 07:08:34 +01:00
parent 826da74f6c
commit 2f6791115f
11 changed files with 2906 additions and 93 deletions

View File

@@ -530,6 +530,7 @@ extern double my_atof(const char*);
#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
#endif
#define INT_MIN64 (~0x7FFFFFFFFFFFFFFFLL)
#define INT_MAX64 0x7FFFFFFFFFFFFFFFLL
#define INT_MIN32 (~0x7FFFFFFFL)
@@ -646,6 +647,13 @@ typedef long longlong;
#define longlong_defined
#endif
#ifndef HAVE_INT64
typedef longlong int64;
#endif
#ifndef HAVE_UINT64
typedef ulonglong uint64;
#endif
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif

View File

@@ -23,6 +23,14 @@
#include <string.h>
typedef enum {
MY_GCVT_ARG_FLOAT,
MY_GCVT_ARG_DOUBLE
} my_gcvt_arg_type;
size_t ma_fcvt(double x, int precision, char *to, my_bool *error);
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);
#endif

View File

@@ -262,6 +262,7 @@ mariadb_stmt.c
ma_loaddata.c
ma_stmt_codec.c
ma_string.c
ma_dtoa.c
${CMAKE_BINARY_DIR}/libmariadb/ma_client_plugin.c
ma_io.c
${SSL_SOURCES}

2826
libmariadb/ma_dtoa.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -61,6 +61,7 @@
#endif
#define UINT_MAX8 0xFF
#define MAX_DOUBLE_STRING_REP_LENGTH 300
#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
#define LONGLONG_MIN ((long long) 0x8000000000000000LL)
#define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL)
@@ -570,33 +571,20 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl
break;
default:
{
#define MAX_DOUBLE_STRING_REP_LENGTH 300
char buff[MAX_DOUBLE_STRING_REP_LENGTH];
size_t length;
char *end;
length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);
/* if (field->decimals >= NOT_FIXED_DEC)
if (field->decimals >= NOT_FIXED_DEC)
{
sprintf(buff, "%-*.*g", (int) length-1, DBL_DIG, val);
length= strlen(buff);
length= ma_gcvt(val, MY_GCVT_ARG_FLOAT, length, buff, NULL);
}
else */
else
{
#ifdef _WIN32
_gcvt(val, 6, buff);
#else
gcvt(val, 6, buff);
#endif
length= strlen(buff);
length= ma_fcvt(val, field->decimals, buff, NULL);
}
/* remove trailing blanks */
end= strchr(buff, '\0') - 1;
while (end > buff && *end == ' ')
*end--= '\0';
/* check if ZEROFILL flag is active */
if (field->flags & ZEROFILL_FLAG)
{
@@ -612,34 +600,6 @@ static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, fl
}
}
/* {{{ ps_fetch_float */
static
void ps_fetch_float(MYSQL_BIND *r_param, const MYSQL_FIELD * field, unsigned char **row)
{
switch(r_param->buffer_type)
{
case MYSQL_TYPE_FLOAT:
{
float *value= (float *)r_param->buffer;
float4get(*value, *row);
r_param->buffer_length= 4;
*r_param->error= 0;
}
break;
default:
{
float value;
memcpy(&value, *row, sizeof(float));
float4get(value, (char *)*row);
convert_from_float(r_param, field, value, sizeof(float));
}
break;
}
(*row)+= 4;
}
/* }}} */
static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, double val, int size)
{
double check_trunc_val= (val > 0) ? floor(val) : -floor(-val);
@@ -708,33 +668,20 @@ static void convert_from_double(MYSQL_BIND *r_param, const MYSQL_FIELD *field, d
break;
default:
{
#define MAX_DOUBLE_STRING_REP_LENGTH 300
char buff[MAX_DOUBLE_STRING_REP_LENGTH];
size_t length;
char *end;
length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);
if (field->decimals >= NOT_FIXED_DEC)
{
sprintf(buff, "%-*.*g", (int) length-1, DBL_DIG, val);
length= strlen(buff);
length= ma_gcvt(val, MY_GCVT_ARG_DOUBLE, length, buff, NULL);
}
else
{
#ifdef _WIN32
#else
gcvt(val, field->decimals, buff);
#endif
// sprintf(buff, "%.*f", field->decimals, val);
length= strlen(buff);
length= ma_fcvt(val, field->decimals, buff, NULL);
}
/* remove trailing blanks */
end= strchr(buff, '\0') - 1;
while (end > buff && *end == ' ')
*end--= '\0';
/* check if ZEROFILL flag is active */
if (field->flags & ZEROFILL_FLAG)
{
@@ -776,6 +723,32 @@ void ps_fetch_double(MYSQL_BIND *r_param, const MYSQL_FIELD * field , unsigned c
}
/* }}} */
/* {{{ ps_fetch_float */
static
void ps_fetch_float(MYSQL_BIND *r_param, const MYSQL_FIELD * field, unsigned char **row)
{
switch(r_param->buffer_type)
{
case MYSQL_TYPE_FLOAT:
{
float *value= (float *)r_param->buffer;
float4get(*value, *row);
r_param->buffer_length= 4;
*r_param->error= 0;
}
break;
default:
{
float value;
memcpy(&value, *row, sizeof(float));
float4get(value, (char *)*row);
convert_from_float(r_param, field, value, sizeof(float));
}
break;
}
(*row)+= 4;
}
/* }}} */
static void convert_to_datetime(MYSQL_TIME *t, unsigned char **row, uint len, enum enum_field_types type)
{

View File

@@ -20,7 +20,7 @@ IF(AUTH_DIALOG_PLUGIN_TYPE MATCHES "DYNAMIC")
IF(WIN32)
SET(DIALOG_SOURCES ${DIALOG_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
ENDIF()
ADD_LIBRARY(dialog SHARED ${DIALOG_SOURCES})
ADD_LIBRARY(dialog MODULE ${DIALOG_SOURCES})
SET_TARGET_PROPERTIES(dialog PROPERTIES PREFIX "")
INSTALL_PLUGIN(dialog ${CMAKE_BINARY_DIR}/plugins/auth)
SIGN_TARGET(dialog)
@@ -40,7 +40,7 @@ IF(AUTH_OLDPASSWORD_PLUGIN_TYPE MATCHES "DYNAMIC")
IF(WIN32)
SET(OLDPASSWORD_SOURCES ${DIALOG_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
ENDIF()
ADD_LIBRARY(mysql_old_password SHARED ${OLDPASSWORD_SOURCES})
ADD_LIBRARY(mysql_old_password MODULE ${OLDPASSWORD_SOURCES})
SET_TARGET_PROPERTIES(mysql_old_password PROPERTIES PREFIX "")
INSTALL_PLUGIN(mysql_old_password ${CMAKE_BINARY_DIR}/plugins/auth)
SIGN_TARGET(mysql_old_password)
@@ -60,7 +60,7 @@ IF(AUTH_CLEARTEXT_PLUGIN_TYPE MATCHES "DYNAMIC")
IF(WIN32)
SET(CTEXT_SOURCES ${CTEXT_SOURCES} ${mysql_clear_password_RC} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
ENDIF()
ADD_LIBRARY(mysql_clear_password SHARED ${CTEXT_SOURCES})
ADD_LIBRARY(mysql_clear_password MODULE ${CTEXT_SOURCES})
SET_TARGET_PROPERTIES(mysql_clear_password PROPERTIES PREFIX "")
INSTALL_PLUGIN(mysql_clear_password ${CMAKE_BINARY_DIR}/plugins/auth)
SIGN_TARGET(mysql_clear_password)
@@ -87,7 +87,7 @@ IF(${AUTH_GSSAPI_PLUGIN_TYPE} MATCHES "DYNAMIC")
ENDIF()
ENDIF()
IF(GSSAPI_FOUND OR WIN32)
ADD_LIBRARY(auth_gssapi_client SHARED ${GSSAPI_SOURCES})
ADD_LIBRARY(auth_gssapi_client MODULE ${GSSAPI_SOURCES})
IF(WIN32)
TARGET_LINK_LIBRARIES(auth_gssapi_client secur32.lib)
ELSE()

View File

@@ -14,7 +14,7 @@ IF(REPLICATION_PLUGIN_TYPE MATCHES "DYNAMIC")
"FILE_DESCRIPTION:Connection plugin for master/slave environment")
ENDIF()
ADD_DEFINITIONS(-DHAVE_REPLICATION_DYNAMIC=1)
ADD_LIBRARY(replication SHARED ${replication_RC} replication.c ${EXPORT_FILE})
ADD_LIBRARY(replication MODULE ${replication_RC} replication.c ${EXPORT_FILE})
IF(WIN32)
TARGET_LINK_LIBRARIES(replication libmariadb)
ENDIF()
@@ -30,7 +30,7 @@ IF(AURORA_PLUGIN_TYPE MATCHES "DYNAMIC")
"FILE_DESCRIPTION:Connection plugin for Amazon AWS Aurora")
ENDIF()
ADD_DEFINITIONS(-DHAVE_AURORA_DYNAMIC=1)
ADD_LIBRARY(aurora SHARED ${aurora_RC} aurora.c ${EXPORT_FILE})
ADD_LIBRARY(aurora MODULE ${aurora_RC} aurora.c ${EXPORT_FILE})
IF(WIN32)
TARGET_LINK_LIBRARIES(aurora libmariadb)
ENDIF()

View File

@@ -18,7 +18,7 @@ IF(REMOTEIO_PLUGIN_TYPE MATCHES "DYNAMIC")
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
SET(REMOTE_IO_SOURCES ${remote_io_RC} remote_io.c)
ADD_DEFINITIONS(-DHAVE_REMOTEIO_DYNAMIC=1)
ADD_LIBRARY(remote_io SHARED ${REMOTE_IO_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
ADD_LIBRARY(remote_io MODULE ${REMOTE_IO_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
TARGET_LINK_LIBRARIES(remote_io ${CURL_LIBRARIES})
SET_TARGET_PROPERTIES(remote_io PROPERTIES PREFIX "")
INSTALL_PLUGIN(remote_io ${CMAKE_BINARY_DIR}/plugins/io)

View File

@@ -20,7 +20,7 @@ IF(SOCKET_PLUGIN_TYPE MATCHES "DYNAMIC")
"FILE_DESCRIPTION:VIO plugin for socket communication")
ENDIF()
ADD_DEFINITIONS(-DHAVE_SOCKET_DYNAMIC=1)
ADD_LIBRARY(pvio_socket SHARED ${pvio_socket_RC} pvio_socket.c ${EXPORT_FILE})
ADD_LIBRARY(pvio_socket MODULE ${pvio_socket_RC} pvio_socket.c ${EXPORT_FILE})
INSTALL_PLUGIN(pvio_socket ${CMAKE_BINARY_DIR}/plugins/pvio)
SIGN_TARGET(pvio_socket)
ENDIF()
@@ -35,7 +35,7 @@ IF(WIN32)
"FILE_DESCRIPTION:VIO plugin for named pipe communication")
ENDIF()
ADD_DEFINITIONS(-DHAVE_NPIPE_DYNAMIC=1)
ADD_LIBRARY(pvio_npipe SHARED ${pvio_npipe_RC} pvio_npipe.c ${EXPORT_FILE})
ADD_LIBRARY(pvio_npipe MODULE ${pvio_npipe_RC} pvio_npipe.c ${EXPORT_FILE})
INSTALL_PLUGIN(pvio_npipe ${CMAKE_BINARY_DIR}/plugins/pvio)
SIGN_TARGET(pvio_npipe)
ENDIF()
@@ -48,7 +48,7 @@ IF(WIN32)
"ORIGINAL_FILE_NAME:pvio_shmem.dll"
"FILE_DESCRIPTION:VIO plugin for shared memory communication")
ENDIF()
ADD_LIBRARY(pvio_shmem SHARED ${pvio_shmem_RC} pvio_shmem.c ${EXPORT_FILE})
ADD_LIBRARY(pvio_shmem MODULE ${pvio_shmem_RC} pvio_shmem.c ${EXPORT_FILE})
INSTALL_PLUGIN(pvio_shmem ${CMAKE_BINARY_DIR}/plugins/pvio)
SIGN_TARGET(pvio_shmem)
ENDIF()

View File

@@ -18,7 +18,7 @@ IF(TRACE_EXAMPLE_PLUGIN_TYPE MATCHES "DYNAMIC")
IF(WIN32)
SET(TRACE_EXAMPLE_SOURCES ${TRACE_EXAMPLE_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
ENDIF()
ADD_LIBRARY(trace_example SHARED ${TRACE_EXAMPLE_SOURCES})
ADD_LIBRARY(trace_example MODULE ${TRACE_EXAMPLE_SOURCES})
SET_TARGET_PROPERTIES(trace_example PROPERTIES PREFIX "")
INSTALL_PLUGIN(trace_example ${CMAKE_BINARY_DIR}/plugins/trace)
SIGN_TARGET(trace_example)

View File

@@ -2339,10 +2339,6 @@ static int test_bug4172(MYSQL *mysql)
char f[100], d[100], e[100];
ulong f_len, d_len, e_len;
diag("numeric precision in ps not fixed now");
return SKIP;
mysql_query(mysql, "DROP TABLE IF EXISTS t1");
mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
@@ -2378,6 +2374,7 @@ static int test_bug4172(MYSQL *mysql)
row= mysql_fetch_row(res);
diag("expected %s %s %s", row[0], row[1], row[2]);
diag("fetched %s %s %s", f, d, e);
FAIL_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]), "");
mysql_free_result(res);