Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ci/scripts/cpp_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ if ! type minio >/dev/null 2>&1; then
fi
case "$(uname)" in
Linux)
exclude_tests+=("arrow-flight-sql-odbc-test")
n_jobs=$(nproc)
;;
Darwin)
Expand Down
22 changes: 13 additions & 9 deletions cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ TYPED_TEST_SUITE(ColumnsOdbcV2Test, TestTypesOdbcV2);

namespace {
// Helper functions

// GH-49702: TODO Disabled on Linux due to BlockingQueue issue
#ifndef __linux__
void CheckSQLColumns(
SQLHSTMT stmt, const std::wstring& expected_table,
const std::wstring& expected_column, const SQLINTEGER& expected_data_type,
Expand Down Expand Up @@ -125,6 +128,7 @@ void CheckRemoteSQLColumns(
expected_octet_char_length, expected_ordinal_position,
expected_is_nullable);
}
#endif // __linux__

void CheckSQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT idx,
const std::string& expected_column_name,
Expand Down Expand Up @@ -416,6 +420,8 @@ TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) {
ValidateFetch(this->stmt, SQL_SUCCESS);
}

// GH-49702: TODO Disabled on Linux due to BlockingQueue issue
#ifndef __linux__
TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) {
// Check table pattern and column pattern returns all columns

Expand Down Expand Up @@ -1210,6 +1216,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) {
// There is no more column
EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt));
}
#endif // __linux__

TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) {
ASSIGN_SQLWCHAR_ARR(table_pattern, L"non-existent-table");
Expand Down Expand Up @@ -2560,10 +2567,6 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) {

ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from 数据 LIMIT 1;");

ASSIGN_SQLWCHAR_ARR_AND_LEN(expected_column_name, L"资料");
SQLSMALLINT expected_column_data_type = SQL_WVARCHAR;
SQLULEN expected_column_size = 0;

ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len));

ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt));
Expand All @@ -2572,13 +2575,14 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) {
buf_char_len, &name_length, &column_data_type,
&column_size, &decimal_digits, &nullable));

EXPECT_EQ(name_length, expected_column_name_len);
std::wstring expected_column_name_wstr = std::wstring(L"资料");
size_t expected_column_name_len = expected_column_name_wstr.length();

std::wstring returned(column_name, column_name + name_length);
std::wstring expected_col_name_str = ConvertToWString(expected_column_name);
EXPECT_EQ(expected_col_name_str, returned);
EXPECT_EQ(expected_column_data_type, column_data_type);
EXPECT_EQ(expected_column_size, column_size);
EXPECT_EQ(expected_column_name_wstr, returned);
EXPECT_EQ(expected_column_name_len, name_length);
EXPECT_EQ(SQL_WVARCHAR, column_data_type);
EXPECT_EQ(0, column_size);
EXPECT_EQ(0, decimal_digits);
EXPECT_EQ(SQL_NULLABLE, nullable);

Expand Down
69 changes: 49 additions & 20 deletions cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ using TestTypes =
::testing::Types<FlightSQLODBCMockTestBase, FlightSQLODBCRemoteTestBase>;
TYPED_TEST_SUITE(ConnectionAttributeTest, TestTypes);

template <typename T>
class ConnectionAttributePreConnectTest : public T {};

using TestTypesHandle = ::testing::Types<FlightSQLOdbcEnvConnHandleMockTestBase,
FlightSQLOdbcEnvConnHandleRemoteTestBase>;
TYPED_TEST_SUITE(ConnectionAttributePreConnectTest, TestTypesHandle);

#ifdef SQL_ATTR_ASYNC_DBC_EVENT
TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) {
ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0));
Expand Down Expand Up @@ -117,31 +124,33 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTraceDMOnly) {
}
#endif // __APPLE__

TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTracefileDMOnly) {
TYPED_TEST(ConnectionAttributePreConnectTest, 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.
// Use placeholder value to avoid the driver manager from producing a trace file.
std::wstring trace_file = L"invalid/file/path";
std::vector<SQLWCHAR> trace_file0(trace_file.begin(), trace_file.end());

#ifdef _WIN32
ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0],
static_cast<SQLINTEGER>(trace_file0.size())));
#ifdef __APPLE__
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00);
#else
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY000);
#endif // __APPLE__
#else // Mac & Linux
ASSERT_EQ(SQL_SUCCESS,
SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0],
static_cast<SQLINTEGER>(trace_file0.size())));
Comment on lines +130 to +141
#endif
}

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
#ifdef __APPLE__
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00);
#else
#ifdef _WIN32
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY024);
#endif // __APPLE__
#else // Mac & Linux
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00);
#endif
}

TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) {
Expand All @@ -166,8 +175,8 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) {
}
#endif

// iODBC does not treat SQL_ATTR_ODBC_CURSORS as DM-only
#ifndef __APPLE__
// Driver Manager behavior tests for Windows only.
#ifdef _WIN32
TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrOdbcCursorsDMOnly) {
// Verify that DM-only attribute is handled by driver manager
SQLULEN cursor_attr;
Expand All @@ -176,7 +185,6 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrOdbcCursorsDMOnly) {
EXPECT_EQ(SQL_CUR_USE_DRIVER, cursor_attr);
}

// iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACE
TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) {
// Verify that DM-only attribute is handled by driver manager
SQLUINTEGER trace;
Expand All @@ -185,7 +193,6 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) {
EXPECT_EQ(SQL_OPT_TRACE_OFF, trace);
}

// iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACEFILE
TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) {
// Verify that DM-only attribute is handled by driver manager
SQLWCHAR out_str[kOdbcBufferSize];
Expand All @@ -199,7 +206,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) {
ODBC::SqlWcharToString(out_str, static_cast<SQLSMALLINT>(out_str_len));
EXPECT_FALSE(out_connection_string.empty());
}
#endif // __APPLE__
#endif // _WIN32

TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) {
SQLWCHAR out_str[kOdbcBufferSize];
Expand All @@ -226,11 +233,17 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTxnIsolationUnsupported
#ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE
TYPED_TEST(ConnectionAttributeTest,
TestSQLGetConnectAttrAsyncDbcFunctionsEnableUnsupported) {
// Verifies that the Windows driver manager returns HY114 for unsupported functionality
SQLUINTEGER enable;
# ifdef _WIN32
// Verifies that the Windows driver manager returns HY114 for unsupported functionality
ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE,
&enable, 0, 0));
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY114);
# else // Mac & Linux
ASSERT_EQ(
SQL_SUCCESS,
SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0));
# endif
}
#endif

Expand Down Expand Up @@ -357,14 +370,24 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrLoginTimeoutValid) {
EXPECT_EQ(42, timeout);
}

#ifdef __linux__
// On Linux, SQL_ATTR_PACKET_SIZE can only be set before connection
// which is why use a different test fixture for Linux.
TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrPacketSizeValid) {
#else // Windows & Mac
TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) {
// The driver always returns 0. PACKET_SIZE value is unused by the driver.

#endif
// Check default value first
SQLUINTEGER size = -1;
#ifdef __linux__
ASSERT_EQ(SQL_ERROR,
SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr));
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState08003);
#else // Windows & Mac
ASSERT_EQ(SQL_SUCCESS,
SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr));
EXPECT_EQ(0, size);
#endif

ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE,
reinterpret_cast<SQLPOINTER>(0), 0));
Expand All @@ -374,12 +397,18 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) {
SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr));
EXPECT_EQ(0, size);

// Attempt to set to non-zero value, driver should return warning and not error
// Attempt to set to non-zero value,
#ifdef __linux__
EXPECT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE,
reinterpret_cast<SQLPOINTER>(2), 0));
#else // Windows & Mac
// driver should return warning and not error
EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE,
reinterpret_cast<SQLPOINTER>(2), 0));

// Verify warning status
VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02);
#endif
}

} // namespace arrow::flight::sql::odbc
14 changes: 10 additions & 4 deletions cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceName) {
}

