Description:
According to specs(http://msdn.microsoft.com/en-us/library/windows/desktop/ms712436%28v=vs.85%29.aspx) if TIME sql data converted to TIMESTAMP, date fields of the timestamp structure are set to the current date, and the fraction field is set to null. But if value of time field >= 24h, the result timestamp structure will contain incorrect timestamp. Besides fraction field of that structure won't be reset.
How to repeat:
DECLARE_TEST(t_bugtime2ts)
{
SQL_TIMESTAMP_STRUCT ts;
SQLLEN outlen= 0;
/* make sure we have reset everything to zero */
memset(&ts, 0, sizeof(SQL_TIMESTAMP_STRUCT));
/* check situations with sec and min overflow */
ok_sql(hstmt, "SELECT CAST('24:45:07.0001' AS TIME(6))");
ok_stmt(hstmt, SQLFetch(hstmt));
ok_stmt(hstmt, SQLGetData(hstmt, 1, SQL_TIMESTAMP, &ts, sizeof(ts), &outlen));
is_num(outlen, sizeof(ts));
/* hour cannot go out of unsigned smallint range */
is_num(ts.hour, 0);
is_num(ts.minute, 45);
is_num(ts.second, 7);
/* Fractional seconds must be 0 no matter what is actually in the field */
is_num(ts.fraction, 0);
{
/* We need tomorrow date */
time_t t= time(NULL) + 24*60*60;
struct tm *cur_tm= localtime(&t);
is_num(ts.year, 1900 + cur_tm->tm_year);
is_num(ts.month, 1 + cur_tm->tm_mon);
is_num(ts.day, cur_tm->tm_mday);
}
ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
return OK;
}
Suggested fix:
=== modified file 'driver/results.c'
--- driver/results.c 2013-04-22 11:46:11 +0000
+++ driver/results.c 2013-06-21 20:07:43 +0000
@@ -573,6 +573,13 @@
(SQL_TIMESTAMP_STRUCT *)rgbValue;
time_t sec_time= time(NULL);
struct tm cur_tm;
+
+ if (ts.hour > 23)
+ {
+ sec_time+= (ts.hour/24)*24*60*60;
+ ts.hour= ts.hour%24;
+ }
+
localtime_r(&sec_time, &cur_tm);
/* I wornder if that hasn't to be server current date*/
@@ -582,7 +589,8 @@
timestamp_info->hour= ts.hour;
timestamp_info->minute= ts.minute;
timestamp_info->second= ts.second;
- get_fractional_part(tmp, SQL_NTS, TRUE, ×tamp_info->fraction);
+ /* Fractional seconds must be 0 no matter what is actually in the field */
+ timestamp_info->fraction= 0;
*pcbValue= sizeof(SQL_TIMESTAMP_STRUCT);
}
}