Skip to content

Commit 7363d52

Browse files
authored
GH-47706: [C++][FlightRPC] ODBC SQLFreeStmt implementation (#48033)
### Rationale for this change Support statement deallocation ### What changes are included in this PR? - Implement SQLFreeStmt - Add tests ### Are these changes tested? Tested locally on MSVC CI ### Are there any user-facing changes? N/A * GitHub Issue: #47706 Authored-by: Alina (Xi) Li <[email protected]> Signed-off-by: David Li <[email protected]>
1 parent 95cdc0c commit 7363d52

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,4 +468,44 @@ 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+
// Close statement handle
479+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_CLOSE));
480+
481+
// Free statement handle
482+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_DROP));
483+
}
484+
485+
TYPED_TEST(ConnectionHandleTest, TestCloseConnectionWithOpenStatement) {
486+
SQLHSTMT statement;
487+
488+
// Connect string
489+
std::string connect_str = this->GetConnectionString();
490+
ASSERT_OK_AND_ASSIGN(std::wstring wconnect_str,
491+
arrow::util::UTF8ToWideString(connect_str));
492+
std::vector<SQLWCHAR> connect_str0(wconnect_str.begin(), wconnect_str.end());
493+
494+
SQLWCHAR out_str[kOdbcBufferSize] = L"";
495+
SQLSMALLINT out_str_len;
496+
497+
// Connecting to ODBC server.
498+
ASSERT_EQ(SQL_SUCCESS,
499+
SQLDriverConnect(this->conn, NULL, &connect_str0[0],
500+
static_cast<SQLSMALLINT>(connect_str0.size()), out_str,
501+
kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT))
502+
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn);
503+
504+
// Allocate a statement using alloc statement
505+
ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement));
506+
507+
// Disconnect from ODBC without closing the statement first
508+
ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn));
509+
}
510+
471511
} // namespace arrow::flight::sql::odbc

0 commit comments

Comments
 (0)