Skip to content

Commit 9199958

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

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-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
@@ -214,8 +214,45 @@ SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle) {
214214
SQLRETURN SQLFreeStmt(SQLHSTMT handle, SQLUSMALLINT option) {
215215
ARROW_LOG(DEBUG) << "SQLFreeStmt called with handle: " << handle
216216
<< ", option: " << option;
217-
// GH-47706 TODO: Implement SQLFreeStmt
218-
return SQL_INVALID_HANDLE;
217+
218+
switch (option) {
219+
case SQL_CLOSE: {
220+
using ODBC::ODBCStatement;
221+
222+
return ODBCStatement::ExecuteWithDiagnostics(handle, SQL_ERROR, [=]() {
223+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(handle);
224+
225+
// Close cursor with suppressErrors set to true
226+
statement->CloseCursor(true);
227+
228+
return SQL_SUCCESS;
229+
});
230+
}
231+
232+
case SQL_DROP: {
233+
return SQLFreeHandle(SQL_HANDLE_STMT, handle);
234+
}
235+
236+
case SQL_UNBIND: {
237+
// GH-47716 TODO: Add tests for SQLBindCol unbinding
238+
using ODBC::ODBCDescriptor;
239+
using ODBC::ODBCStatement;
240+
return ODBCStatement::ExecuteWithDiagnostics(handle, SQL_ERROR, [=]() {
241+
ODBCStatement* statement = reinterpret_cast<ODBCStatement*>(handle);
242+
ODBCDescriptor* ard = statement->GetARD();
243+
// Unbind columns
244+
ard->SetHeaderField(SQL_DESC_COUNT, (void*)0, 0);
245+
return SQL_SUCCESS;
246+
});
247+
}
248+
249+
// SQLBindParameter is not supported
250+
case SQL_RESET_PARAMS: {
251+
return SQL_SUCCESS;
252+
}
253+
}
254+
255+
return SQL_ERROR;
219256
}
220257

221258
inline bool IsValidStringFieldArgs(SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length,

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,46 @@ TEST(SQLSetEnvAttr, TestSQLSetEnvAttrNullValuePointer) {
220220
ASSERT_EQ(SQL_SUCCESS, SQLFreeEnv(env));
221221
}
222222

223+
TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) {
224+
SQLHSTMT statement;
225+
226+
// Allocate a statement using alloc statement
227+
ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement));
228+
229+
SQLWCHAR sql_buffer[kOdbcBufferSize] = L"SELECT 1";
230+
ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(statement, sql_buffer, SQL_NTS));
231+
232+
// Close statement handle
233+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_CLOSE));
234+
235+
// Free statement handle
236+
ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_DROP));
237+
}
238+
239+
TYPED_TEST(ConnectionHandleTest, TestCloseConnectionWithOpenStatement) {
240+
SQLHSTMT statement;
241+
242+
// Connect string
243+
std::string connect_str = this->GetConnectionString();
244+
ASSERT_OK_AND_ASSIGN(std::wstring wconnect_str,
245+
arrow::util::UTF8ToWideString(connect_str));
246+
std::vector<SQLWCHAR> connect_str0(wconnect_str.begin(), wconnect_str.end());
247+
248+
SQLWCHAR out_str[kOdbcBufferSize] = L"";
249+
SQLSMALLINT out_str_len;
250+
251+
// Connecting to ODBC server.
252+
ASSERT_EQ(SQL_SUCCESS,
253+
SQLDriverConnect(this->conn, NULL, &connect_str0[0],
254+
static_cast<SQLSMALLINT>(connect_str0.size()), out_str,
255+
kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT))
256+
<< GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn);
257+
258+
// Allocate a statement using alloc statement
259+
ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement));
260+
261+
// Disconnect from ODBC without closing the statement first
262+
ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn));
263+
}
264+
223265
} // namespace arrow::flight::sql::odbc

0 commit comments

Comments
 (0)