You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
Fix for CONC-371: Incorrect fractional part conversion
If a datetime or time value is represented a a string and has a fractional part with less than 6 digits, it should be interpreted as a 6-digit representation: .9 becomes 900000 .09 becomes 90000 etc.
This commit is contained in:
@@ -198,7 +198,9 @@ 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 str_to_TIME(const char *str, size_t length, MYSQL_TIME *tm)
|
||||||
{
|
{
|
||||||
char *start= alloca(length + 1);
|
char *start= alloca(length + 1),
|
||||||
|
*begin= start,
|
||||||
|
*frac;
|
||||||
my_bool is_date= 0, is_time= 0;
|
my_bool is_date= 0, is_time= 0;
|
||||||
|
|
||||||
memset(tm, 0, sizeof(MYSQL_TIME));
|
memset(tm, 0, sizeof(MYSQL_TIME));
|
||||||
@@ -250,11 +252,15 @@ my_bool str_to_TIME(const char *str, size_t length, MYSQL_TIME *tm)
|
|||||||
else
|
else
|
||||||
tm->time_type= MYSQL_TIMESTAMP_TIME;
|
tm->time_type= MYSQL_TIMESTAMP_TIME;
|
||||||
|
|
||||||
if (strchr(start, '.')) /* fractional seconds */
|
if ((frac= strchr(start, '.'))) /* fractional seconds */
|
||||||
{
|
{
|
||||||
|
size_t frac_len= (begin + length) - (frac + 1);
|
||||||
if (sscanf(start, "%d:%d:%d.%ld", &tm->hour, &tm->minute,
|
if (sscanf(start, "%d:%d:%d.%ld", &tm->hour, &tm->minute,
|
||||||
&tm->second,&tm->second_part) < 4)
|
&tm->second,&tm->second_part) < 4)
|
||||||
goto error;
|
goto error;
|
||||||
|
/* conc-371 */
|
||||||
|
if (frac_len < 6)
|
||||||
|
tm->second_part*= pow(10, 6 - frac_len);
|
||||||
} else {
|
} else {
|
||||||
if (sscanf(start, "%d:%d:%d", &tm->hour, &tm->minute,
|
if (sscanf(start, "%d:%d:%d", &tm->hour, &tm->minute,
|
||||||
&tm->second) < 3)
|
&tm->second) < 3)
|
||||||
|
@@ -4783,6 +4783,54 @@ static int test_conc344(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_conc_fraction(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
MYSQL_TIME tm;
|
||||||
|
MYSQL_BIND bind[1];
|
||||||
|
char query[1024];
|
||||||
|
int i;
|
||||||
|
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
for (i=0; i < 6; i++)
|
||||||
|
{
|
||||||
|
unsigned long expected= 0;
|
||||||
|
sprintf(query, "SELECT '2018-11-05 22:25:59.%0*d'", i + 1, 9);
|
||||||
|
|
||||||
|
diag("%d: %s", i, query);
|
||||||
|
|
||||||
|
rc= mysql_stmt_prepare(stmt, SL(query));
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_stmt_rc(rc, 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;
|
||||||
|
bind[0].buffer= &tm;
|
||||||
|
bind[0].buffer_length= sizeof(MYSQL_TIME);
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_result(stmt, bind);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
rc= mysql_stmt_fetch(stmt);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
diag("second_part: %ld", tm.second_part);
|
||||||
|
|
||||||
|
expected= 9 * powl(10, (5 - i));
|
||||||
|
|
||||||
|
FAIL_IF(tm.second_part != expected, "expected fractional part to be 900000");
|
||||||
|
|
||||||
|
}
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
{"test_conc344", test_conc344, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_conc344", test_conc344, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc334", test_conc334, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_conc334", test_conc334, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
@@ -4857,6 +4905,7 @@ struct my_tests_st my_tests[] = {
|
|||||||
{"test_sshort_bug", test_sshort_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
{"test_sshort_bug", test_sshort_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
{"test_stiny_bug", test_stiny_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
{"test_stiny_bug", test_stiny_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
{"test_bug53311", test_bug53311, TEST_CONNECTION_NEW, 0, NULL , NULL},
|
{"test_bug53311", test_bug53311, TEST_CONNECTION_NEW, 0, NULL , NULL},
|
||||||
|
{"test_conc_fraction", test_conc_fraction, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user