1
0
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:
Georg Richter
2018-11-06 10:03:15 +01:00
parent 639413cb21
commit 70082afeb7
2 changed files with 57 additions and 2 deletions

View File

@@ -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)
{
char *start= alloca(length + 1);
char *start= alloca(length + 1),
*begin= start,
*frac;
my_bool is_date= 0, is_time= 0;
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
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,
&tm->second,&tm->second_part) < 4)
goto error;
/* conc-371 */
if (frac_len < 6)
tm->second_part*= pow(10, 6 - frac_len);
} else {
if (sscanf(start, "%d:%d:%d", &tm->hour, &tm->minute,
&tm->second) < 3)

View File

@@ -4783,6 +4783,54 @@ static int test_conc344(MYSQL *mysql)
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[] = {
{"test_conc344", test_conc344, 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_stiny_bug", test_stiny_bug, TEST_CONNECTION_DEFAULT, 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}
};