Index: ChangeLog =================================================================== --- ChangeLog (revision 614) +++ ChangeLog (working copy) @@ -7,6 +7,8 @@ ODBC logging should be used. Bugs fixed: + * SQLColumns() incorrectly reported that an auto-updating timestamp + field was not nullable. (Bug #14414) * SQLSpecialColumns() returned all TIMESTAMP fields when queried for SQL_ROWVER, not just an auto-updating TIMESTAMP field. (Bug #9927, still limited by Bug #30081 in the server.) Index: driver/catalog.c =================================================================== --- driver/catalog.c (revision 614) +++ driver/catalog.c (working copy) @@ -863,7 +863,12 @@ row[15]= strdup_root(alloc, buff); /* CHAR_OCTET_LENGTH */ } - if ((field->flags & NOT_NULL_FLAG) == NOT_NULL_FLAG) + /* + If a field has TIMESTAMP_FLAG set, it's an auto-updating timestamp + field, and NULL can be stored to it (although it gets turned into + something else). + */ + if ((field->flags & NOT_NULL_FLAG) && !(field->flags & TIMESTAMP_FLAG)) { sprintf(buff, "%d", SQL_NO_NULLS); row[10]= strdup_root(alloc, buff); /* NULLABLE */ Index: test/my_datetime.c =================================================================== --- test/my_datetime.c (revision 614) +++ test/my_datetime.c (working copy) @@ -722,8 +722,6 @@ */ DECLARE_TEST(t_bug30081) { - SQLCHAR col[10]; - ok_sql(hstmt, "DROP TABLE IF EXISTS t_bug30081"); ok_sql(hstmt, "CREATE TABLE t_bug30081 (a TIMESTAMP DEFAULT 0," @@ -741,6 +739,46 @@ return OK; } + + +/** + Bug #14414: SQLColumn() does not return timestamp nullable attribute correctly +*/ +DECLARE_TEST(t_bug14414) +{ + SQLCHAR col[10]; + + ok_sql(hstmt, "DROP TABLE IF EXISTS t_bug14414"); + ok_sql(hstmt, "CREATE TABLE t_bug14414(a TIMESTAMP, b TIMESTAMP NOT NULL," + "c TIMESTAMP NULL)"); + + ok_stmt(hstmt, SQLColumns(hstmt, NULL, 0, NULL, 0, + (SQLCHAR *)"t_bug14414", SQL_NTS, NULL, 0)); + + ok_stmt(hstmt, SQLFetch(hstmt)); + is_str(my_fetch_str(hstmt, col, 4), "a", 1); + is_num(my_fetch_int(hstmt, 11), SQL_NULLABLE); + is_str(my_fetch_str(hstmt, col, 18), "YES", 3); + + ok_stmt(hstmt, SQLFetch(hstmt)); + is_str(my_fetch_str(hstmt, col, 4), "b", 1); + is_num(my_fetch_int(hstmt, 11), SQL_NO_NULLS); + is_str(my_fetch_str(hstmt, col, 18), "NO", 3); + + ok_stmt(hstmt, SQLFetch(hstmt)); + is_str(my_fetch_str(hstmt, col, 4), "c", 1); + is_num(my_fetch_int(hstmt, 11), SQL_NULLABLE); + is_str(my_fetch_str(hstmt, col, 18), "YES", 3); + + expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA); + + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); + + ok_sql(hstmt, "DROP TABLE IF EXISTS t_bug14414"); + return OK; +} + + BEGIN_TESTS ADD_TEST(my_ts) ADD_TEST(t_tstotime) @@ -752,6 +790,7 @@ ADD_TEST(t_bug15773) ADD_TEST(t_bug9927) ADD_TODO(t_bug30081) + ADD_TEST(t_bug14414) END_TESTS