Index: driver/options.c =================================================================== --- driver/options.c (revision 1012) +++ driver/options.c (working copy) @@ -381,19 +381,31 @@ if (trans_supported(dbc)) { char buff[80]; - const char *level; + const char *level= NULL; - if ((SQLINTEGER)(SQLLEN)ValuePtr & SQL_TXN_SERIALIZABLE) + if ((SQLINTEGER)ValuePtr == SQL_TXN_SERIALIZABLE) level="SERIALIZABLE"; - else if ((SQLINTEGER)(SQLLEN)ValuePtr & SQL_TXN_REPEATABLE_READ) + else if ((SQLINTEGER)ValuePtr == SQL_TXN_REPEATABLE_READ) level="REPEATABLE READ"; - else if ((SQLINTEGER)(SQLLEN)ValuePtr & SQL_TXN_REPEATABLE_READ) + else if ((SQLINTEGER)ValuePtr == SQL_TXN_READ_COMMITTED) level="READ COMMITTED"; + else if ((SQLINTEGER)ValuePtr == SQL_TXN_READ_UNCOMMITTED) + level="READ UNCOMMITTED"; + + if (level) + { + SQLRETURN rc; + sprintf(buff,"SET SESSION TRANSACTION ISOLATION LEVEL %s", + level); + if (SQL_SUCCEEDED(rc = odbc_stmt(dbc,buff))) + dbc->txn_isolation= (SQLINTEGER)ValuePtr; + return rc; + } else - level="READ UNCOMMITTED"; - sprintf(buff,"SET SESSION TRANSACTION ISOLATION LEVEL %s",level); - if (odbc_stmt(dbc,buff) == SQL_SUCCESS) - dbc->txn_isolation= (SQLINTEGER)(SQLLEN)ValuePtr; + { + return set_dbc_error(dbc, "HY024", + "Invalid attribute value", 0); + } } break; Index: test/my_basics.c =================================================================== --- test/my_basics.c (revision 1012) +++ test/my_basics.c (working copy) @@ -505,6 +505,54 @@ } +/* + Bug #31959 - Allows dirty reading with SQL_TXN_READ_COMMITTED + isolation through ODBC +*/ +DECLARE_TEST(t_bug31959) +{ + SQLCHAR level[50] = "uninitialized"; + SQLINTEGER i; + SQLINTEGER levelid[] = {SQL_TXN_SERIALIZABLE, SQL_TXN_REPEATABLE_READ, + SQL_TXN_READ_COMMITTED, SQL_TXN_READ_UNCOMMITTED}; + SQLCHAR *levelname[] = {"SERIALIZABLE", "REPEATABLE-READ", + "READ-COMMITTED", "READ-UNCOMMITTED"}; + + ok_stmt(hstmt, SQLPrepare(hstmt, "select @@tx_isolation", SQL_NTS)); + + /* check all 4 valid isolation levels */ + for(i = 3; i >= 0; --i) + { + ok_con(hdbc, SQLSetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION, + (SQLPOINTER)levelid[i], 0)); + ok_stmt(hstmt, SQLExecute(hstmt)); + ok_stmt(hstmt, SQLFetch(hstmt)); + ok_stmt(hstmt, SQLGetData(hstmt, 1, SQL_C_CHAR, level, 50, NULL)); + is_str(level, levelname[i], strlen(levelname[i])); + printMessage("Level = %s\n", level); + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); + } + + /* check invalid value (and corresponding SQL state) */ + is(SQLSetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)999, 0) == + SQL_ERROR); + { + SQLCHAR sql_state[6]; + SQLINTEGER err_code= 0; + SQLCHAR err_msg[SQL_MAX_MESSAGE_LENGTH]= {0}; + SQLSMALLINT err_len= 0; + + memset(err_msg, 'C', SQL_MAX_MESSAGE_LENGTH); + SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, sql_state, &err_code, err_msg, + SQL_MAX_MESSAGE_LENGTH - 1, &err_len); + + is_str(sql_state, (SQLCHAR *)"HY024", 5); + } + + return OK; +} + + BEGIN_TESTS ADD_TEST(my_basics) ADD_TEST(t_max_select) @@ -520,6 +568,7 @@ ADD_TEST(t_bug30774) ADD_TEST(t_bug30840) ADD_TEST(t_bug32727) + ADD_TEST(t_bug31959) END_TESTS