Skip to content

Commit 6927482

Browse files
alinaliBQrscales
andcommitted
Extract SQLFreeStmt implementation
Add statement allocate tests Co-Authored-By: rscales <robscales@icloud.com>
1 parent 5aa7dd1 commit 6927482

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,45 @@ SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle) {
219219
SQLRETURN SQLFreeStmt(SQLHSTMT handle, SQLUSMALLINT option) {
220220
ARROW_LOG(DEBUG) << "SQLFreeStmt called with handle: " << handle
221221
<< ", option: " << option;
222-
// GH-47706 TODO: Implement SQLFreeStmt
223-
return SQL_INVALID_HANDLE;
222+
223+
switch (option) {
224+
case SQL_CLOSE: {
225+
using ODBC::ODBCStatement;
226+
227+
return ODBCStatement::ExecuteWithDiagnostics(handle, SQL_ERROR, [=]() {
228+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(handle);
229+
230+
// Close cursor with suppressErrors set to true
231+
statement->CloseCursor(true);
232+
233+
return SQL_SUCCESS;
234+
});
235+
}
236+
237+
case SQL_DROP: {
238+
return SQLFreeHandle(SQL_HANDLE_STMT, handle);
239+
}
240+
241+
case SQL_UNBIND: {
242+
// GH-47716 TODO: Add tests for SQLBindCol unbinding
243+
using ODBC::ODBCDescriptor;
244+
using ODBC::ODBCStatement;
245+
return ODBCStatement::ExecuteWithDiagnostics(handle, SQL_ERROR, [=]() {
246+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(handle);
247+
ODBCDescriptor* ard = statement->GetARD();
248+
// Unbind columns
249+
ard->SetHeaderField(SQL_DESC_COUNT, (void*)0, 0);
250+
return SQL_SUCCESS;
251+
});
252+
}
253+
254+
// SQLBindParameter is not supported
255+
case SQL_RESET_PARAMS: {
256+
return SQL_SUCCESS;
257+
}
258+
}
259+
260+
return SQL_ERROR;
224261
}
225262

226263
inline bool IsValidStringFieldArgs(SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length,

cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,4 +468,47 @@ TYPED_TEST(ConnectionHandleTest, TestSQLDisconnectWithoutConnection) {
468468
TYPED_TEST(ConnectionTest, TestConnect) {
469469
// Verifies connect and disconnect works on its own
470470
}
471+
472+
TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) {
473+
SQLHSTMT statement;
474+
475+
// Allocate a statement using alloc statement
476+
ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement));
477+
478+
SQLWCHAR sql_buffer[kOdbcBufferSize] = L"SELECT 1";
479+
ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(statement, sql_buffer, SQL_NTS));
480+
481+
// Close statement handle
482+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_CLOSE));
483+
484+
// Free statement handle
485+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_DROP));
486+
}
487+
488+
TYPED_TEST(ConnectionHandleTest, TestCloseConnectionWithOpenStatement) {
489+
SQLHSTMT statement;
490+
491+
// Connect string
492+
std::string connect_str = this->GetConnectionString();
493+
ASSERT_OK_AND_ASSIGN(std::wstring wconnect_str,
494+
arrow::util::UTF8ToWideString(connect_str));
495+
std::vector<SQLWCHAR> connect_str0(wconnect_str.begin(), wconnect_str.end());
496+
497+
SQLWCHAR out_str[kOdbcBufferSize] = L"";
498+
SQLSMALLINT out_str_len;
499+
500+
// Connecting to ODBC server.
501+
ASSERT_EQ(SQL_SUCCESS,
502+
SQLDriverConnect(this->conn, NULL, &connect_str0[0],
503+
static_cast<SQLSMALLINT>(connect_str0.size()), out_str,
504+
kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT))
505+
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn);
506+
507+
// Allocate a statement using alloc statement
508+
ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement));
509+
510+
// Disconnect from ODBC without closing the statement first
511+
ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn));
512+
}
513+
471514
} // namespace arrow::flight::sql::odbc

0 commit comments

Comments
 (0)