Skip to content

Commit 9111134

Browse files
author
Bogdan Degtyariov
committed
Bug#26474326 - SQLCloseCursor does not return correct error
Change-Id: I483dff7681fda43f49616078c526992bb7a8129e
1 parent ef906e3 commit 9111134

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

driver/cursor.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,21 @@ SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT Handle, SQLSMALLINT Operation)
19861986
SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT Handle)
19871987
{
19881988
CHECK_HANDLE(Handle);
1989+
STMT *stmt = (STMT*)Handle;
19891990

1990-
return my_SQLFreeStmt(Handle, SQL_CLOSE);
1991+
/*
1992+
In this case the existence of a cursor is assumed if
1993+
a result exists in a statement.
1994+
The check has to be done before freeing STMT.
1995+
*/
1996+
bool no_cursor = !stmt->result;
1997+
SQLRETURN res = my_SQLFreeStmt(Handle, SQL_CLOSE);
1998+
1999+
2000+
if ( no_cursor )
2001+
{
2002+
return stmt->set_error("24000", "Invalid cursor state", 0);
2003+
}
2004+
2005+
return res;
19912006
}

test/my_cursor.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,7 +3418,42 @@ DECLARE_TEST(t_18805455)
34183418
}
34193419

34203420

3421+
/*
3422+
Bug#26474326 - SQLCLOSECURSOR DOES NOT RETURN CORRECT ERROR
3423+
*/
3424+
DECLARE_TEST(t_bug26474326_sqlclosecursor)
3425+
{
3426+
SQLCHAR sqlstate[6], message[SQL_MAX_MESSAGE_LENGTH + 1];
3427+
SQLINTEGER native_error = 0;
3428+
SQLSMALLINT length = 0;
3429+
const char *expected_msg = "Invalid cursor state";
3430+
3431+
SQLRETURN res = SQLCloseCursor(hstmt);
3432+
3433+
// Make the buffer safe for use of strstr() function
3434+
#define CHECK_INVALID_CURSOR_ERROR is_num(SQL_ERROR, res); \
3435+
memset(message, 0, SQL_MAX_MESSAGE_LENGTH + 1); \
3436+
SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, sqlstate, &native_error, \
3437+
message, SQL_MAX_MESSAGE_LENGTH - 1, &length); \
3438+
is_str("24000", sqlstate, 5); \
3439+
is(NULL != strstr((const char*)message, expected_msg))
3440+
3441+
CHECK_INVALID_CURSOR_ERROR;
3442+
3443+
ok_sql(hstmt, "SELECT 1");
3444+
// This call should succeed because the result set exists.
3445+
ok_stmt(hstmt, SQLCloseCursor(hstmt));
3446+
3447+
// Result set is closed by the previous call. Error is expected.
3448+
res = SQLCloseCursor(hstmt);
3449+
CHECK_INVALID_CURSOR_ERROR;
3450+
3451+
return OK;
3452+
}
3453+
3454+
34213455
BEGIN_TESTS
3456+
ADD_TEST(t_bug26474326_sqlclosecursor)
34223457
ADD_TEST(my_positioned_cursor)
34233458
ADD_TEST(my_setpos_cursor)
34243459
ADD_TEST(t_bug5853)

0 commit comments

Comments
 (0)