From f778317285c19f5b2c9316eb567fc95c93d6e273 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 7 Oct 2025 16:06:35 -0700 Subject: [PATCH 1/5] Extract Implementation for SQLGetConnectAttr and SQLSetConnectAttr --- cpp/src/arrow/flight/sql/odbc/odbc_api.cc | 24 ++++++++++--- .../sql/odbc/odbc_impl/odbc_connection.cc | 36 +++++++++---------- .../sql/odbc/odbc_impl/odbc_connection.h | 5 +-- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc index bce7c10e82b..df0ecf05713 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc @@ -271,8 +271,16 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC conn, SQLINTEGER attribute, SQLPOINTER value << ", attribute: " << attribute << ", value_ptr: " << value_ptr << ", buffer_length: " << buffer_length << ", string_length_ptr: " << static_cast(string_length_ptr); - // GH-47708 TODO: Implement SQLGetConnectAttr - return SQL_INVALID_HANDLE; + + using arrow::flight::sql::odbc::Connection; + using ODBC::ODBCConnection; + + return ODBCConnection::ExecuteWithDiagnostics(conn, SQL_ERROR, [=]() { + const bool is_unicode = true; + ODBCConnection* connection = reinterpret_cast(conn); + return connection->GetConnectAttr(attribute, value_ptr, buffer_length, + string_length_ptr, is_unicode); + }); } SQLRETURN SQLSetConnectAttr(SQLHDBC conn, SQLINTEGER attr, SQLPOINTER value_ptr, @@ -280,8 +288,16 @@ SQLRETURN SQLSetConnectAttr(SQLHDBC conn, SQLINTEGER attr, SQLPOINTER value_ptr, ARROW_LOG(DEBUG) << "SQLSetConnectAttrW called with conn: " << conn << ", attr: " << attr << ", value_ptr: " << value_ptr << ", value_len: " << value_len; - // GH-47708 TODO: Implement SQLSetConnectAttr - return SQL_INVALID_HANDLE; + + using arrow::flight::sql::odbc::Connection; + using ODBC::ODBCConnection; + + return ODBCConnection::ExecuteWithDiagnostics(conn, SQL_ERROR, [=]() { + const bool is_unicode = true; + ODBCConnection* connection = reinterpret_cast(conn); + connection->SetConnectAttr(attr, value_ptr, value_len, is_unicode); + return SQL_SUCCESS; + }); } SQLRETURN SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle, diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc index c0a55840d56..186172d4dcf 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc @@ -578,58 +578,58 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, } } -void ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, - SQLINTEGER buffer_length, SQLINTEGER* output_length, - bool is_unicode) { +SQLRETURN ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, + SQLINTEGER buffer_length, + SQLINTEGER* output_length, bool is_unicode) { boost::optional spi_attribute; switch (attribute) { // Internal connection attributes -#ifdef SQL_ATR_ASYNC_DBC_EVENT +#ifdef SQL_ATTR_ASYNC_DBC_EVENT case SQL_ATTR_ASYNC_DBC_EVENT: GetAttribute(static_cast(NULL), value, buffer_length, output_length); - return; + return SQL_SUCCESS; #endif #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE: GetAttribute(static_cast(SQL_ASYNC_DBC_ENABLE_OFF), value, buffer_length, output_length); - return; + return SQL_SUCCESS; #endif -#ifdef SQL_ATTR_ASYNC_PCALLBACK +#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK case SQL_ATTR_ASYNC_DBC_PCALLBACK: GetAttribute(static_cast(NULL), value, buffer_length, output_length); - return; + return SQL_SUCCESS; #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT case SQL_ATTR_ASYNC_DBC_PCONTEXT: GetAttribute(static_cast(NULL), value, buffer_length, output_length); - return; + return SQL_SUCCESS; #endif case SQL_ATTR_ASYNC_ENABLE: GetAttribute(static_cast(SQL_ASYNC_ENABLE_OFF), value, buffer_length, output_length); - return; + return SQL_SUCCESS; case SQL_ATTR_AUTO_IPD: GetAttribute(static_cast(SQL_FALSE), value, buffer_length, output_length); - return; + return SQL_SUCCESS; case SQL_ATTR_AUTOCOMMIT: GetAttribute(static_cast(SQL_AUTOCOMMIT_ON), value, buffer_length, output_length); - return; + return SQL_SUCCESS; #ifdef SQL_ATTR_DBC_INFO_TOKEN case SQL_ATTR_DBC_INFO_TOKEN: throw DriverException("Cannot read set-only attribute", "HY092"); #endif case SQL_ATTR_ENLIST_IN_DTC: GetAttribute(static_cast(NULL), value, buffer_length, output_length); - return; + return SQL_SUCCESS; case SQL_ATTR_ODBC_CURSORS: // DM-only. throw DriverException("Invalid attribute", "HY092"); case SQL_ATTR_QUIET_MODE: GetAttribute(static_cast(NULL), value, buffer_length, output_length); - return; + return SQL_SUCCESS; case SQL_ATTR_TRACE: // DM-only throw DriverException("Invalid attribute", "HY092"); case SQL_ATTR_TRACEFILE: @@ -639,7 +639,7 @@ void ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, case SQL_ATTR_TRANSLATE_OPTION: throw DriverException("Optional feature not supported.", "HYC00"); case SQL_ATTR_TXN_ISOLATION: - throw DriverException("Optional feature not supported.", "HCY00"); + throw DriverException("Optional feature not supported.", "HYC00"); case SQL_ATTR_CURRENT_CATALOG: { const auto& catalog = spi_connection_->GetAttribute(Connection::CURRENT_CATALOG); @@ -647,9 +647,8 @@ void ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, throw DriverException("Optional feature not supported.", "HYC00"); } const std::string& info_value = boost::get(*catalog); - GetStringAttribute(is_unicode, info_value, true, value, buffer_length, - output_length, GetDiagnostics()); - return; + return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, + output_length, GetDiagnostics()); } // These all are uint32_t attributes. @@ -678,6 +677,7 @@ void ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, GetAttribute(static_cast(boost::get(*spi_attribute)), value, buffer_length, output_length); + return SQL_SUCCESS; } void ODBCConnection::Disconnect() { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h index 8157c2f5f94..46aac616f21 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h @@ -56,8 +56,9 @@ class ODBCConnection : public ODBCHandle { SQLSMALLINT* output_length, bool is_unicode); void SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length, bool isUnicode); - void GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, - SQLINTEGER* output_length, bool is_unicode); + SQLRETURN GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, + SQLINTEGER buffer_length, SQLINTEGER* output_length, + bool is_unicode); ~ODBCConnection() = default; From 2faa819be66e10508f88510e8c69891d08aab9eb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 7 Oct 2025 16:07:25 -0700 Subject: [PATCH 2/5] Add tests for connection attribute --- .../sql/odbc/tests/connection_attr_test.cc | 565 ++++++++++++++++++ 1 file changed, 565 insertions(+) create mode 100644 cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc new file mode 100644 index 00000000000..06171fafd7b --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc @@ -0,0 +1,565 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +#include "arrow/flight/sql/odbc/tests/odbc_test_suite.h" + +#ifdef _WIN32 +# include +#endif + +#include +#include +#include + +#include "gtest/gtest.h" + +namespace arrow::flight::sql::odbc { + +#ifdef SQL_ATTR_ASYNC_DBC_EVENT +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + // Driver Manager on Windows returns error code HY118 + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY118); + + this->Disconnect(); +} +#endif + +#ifdef SQL_ATTR_ASYNC_ENABLE +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncEnableUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} +#endif + +#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} +#endif + +#ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} +#endif + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAutoIpdReadOnly) { + this->Connect(); + + // Verify read-only attribute cannot be set + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrConnectionDeadReadOnly) { + this->Connect(); + + // Verify read-only attribute cannot be set + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + + this->Disconnect(); +} + +#ifdef SQL_ATTR_DBC_INFO_TOKEN +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} +#endif + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrEnlistInDtcUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrOdbcCursorsDMOnly) { + this->AllocEnvConnHandles(); + + // Verify DM-only attribute is settable via Driver Manager + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, + reinterpret_cast(SQL_CUR_USE_DRIVER), 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + + std::string connect_str = this->GetConnectionString(); + this->ConnectWithString(connect_str); + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrQuietModeReadOnly) { + this->Connect(); + + // Verify read-only attribute cannot be set + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTraceDMOnly) { + this->Connect(); + + // Verify DM-only attribute is settable via Driver Manager + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRACE, + reinterpret_cast(SQL_OPT_TRACE_OFF), 0); + EXPECT_EQ(SQL_SUCCESS, ret); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTracefileDMOnly) { + this->Connect(); + + // Verify DM-only attribute is handled by Driver Manager + + // Use placeholder value as we want the call to fail, or else + // the driver manager will produce a trace file. + std::wstring trace_file = L"invalid/file/path"; + std::vector trace_file0(trace_file.begin(), trace_file.end()); + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + static_cast(trace_file0.size())); + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY000); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTranslateLabDMOnly) { + this->Connect(); + + // Verify DM-only attribute is handled by Driver Manager + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0); + EXPECT_EQ(SQL_ERROR, ret); + // Checks for invalid argument return error + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY024); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTranslateOptionUnsupported) { + this->Connect(); + + SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTxnIsolationUnsupported) { + this->Connect(); + + SQLRETURN ret = + SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, + reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0); + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +#ifdef SQL_ATTR_DBC_INFO_TOKEN +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { + this->Connect(); + + // Verify that set-only attribute cannot be read + SQLPOINTER ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + + this->Disconnect(); +} +#endif + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrOdbcCursorsDMOnly) { + this->Connect(); + + // Verify that DM-only attribute is handled by driver manager + SQLULEN cursor_attr; + SQLRETURN ret = + SQLGetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, &cursor_attr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_CUR_USE_DRIVER, cursor_attr); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTraceDMOnly) { + this->Connect(); + + // Verify that DM-only attribute is handled by driver manager + SQLUINTEGER trace; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRACE, &trace, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_OPT_TRACE_OFF, trace); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTraceFileDMOnly) { + this->Connect(); + + // Verify that DM-only attribute is handled by driver manager + SQLWCHAR out_str[ODBC_BUFFER_SIZE]; + SQLINTEGER out_str_len; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, + ODBC_BUFFER_SIZE, &out_str_len); + + EXPECT_EQ(SQL_SUCCESS, ret); + // Length is returned in bytes for SQLGetConnectAttr, + // we want the number of characters + out_str_len /= arrow::flight::sql::odbc::GetSqlWCharSize(); + std::string out_connection_string = + ODBC::SqlWcharToString(out_str, static_cast(out_str_len)); + EXPECT_TRUE(!out_connection_string.empty()); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTranslateLibUnsupported) { + this->Connect(); + + SQLWCHAR out_str[ODBC_BUFFER_SIZE]; + SQLINTEGER out_str_len; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, + ODBC_BUFFER_SIZE, &out_str_len); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTranslateOptionUnsupported) { + this->Connect(); + + SQLINTEGER option; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTxnIsolationUnsupported) { + this->Connect(); + + SQLINTEGER isolation; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + + this->Disconnect(); +} + +#ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE +TYPED_TEST(FlightSQLODBCTestBase, + TestSQLGetConnectAttrAsyncDbcFunctionsEnableUnsupported) { + this->Connect(); + + // Verifies that the Windows driver manager returns HY114 for unsupported functionality + SQLUINTEGER enable; + SQLRETURN ret = + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0); + + EXPECT_EQ(SQL_ERROR, ret); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY114); + + this->Disconnect(); +} +#endif + +// Tests for supported attributes + +#ifdef SQL_ATTR_ASYNC_DBC_EVENT +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcEventDefault) { + this->Connect(); + + SQLPOINTER ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(reinterpret_cast(NULL), ptr); + + this->Disconnect(); +} +#endif + +#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcPcallbackDefault) { + this->Connect(); + + SQLPOINTER ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(reinterpret_cast(NULL), ptr); + + this->Disconnect(); +} +#endif + +#ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcPcontextDefault) { + this->Connect(); + + SQLPOINTER ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(reinterpret_cast(NULL), ptr); + + this->Disconnect(); +} +#endif + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncEnableDefault) { + this->Connect(); + + SQLULEN enable; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_ASYNC_ENABLE_OFF, enable); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAutoIpdDefault) { + this->Connect(); + + SQLUINTEGER ipd; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, &ipd, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(static_cast(SQL_FALSE), ipd); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAutocommitDefault) { + this->Connect(); + + SQLUINTEGER auto_commit; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_AUTOCOMMIT_ON, auto_commit); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrEnlistInDtcDefault) { + this->Connect(); + + SQLPOINTER ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(reinterpret_cast(NULL), ptr); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrQuietModeDefault) { + this->Connect(); + + HWND ptr = NULL; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, ptr, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(reinterpret_cast(NULL), ptr); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAccessModeValid) { + this->Connect(); + + // The driver always returns SQL_MODE_READ_WRITE + + // Check default value first + SQLUINTEGER mode = -1; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_MODE_READ_WRITE, mode); + + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, + reinterpret_cast(SQL_MODE_READ_WRITE), 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + + mode = -1; + + ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(SQL_MODE_READ_WRITE, mode); + + // Attempt to set to SQL_MODE_READ_ONLY, driver should return warning and not error + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, + reinterpret_cast(SQL_MODE_READ_ONLY), 0); + + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, ret); + + // Verify warning status + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrConnectionTimeoutValid) { + this->Connect(); + + // Check default value first + SQLUINTEGER timeout = -1; + SQLRETURN ret = + SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(0, timeout); + + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + reinterpret_cast(42), 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + + timeout = -1; + + ret = SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(42, timeout); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrLoginTimeoutValid) { + this->Connect(); + + // Check default value first + SQLUINTEGER timeout = -1; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(0, timeout); + + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, + reinterpret_cast(42), 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + + timeout = -1; + + ret = SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(42, timeout); + + this->Disconnect(); +} + +TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrPacketSizeValid) { + this->Connect(); + + // The driver always returns 0. PACKET_SIZE value is unused by the driver. + + // Check default value first + SQLUINTEGER size = -1; + SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(0, size); + + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(0), 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + + size = -1; + + ret = SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0); + + EXPECT_EQ(SQL_SUCCESS, ret); + EXPECT_EQ(0, size); + + // Attempt to set to non-zero value, driver should return warning and not error + ret = SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(2), 0); + + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, ret); + + // Verify warning status + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); + + this->Disconnect(); +} + +} // namespace arrow::flight::sql::odbc From 6ac8581e7606710739020a1be0e597442992b010 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 21 Oct 2025 15:15:28 -0700 Subject: [PATCH 3/5] Work on code review comments Co-authored-by: justing-bq Co-authored-by: alinalibq --- .../sql/odbc/tests/connection_attr_test.cc | 452 +++++------------- 1 file changed, 126 insertions(+), 326 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc index 06171fafd7b..3197d86b969 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc @@ -16,550 +16,350 @@ // under the License. #include "arrow/flight/sql/odbc/tests/odbc_test_suite.h" -#ifdef _WIN32 -# include -#endif +#include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include #include #include -#include "gtest/gtest.h" +#include namespace arrow::flight::sql::odbc { -#ifdef SQL_ATTR_ASYNC_DBC_EVENT -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { - this->Connect(); +template +class ConnectionAttributeTest : public T { + public: + using List = std::list; +}; - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0); +using TestTypes = + ::testing::Types; +TYPED_TEST_SUITE(ConnectionAttributeTest, TestTypes); - EXPECT_EQ(SQL_ERROR, ret); +#ifdef SQL_ATTR_ASYNC_DBC_EVENT +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); // Driver Manager on Windows returns error code HY118 VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY118); - - this->Disconnect(); } #endif #ifdef SQL_ATTR_ASYNC_ENABLE -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncEnableUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncEnableUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #endif -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAutoIpdReadOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAutoIpdReadOnly) { // Verify read-only attribute cannot be set - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrConnectionDeadReadOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionDeadReadOnly) { // Verify read-only attribute cannot be set - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); - - this->Disconnect(); } #ifdef SQL_ATTR_DBC_INFO_TOKEN -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #endif -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrEnlistInDtcUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrOdbcCursorsDMOnly) { +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { this->AllocEnvConnHandles(); // Verify DM-only attribute is settable via Driver Manager - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, - reinterpret_cast(SQL_CUR_USE_DRIVER), 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLSetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, + reinterpret_cast(SQL_CUR_USE_DRIVER), 0)); std::string connect_str = this->GetConnectionString(); this->ConnectWithString(connect_str); - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrQuietModeReadOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { // Verify read-only attribute cannot be set - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTraceDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTraceDMOnly) { // Verify DM-only attribute is settable via Driver Manager - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRACE, - reinterpret_cast(SQL_OPT_TRACE_OFF), 0); - EXPECT_EQ(SQL_SUCCESS, ret); - - this->Disconnect(); + ASSERT_EQ(SQL_SUCCESS, + SQLSetConnectAttr(this->conn, SQL_ATTR_TRACE, + reinterpret_cast(SQL_OPT_TRACE_OFF), 0)); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTracefileDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTracefileDMOnly) { // Verify DM-only attribute is handled by Driver Manager // Use placeholder value as we want the call to fail, or else // the driver manager will produce a trace file. std::wstring trace_file = L"invalid/file/path"; std::vector trace_file0(trace_file.begin(), trace_file.end()); - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], - static_cast(trace_file0.size())); - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + static_cast(trace_file0.size()))); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY000); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTranslateLabDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateLabDMOnly) { // Verify DM-only attribute is handled by Driver Manager - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0); - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); // Checks for invalid argument return error VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY024); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTranslateOptionUnsupported) { - this->Connect(); - - SQLRETURN ret = SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) { + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrTxnIsolationUnsupported) { - this->Connect(); - - SQLRETURN ret = - SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, - reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0); - EXPECT_EQ(SQL_ERROR, ret); +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTxnIsolationUnsupported) { + ASSERT_EQ(SQL_ERROR, + SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, + reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #ifdef SQL_ATTR_DBC_INFO_TOKEN -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { // Verify that set-only attribute cannot be read SQLPOINTER ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); - - this->Disconnect(); } #endif -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrOdbcCursorsDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrOdbcCursorsDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLULEN cursor_attr; - SQLRETURN ret = - SQLGetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, &cursor_attr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, &cursor_attr, 0, 0)); EXPECT_EQ(SQL_CUR_USE_DRIVER, cursor_attr); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTraceDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLUINTEGER trace; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRACE, &trace, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_TRACE, &trace, 0, 0)); EXPECT_EQ(SQL_OPT_TRACE_OFF, trace); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTraceFileDMOnly) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLWCHAR out_str[ODBC_BUFFER_SIZE]; SQLINTEGER out_str_len; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, - ODBC_BUFFER_SIZE, &out_str_len); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, + ODBC_BUFFER_SIZE, &out_str_len)); // Length is returned in bytes for SQLGetConnectAttr, // we want the number of characters out_str_len /= arrow::flight::sql::odbc::GetSqlWCharSize(); std::string out_connection_string = ODBC::SqlWcharToString(out_str, static_cast(out_str_len)); EXPECT_TRUE(!out_connection_string.empty()); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTranslateLibUnsupported) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) { SQLWCHAR out_str[ODBC_BUFFER_SIZE]; SQLINTEGER out_str_len; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, - ODBC_BUFFER_SIZE, &out_str_len); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, + ODBC_BUFFER_SIZE, &out_str_len)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTranslateOptionUnsupported) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateOptionUnsupported) { SQLINTEGER option; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrTxnIsolationUnsupported) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTxnIsolationUnsupported) { SQLINTEGER isolation; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); - - this->Disconnect(); } #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE -TYPED_TEST(FlightSQLODBCTestBase, +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcFunctionsEnableUnsupported) { - this->Connect(); - // Verifies that the Windows driver manager returns HY114 for unsupported functionality SQLUINTEGER enable; - SQLRETURN ret = - SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0); - - EXPECT_EQ(SQL_ERROR, ret); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, + &enable, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY114); - - this->Disconnect(); } #endif // Tests for supported attributes #ifdef SQL_ATTR_ASYNC_DBC_EVENT -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcEventDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcEventDefault) { SQLPOINTER ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, 0)); EXPECT_EQ(reinterpret_cast(NULL), ptr); - - this->Disconnect(); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcPcallbackDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcallbackDefault) { SQLPOINTER ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, 0)); EXPECT_EQ(reinterpret_cast(NULL), ptr); - - this->Disconnect(); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncDbcPcontextDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcontextDefault) { SQLPOINTER ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, 0)); EXPECT_EQ(reinterpret_cast(NULL), ptr); - - this->Disconnect(); } #endif -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAsyncEnableDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncEnableDefault) { SQLULEN enable; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, 0)); EXPECT_EQ(SQL_ASYNC_ENABLE_OFF, enable); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAutoIpdDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutoIpdDefault) { SQLUINTEGER ipd; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, &ipd, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, &ipd, 0, 0)); EXPECT_EQ(static_cast(SQL_FALSE), ipd); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrAutocommitDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutocommitDefault) { SQLUINTEGER auto_commit; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, 0)); EXPECT_EQ(SQL_AUTOCOMMIT_ON, auto_commit); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrEnlistInDtcDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrEnlistInDtcDefault) { SQLPOINTER ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, 0)); EXPECT_EQ(reinterpret_cast(NULL), ptr); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLGetConnectAttrQuietModeDefault) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrQuietModeDefault) { HWND ptr = NULL; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, ptr, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, ptr, 0, 0)); EXPECT_EQ(reinterpret_cast(NULL), ptr); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrAccessModeValid) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAccessModeValid) { // The driver always returns SQL_MODE_READ_WRITE // Check default value first SQLUINTEGER mode = -1; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, - reinterpret_cast(SQL_MODE_READ_WRITE), 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, + reinterpret_cast(SQL_MODE_READ_WRITE), 0)); mode = -1; - - ret = SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, 0)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); // Attempt to set to SQL_MODE_READ_ONLY, driver should return warning and not error - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, - reinterpret_cast(SQL_MODE_READ_ONLY), 0); - - EXPECT_EQ(SQL_SUCCESS_WITH_INFO, ret); + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, + reinterpret_cast(SQL_MODE_READ_ONLY), 0)); // Verify warning status VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrConnectionTimeoutValid) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; - SQLRETURN ret = - SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0)); EXPECT_EQ(0, timeout); - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, - reinterpret_cast(42), 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + reinterpret_cast(42), 0)); timeout = -1; - - ret = SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, 0)); EXPECT_EQ(42, timeout); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrLoginTimeoutValid) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrLoginTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0)); EXPECT_EQ(0, timeout); - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, - reinterpret_cast(42), 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, + reinterpret_cast(42), 0)); timeout = -1; - - ret = SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, 0)); EXPECT_EQ(42, timeout); - - this->Disconnect(); } -TYPED_TEST(FlightSQLODBCTestBase, TestSQLSetConnectAttrPacketSizeValid) { - this->Connect(); - +TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) { // The driver always returns 0. PACKET_SIZE value is unused by the driver. // Check default value first SQLUINTEGER size = -1; - SQLRETURN ret = SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0)); EXPECT_EQ(0, size); - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, - reinterpret_cast(0), 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(0), 0)); size = -1; - - ret = SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0); - - EXPECT_EQ(SQL_SUCCESS, ret); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, 0)); EXPECT_EQ(0, size); // Attempt to set to non-zero value, driver should return warning and not error - ret = SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, - reinterpret_cast(2), 0); - - EXPECT_EQ(SQL_SUCCESS_WITH_INFO, ret); + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(2), 0)); // Verify warning status VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); - - this->Disconnect(); } } // namespace arrow::flight::sql::odbc From 3f1cefbdbf59076948d66823032c16d0c5693f05 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 22 Oct 2025 16:01:32 -0700 Subject: [PATCH 4/5] Remove `using List` Rebase from `master` --- .../flight/sql/odbc/tests/CMakeLists.txt | 1 + .../sql/odbc/tests/connection_attr_test.cc | 53 +++++++++---------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt index 4bc240637e7..f82f5416957 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt @@ -34,6 +34,7 @@ add_arrow_test(flight_sql_odbc_test SOURCES odbc_test_suite.cc odbc_test_suite.h + connection_attr_test.cc connection_test.cc # Enable Protobuf cleanup after test execution # GH-46889: move protobuf_test_util to a more common location diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc index 3197d86b969..b7019cdda42 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc @@ -27,10 +27,7 @@ namespace arrow::flight::sql::odbc { template -class ConnectionAttributeTest : public T { - public: - using List = std::list; -}; +class ConnectionAttributeTest : public T {}; using TestTypes = ::testing::Types; @@ -40,53 +37,53 @@ TYPED_TEST_SUITE(ConnectionAttributeTest, TestTypes); TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); // Driver Manager on Windows returns error code HY118 - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY118); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY118); } #endif #ifdef SQL_ATTR_ASYNC_ENABLE TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncEnableUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAutoIpdReadOnly) { // Verify read-only attribute cannot be set ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionDeadReadOnly) { // Verify read-only attribute cannot be set ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #ifdef SQL_ATTR_DBC_INFO_TOKEN TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { @@ -104,7 +101,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { // Verify read-only attribute cannot be set ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTraceDMOnly) { @@ -123,26 +120,26 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTracefileDMOnly) { std::vector trace_file0(trace_file.begin(), trace_file.end()); ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], static_cast(trace_file0.size()))); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY000); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateLabDMOnly) { // Verify DM-only attribute is handled by Driver Manager ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); // Checks for invalid argument return error - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY024); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY024); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTxnIsolationUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_DBC_INFO_TOKEN @@ -150,7 +147,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { // Verify that set-only attribute cannot be read SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY092); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #endif @@ -171,10 +168,10 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { // Verify that DM-only attribute is handled by driver manager - SQLWCHAR out_str[ODBC_BUFFER_SIZE]; + SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, - ODBC_BUFFER_SIZE, &out_str_len)); + kOdbcBufferSize, &out_str_len)); // Length is returned in bytes for SQLGetConnectAttr, // we want the number of characters out_str_len /= arrow::flight::sql::odbc::GetSqlWCharSize(); @@ -184,25 +181,25 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) { - SQLWCHAR out_str[ODBC_BUFFER_SIZE]; + SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, - ODBC_BUFFER_SIZE, &out_str_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + kOdbcBufferSize, &out_str_len)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateOptionUnsupported) { SQLINTEGER option; ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTxnIsolationUnsupported) { SQLINTEGER isolation; ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE @@ -212,7 +209,7 @@ TYPED_TEST(ConnectionAttributeTest, SQLUINTEGER enable; ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_HY114); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY114); } #endif @@ -302,7 +299,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAccessModeValid) { reinterpret_cast(SQL_MODE_READ_ONLY), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionTimeoutValid) { @@ -359,7 +356,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) { reinterpret_cast(2), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, error_state_01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); } } // namespace arrow::flight::sql::odbc From 2332bdae2b2fd097610d2ee808f2504e60159a99 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 23 Oct 2025 11:58:44 -0700 Subject: [PATCH 5/5] Use `EXPECT_FALSE` --- cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc index b7019cdda42..ed1db2560ca 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc @@ -177,7 +177,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { out_str_len /= arrow::flight::sql::odbc::GetSqlWCharSize(); std::string out_connection_string = ODBC::SqlWcharToString(out_str, static_cast(out_str_len)); - EXPECT_TRUE(!out_connection_string.empty()); + EXPECT_FALSE(out_connection_string.empty()); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) {