#ifdef SQL_DRIVER_AWARE_POOLING_SUPPORTED
// GH-49782: TODO Disabled on Linux until SQL_DRIVER_AWARE_POOLING_SUPPORTED is
// implemented in the driver.
# ifndef __linux__
TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) {
// According to Microsoft documentation, ODBC driver does not need to implement
// SQL_DRIVER_AWARE_POOLING_SUPPORTED and the Driver Manager will ignore the
Expand All @@ -153,7 +156,8 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) {

EXPECT_EQ(static_cast<SQLUINTEGER>(SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE), value);
}
#endif
# endif // __linux__
#endif // SQL_DRIVER_AWARE_POOLING_SUPPORTED

// These information types are implemented by the Driver Manager alone.
TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdbc) {
Expand Down Expand Up @@ -331,11 +335,13 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcVer) {

std::wstring result = ConvertToWString(value);

#ifdef __APPLE__
#if defined(__APPLE__)
EXPECT_EQ(std::wstring(L"03.52.0000"), result);
#else
#elif defined(__linux__)
EXPECT_EQ(std::wstring(L"03.52"), result);
#else // WINDOWS
EXPECT_EQ(std::wstring(L"03.80.0000"), result);
#endif // __APPLE__
#endif
}

TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArrayRowCounts) {
Expand Down
23 changes: 14 additions & 9 deletions cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,20 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) {
EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 1, nullptr, nullptr,
nullptr, 0, nullptr));

// Invalid handle
#ifdef __APPLE__
// MacOS ODBC driver manager requires connection handle
EXPECT_EQ(SQL_INVALID_HANDLE,
SQLGetDiagRec(0, this->conn, 1, nullptr, nullptr, nullptr, 0, nullptr));
#else
EXPECT_EQ(SQL_INVALID_HANDLE,
// Linux & Windows driver managers have different expected return values
# ifdef __linux__
SQLRETURN expected_rc = SQL_ERROR;
# else // Windows
SQLRETURN expected_rc = SQL_INVALID_HANDLE;
# endif
EXPECT_EQ(expected_rc,
SQLGetDiagRec(0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr));
#endif // __APPLE__
#endif
}

TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorInputData) {
Expand Down Expand Up @@ -491,13 +496,13 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) {
EXPECT_EQ(0, native_error);

// Function sequence error state from driver manager
#ifdef _WIN32
// Windows Driver Manager returns S1010
EXPECT_EQ(kErrorStateS1010, SqlWcharToString(sql_state));
#else
// unix Driver Manager returns HY010
#ifdef __APPLE__
// MacOS Driver Manager returns HY010
EXPECT_EQ(kErrorStateHY010, SqlWcharToString(sql_state));
#endif // _WIN32
#else // Linux & Windows
// Linux & Windows Driver Managers returns S1010
EXPECT_EQ(kErrorStateS1010, SqlWcharToString(sql_state));
#endif

std::string msg = SqlWcharToString(message);
EXPECT_FALSE(msg.empty());
Expand Down
7 changes: 4 additions & 3 deletions cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ using TestTypesOdbcV2 =
::testing::Types<FlightSQLOdbcV2MockTestBase, FlightSQLOdbcV2RemoteTestBase>;
TYPED_TEST_SUITE(GetFunctionsOdbcV2Test, TestTypesOdbcV2);

// MacOS driver manager iODBC does not support SQLGetFunctions for ODBC 3.x or 2.x driver
#ifndef __APPLE__
// Unix driver managers iODBC and Unix-ODBC do not support SQLGetFunctions
// for ODBC 3.x or 2.x driver
#ifdef _WIN32
TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsAllFunctions) {
// Verify driver manager return values for SQLGetFunctions

Expand Down Expand Up @@ -218,6 +219,6 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsUnsupportedSingleAPI) {
api_exists = -1;
}
}
#endif // __APPLE__
#endif // _WIN32

} // namespace arrow::flight::sql::odbc
4 changes: 4 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) {
TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtEventUnsupported) {
// Driver does not support asynchronous notification
ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR,
# ifdef __linux__
kErrorStateHYC00);
# else // Windows & Mac
kErrorStateHY118);
# endif
}
#endif

Expand Down
Loading
Loading