diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc index 90e5db7201a2..18da16ca1518 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc @@ -31,7 +31,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" #include "arrow/util/logging.h" -#if defined _WIN32 || defined _WIN64 +#if defined _WIN32 // For displaying DSN Window # include "arrow/flight/sql/odbc/odbc_impl/system_dsn.h" #endif @@ -810,7 +810,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle, // GH-46448 TODO: Implement SQL_DRIVER_COMPLETE_REQUIRED in SQLDriverConnect according // to the spec -#if defined _WIN32 || defined _WIN64 +#if defined _WIN32 // Load the DSN window according to driver_completion if (driver_completion == SQL_DRIVER_PROMPT) { // Load DSN window before first attempt to connect diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h b/cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h index 53273a5b6d37..4fea8569acb5 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h @@ -27,79 +27,95 @@ // // Define internal ODBC API function headers. namespace arrow::flight::sql::odbc { -SQLRETURN SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, SQLHANDLE* result); -SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle); -SQLRETURN SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT option); -SQLRETURN SQLGetDiagField(SQLSMALLINT handle_type, SQLHANDLE handle, - SQLSMALLINT rec_number, SQLSMALLINT diag_identifier, - SQLPOINTER diag_info_ptr, SQLSMALLINT buffer_length, - SQLSMALLINT* string_length_ptr); -SQLRETURN SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT rec_number, - SQLWCHAR* sql_state, SQLINTEGER* native_error_ptr, - SQLWCHAR* message_text, SQLSMALLINT buffer_length, - SQLSMALLINT* text_length_ptr); -SQLRETURN SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr, - SQLINTEGER buffer_len, SQLINTEGER* str_len_ptr); -SQLRETURN SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr, - SQLINTEGER str_len); -SQLRETURN SQLGetConnectAttr(SQLHDBC conn, SQLINTEGER attribute, SQLPOINTER value_ptr, - SQLINTEGER buffer_length, SQLINTEGER* string_length_ptr); -SQLRETURN SQLSetConnectAttr(SQLHDBC conn, SQLINTEGER attr, SQLPOINTER value, - SQLINTEGER value_len); -SQLRETURN SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle, - SQLWCHAR* in_connection_string, - SQLSMALLINT in_connection_string_len, - SQLWCHAR* out_connection_string, - SQLSMALLINT out_connection_string_buffer_len, - SQLSMALLINT* out_connection_string_len, - SQLUSMALLINT driver_completion); -SQLRETURN SQLConnect(SQLHDBC conn, SQLWCHAR* dsn_name, SQLSMALLINT dsn_name_len, - SQLWCHAR* user_name, SQLSMALLINT user_name_len, SQLWCHAR* password, - SQLSMALLINT password_len); -SQLRETURN SQLDisconnect(SQLHDBC conn); -SQLRETURN SQLGetInfo(SQLHDBC conn, SQLUSMALLINT info_type, SQLPOINTER info_value_ptr, - SQLSMALLINT buf_len, SQLSMALLINT* length); -SQLRETURN SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, SQLPOINTER value_ptr, - SQLINTEGER buffer_length, SQLINTEGER* string_length_ptr); -SQLRETURN SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, SQLPOINTER value_ptr, - SQLINTEGER stringLength); -SQLRETURN SQLExecDirect(SQLHSTMT stmt, SQLWCHAR* queryText, SQLINTEGER text_length); -SQLRETURN SQLPrepare(SQLHSTMT stmt, SQLWCHAR* queryText, SQLINTEGER text_length); -SQLRETURN SQLExecute(SQLHSTMT stmt); -SQLRETURN SQLFetch(SQLHSTMT stmt); -SQLRETURN SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT fetch_orientation, - SQLLEN fetch_offset, SQLULEN* row_count_ptr, - SQLUSMALLINT* row_status_array); -SQLRETURN SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT fetch_orientation, - SQLLEN fetch_offset); -SQLRETURN SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT record_number, SQLSMALLINT c_type, - SQLPOINTER data_ptr, SQLLEN buffer_length, SQLLEN* indicator_ptr); -SQLRETURN SQLCloseCursor(SQLHSTMT stmt); -SQLRETURN SQLGetData(SQLHSTMT stmt, SQLUSMALLINT record_number, SQLSMALLINT c_type, - SQLPOINTER data_ptr, SQLLEN buffer_length, SQLLEN* indicator_ptr); -SQLRETURN SQLMoreResults(SQLHSTMT stmt); -SQLRETURN SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT* column_count_ptr); -SQLRETURN SQLRowCount(SQLHSTMT stmt, SQLLEN* row_count_ptr); -SQLRETURN SQLTables(SQLHSTMT stmt, SQLWCHAR* catalog_name, - SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name, - SQLSMALLINT schema_name_length, SQLWCHAR* table_name, - SQLSMALLINT table_name_length, SQLWCHAR* table_type, - SQLSMALLINT table_type_length); -SQLRETURN SQLColumns(SQLHSTMT stmt, SQLWCHAR* catalog_name, - SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name, - SQLSMALLINT schema_name_length, SQLWCHAR* table_name, - SQLSMALLINT table_name_length, SQLWCHAR* column_name, - SQLSMALLINT column_name_length); -SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, - SQLUSMALLINT field_identifier, - SQLPOINTER character_attribute_ptr, SQLSMALLINT buffer_length, - SQLSMALLINT* output_length, SQLLEN* numeric_attribute_ptr); -SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT dataType); -SQLRETURN SQLNativeSql(SQLHDBC conn, SQLWCHAR* in_statement_text, - SQLINTEGER in_statement_text_length, SQLWCHAR* out_statement_text, - SQLINTEGER buffer_length, SQLINTEGER* out_statement_text_length); -SQLRETURN SQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT column_number, SQLWCHAR* column_name, - SQLSMALLINT buffer_length, SQLSMALLINT* name_length_ptr, - SQLSMALLINT* data_type_ptr, SQLULEN* column_size_ptr, - SQLSMALLINT* decimal_digits_ptr, SQLSMALLINT* nullable_ptr); +[[nodiscard]] SQLRETURN SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, + SQLHANDLE* result); +[[nodiscard]] SQLRETURN SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle); +[[nodiscard]] SQLRETURN SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT option); +[[nodiscard]] SQLRETURN SQLGetDiagField(SQLSMALLINT handle_type, SQLHANDLE handle, + SQLSMALLINT rec_number, + SQLSMALLINT diag_identifier, + SQLPOINTER diag_info_ptr, + SQLSMALLINT buffer_length, + SQLSMALLINT* string_length_ptr); +[[nodiscard]] SQLRETURN SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle, + SQLSMALLINT rec_number, SQLWCHAR* sql_state, + SQLINTEGER* native_error_ptr, + SQLWCHAR* message_text, SQLSMALLINT buffer_length, + SQLSMALLINT* text_length_ptr); +[[nodiscard]] SQLRETURN SQLGetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr, + SQLINTEGER buffer_len, SQLINTEGER* str_len_ptr); +[[nodiscard]] SQLRETURN SQLSetEnvAttr(SQLHENV env, SQLINTEGER attr, SQLPOINTER value_ptr, + SQLINTEGER str_len); +[[nodiscard]] SQLRETURN SQLGetConnectAttr(SQLHDBC conn, SQLINTEGER attribute, + SQLPOINTER value_ptr, SQLINTEGER buffer_length, + SQLINTEGER* string_length_ptr); +[[nodiscard]] SQLRETURN SQLSetConnectAttr(SQLHDBC conn, SQLINTEGER attr, SQLPOINTER value, + SQLINTEGER value_len); +[[nodiscard]] SQLRETURN SQLDriverConnect(SQLHDBC conn, SQLHWND window_handle, + SQLWCHAR* in_connection_string, + SQLSMALLINT in_connection_string_len, + SQLWCHAR* out_connection_string, + SQLSMALLINT out_connection_string_buffer_len, + SQLSMALLINT* out_connection_string_len, + SQLUSMALLINT driver_completion); +[[nodiscard]] SQLRETURN SQLConnect(SQLHDBC conn, SQLWCHAR* dsn_name, + SQLSMALLINT dsn_name_len, SQLWCHAR* user_name, + SQLSMALLINT user_name_len, SQLWCHAR* password, + SQLSMALLINT password_len); +[[nodiscard]] SQLRETURN SQLDisconnect(SQLHDBC conn); +[[nodiscard]] SQLRETURN SQLGetInfo(SQLHDBC conn, SQLUSMALLINT info_type, + SQLPOINTER info_value_ptr, SQLSMALLINT buf_len, + SQLSMALLINT* length); +[[nodiscard]] SQLRETURN SQLGetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, + SQLPOINTER value_ptr, SQLINTEGER buffer_length, + SQLINTEGER* string_length_ptr); +[[nodiscard]] SQLRETURN SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attribute, + SQLPOINTER value_ptr, SQLINTEGER stringLength); +[[nodiscard]] SQLRETURN SQLExecDirect(SQLHSTMT stmt, SQLWCHAR* queryText, + SQLINTEGER text_length); +[[nodiscard]] SQLRETURN SQLPrepare(SQLHSTMT stmt, SQLWCHAR* queryText, + SQLINTEGER text_length); +[[nodiscard]] SQLRETURN SQLExecute(SQLHSTMT stmt); +[[nodiscard]] SQLRETURN SQLFetch(SQLHSTMT stmt); +[[nodiscard]] SQLRETURN SQLExtendedFetch(SQLHSTMT stmt, SQLUSMALLINT fetch_orientation, + SQLLEN fetch_offset, SQLULEN* row_count_ptr, + SQLUSMALLINT* row_status_array); +[[nodiscard]] SQLRETURN SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT fetch_orientation, + SQLLEN fetch_offset); +[[nodiscard]] SQLRETURN SQLBindCol(SQLHSTMT stmt, SQLUSMALLINT record_number, + SQLSMALLINT c_type, SQLPOINTER data_ptr, + SQLLEN buffer_length, SQLLEN* indicator_ptr); +[[nodiscard]] SQLRETURN SQLCloseCursor(SQLHSTMT stmt); +[[nodiscard]] SQLRETURN SQLGetData(SQLHSTMT stmt, SQLUSMALLINT record_number, + SQLSMALLINT c_type, SQLPOINTER data_ptr, + SQLLEN buffer_length, SQLLEN* indicator_ptr); +[[nodiscard]] SQLRETURN SQLMoreResults(SQLHSTMT stmt); +[[nodiscard]] SQLRETURN SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT* column_count_ptr); +[[nodiscard]] SQLRETURN SQLRowCount(SQLHSTMT stmt, SQLLEN* row_count_ptr); +[[nodiscard]] SQLRETURN SQLTables(SQLHSTMT stmt, SQLWCHAR* catalog_name, + SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name, + SQLSMALLINT schema_name_length, SQLWCHAR* table_name, + SQLSMALLINT table_name_length, SQLWCHAR* table_type, + SQLSMALLINT table_type_length); +[[nodiscard]] SQLRETURN SQLColumns(SQLHSTMT stmt, SQLWCHAR* catalog_name, + SQLSMALLINT catalog_name_length, SQLWCHAR* schema_name, + SQLSMALLINT schema_name_length, SQLWCHAR* table_name, + SQLSMALLINT table_name_length, SQLWCHAR* column_name, + SQLSMALLINT column_name_length); +[[nodiscard]] SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, + SQLUSMALLINT field_identifier, + SQLPOINTER character_attribute_ptr, + SQLSMALLINT buffer_length, + SQLSMALLINT* output_length, + SQLLEN* numeric_attribute_ptr); +[[nodiscard]] SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT dataType); +[[nodiscard]] SQLRETURN SQLNativeSql(SQLHDBC conn, SQLWCHAR* in_statement_text, + SQLINTEGER in_statement_text_length, + SQLWCHAR* out_statement_text, + SQLINTEGER buffer_length, + SQLINTEGER* out_statement_text_length); +[[nodiscard]] SQLRETURN SQLDescribeCol( + SQLHSTMT stmt, SQLUSMALLINT column_number, SQLWCHAR* column_name, + SQLSMALLINT buffer_length, SQLSMALLINT* name_length_ptr, SQLSMALLINT* data_type_ptr, + SQLULEN* column_size_ptr, SQLSMALLINT* decimal_digits_ptr, SQLSMALLINT* nullable_ptr); } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc index 924186a9be3f..519bbbfe1ac7 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -27,10 +27,7 @@ namespace arrow::flight::sql::odbc { template -class ColumnsTest : public T { - public: - using List = std::list; -}; +class ColumnsTest : public T {}; class ColumnsMockTest : public FlightSQLODBCMockTestBase {}; class ColumnsRemoteTest : public FlightSQLODBCRemoteTestBase {}; @@ -38,16 +35,14 @@ using TestTypes = ::testing::Types; TYPED_TEST_SUITE(ColumnsTest, TestTypes); template -class ColumnsOdbcV2Test : public T { - public: - using List = std::list; -}; +class ColumnsOdbcV2Test : public T {}; class ColumnsOdbcV2MockTest : public FlightSQLOdbcV2MockTestBase {}; class ColumnsOdbcV2RemoteTest : public FlightSQLOdbcV2RemoteTestBase {}; using TestTypesOdbcV2 = ::testing::Types; TYPED_TEST_SUITE(ColumnsOdbcV2Test, TestTypesOdbcV2); +namespace { // Helper functions void CheckSQLColumns( SQLHSTMT stmt, const std::wstring& expected_table, @@ -379,6 +374,7 @@ void CheckSQLColAttributesNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLColAttributes(stmt, idx, field_identifier, 0, 0, 0, &num_val)); ASSERT_EQ(expected_attr_numeric, num_val); } +} // namespace TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) { SQLWCHAR catalog_name[] = L""; @@ -2206,23 +2202,38 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); - SQLWCHAR* column_names[] = { - (SQLWCHAR*)L"stiny_int_min", (SQLWCHAR*)L"stiny_int_max", - (SQLWCHAR*)L"utiny_int_min", (SQLWCHAR*)L"utiny_int_max", - (SQLWCHAR*)L"ssmall_int_min", (SQLWCHAR*)L"ssmall_int_max", - (SQLWCHAR*)L"usmall_int_min", (SQLWCHAR*)L"usmall_int_max", - (SQLWCHAR*)L"sinteger_min", (SQLWCHAR*)L"sinteger_max", - (SQLWCHAR*)L"uinteger_min", (SQLWCHAR*)L"uinteger_max", - (SQLWCHAR*)L"sbigint_min", (SQLWCHAR*)L"sbigint_max", - (SQLWCHAR*)L"ubigint_min", (SQLWCHAR*)L"ubigint_max", - (SQLWCHAR*)L"decimal_negative", (SQLWCHAR*)L"decimal_positive", - (SQLWCHAR*)L"float_min", (SQLWCHAR*)L"float_max", - (SQLWCHAR*)L"double_min", (SQLWCHAR*)L"double_max", - (SQLWCHAR*)L"bit_false", (SQLWCHAR*)L"bit_true", - (SQLWCHAR*)L"c_char", (SQLWCHAR*)L"c_wchar", - (SQLWCHAR*)L"c_wvarchar", (SQLWCHAR*)L"c_varchar", - (SQLWCHAR*)L"date_min", (SQLWCHAR*)L"date_max", - (SQLWCHAR*)L"timestamp_min", (SQLWCHAR*)L"timestamp_max"}; + const SQLWCHAR* column_names[] = {static_cast(L"stiny_int_min"), + static_cast(L"stiny_int_max"), + static_cast(L"utiny_int_min"), + static_cast(L"utiny_int_max"), + static_cast(L"ssmall_int_min"), + static_cast(L"ssmall_int_max"), + static_cast(L"usmall_int_min"), + static_cast(L"usmall_int_max"), + static_cast(L"sinteger_min"), + static_cast(L"sinteger_max"), + static_cast(L"uinteger_min"), + static_cast(L"uinteger_max"), + static_cast(L"sbigint_min"), + static_cast(L"sbigint_max"), + static_cast(L"ubigint_min"), + static_cast(L"ubigint_max"), + static_cast(L"decimal_negative"), + static_cast(L"decimal_positive"), + static_cast(L"float_min"), + static_cast(L"float_max"), + static_cast(L"double_min"), + static_cast(L"double_max"), + static_cast(L"bit_false"), + static_cast(L"bit_true"), + static_cast(L"c_char"), + static_cast(L"c_wchar"), + static_cast(L"c_wvarchar"), + static_cast(L"c_varchar"), + static_cast(L"date_min"), + static_cast(L"date_max"), + static_cast(L"timestamp_min"), + static_cast(L"timestamp_max")}; SQLSMALLINT column_data_types[] = { SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, @@ -2273,23 +2284,38 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); - SQLWCHAR* column_names[] = { - (SQLWCHAR*)L"stiny_int_min", (SQLWCHAR*)L"stiny_int_max", - (SQLWCHAR*)L"utiny_int_min", (SQLWCHAR*)L"utiny_int_max", - (SQLWCHAR*)L"ssmall_int_min", (SQLWCHAR*)L"ssmall_int_max", - (SQLWCHAR*)L"usmall_int_min", (SQLWCHAR*)L"usmall_int_max", - (SQLWCHAR*)L"sinteger_min", (SQLWCHAR*)L"sinteger_max", - (SQLWCHAR*)L"uinteger_min", (SQLWCHAR*)L"uinteger_max", - (SQLWCHAR*)L"sbigint_min", (SQLWCHAR*)L"sbigint_max", - (SQLWCHAR*)L"ubigint_min", (SQLWCHAR*)L"ubigint_max", - (SQLWCHAR*)L"decimal_negative", (SQLWCHAR*)L"decimal_positive", - (SQLWCHAR*)L"float_min", (SQLWCHAR*)L"float_max", - (SQLWCHAR*)L"double_min", (SQLWCHAR*)L"double_max", - (SQLWCHAR*)L"bit_false", (SQLWCHAR*)L"bit_true", - (SQLWCHAR*)L"c_char", (SQLWCHAR*)L"c_wchar", - (SQLWCHAR*)L"c_wvarchar", (SQLWCHAR*)L"c_varchar", - (SQLWCHAR*)L"date_min", (SQLWCHAR*)L"date_max", - (SQLWCHAR*)L"timestamp_min", (SQLWCHAR*)L"timestamp_max"}; + const SQLWCHAR* column_names[] = {static_cast(L"stiny_int_min"), + static_cast(L"stiny_int_max"), + static_cast(L"utiny_int_min"), + static_cast(L"utiny_int_max"), + static_cast(L"ssmall_int_min"), + static_cast(L"ssmall_int_max"), + static_cast(L"usmall_int_min"), + static_cast(L"usmall_int_max"), + static_cast(L"sinteger_min"), + static_cast(L"sinteger_max"), + static_cast(L"uinteger_min"), + static_cast(L"uinteger_max"), + static_cast(L"sbigint_min"), + static_cast(L"sbigint_max"), + static_cast(L"ubigint_min"), + static_cast(L"ubigint_max"), + static_cast(L"decimal_negative"), + static_cast(L"decimal_positive"), + static_cast(L"float_min"), + static_cast(L"float_max"), + static_cast(L"double_min"), + static_cast(L"double_max"), + static_cast(L"bit_false"), + static_cast(L"bit_true"), + static_cast(L"c_char"), + static_cast(L"c_wchar"), + static_cast(L"c_wvarchar"), + static_cast(L"c_varchar"), + static_cast(L"date_min"), + static_cast(L"date_max"), + static_cast(L"timestamp_min"), + static_cast(L"timestamp_max")}; SQLSMALLINT column_data_types[] = { SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, SQL_INTEGER, @@ -2349,11 +2375,15 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { SQLWCHAR sql_query[] = L"SELECT * from $scratch.ODBCTest LIMIT 1;"; SQLINTEGER query_length = static_cast(wcslen(sql_query)); - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"sinteger_max", (SQLWCHAR*)L"sbigint_max", - (SQLWCHAR*)L"decimal_positive", (SQLWCHAR*)L"float_max", - (SQLWCHAR*)L"double_max", (SQLWCHAR*)L"bit_true", - (SQLWCHAR*)L"date_max", (SQLWCHAR*)L"time_max", - (SQLWCHAR*)L"timestamp_max"}; + const SQLWCHAR* column_names[] = {static_cast(L"sinteger_max"), + static_cast(L"sbigint_max"), + static_cast(L"decimal_positive"), + static_cast(L"float_max"), + static_cast(L"double_max"), + static_cast(L"bit_true"), + static_cast(L"date_max"), + static_cast(L"time_max"), + static_cast(L"timestamp_max")}; SQLSMALLINT column_data_types[] = {SQL_INTEGER, SQL_BIGINT, SQL_DECIMAL, SQL_FLOAT, SQL_DOUBLE, SQL_BIT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP}; @@ -2403,11 +2433,15 @@ TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBC2) { SQLWCHAR sql_query[] = L"SELECT * from $scratch.ODBCTest LIMIT 1;"; SQLINTEGER query_length = static_cast(wcslen(sql_query)); - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"sinteger_max", (SQLWCHAR*)L"sbigint_max", - (SQLWCHAR*)L"decimal_positive", (SQLWCHAR*)L"float_max", - (SQLWCHAR*)L"double_max", (SQLWCHAR*)L"bit_true", - (SQLWCHAR*)L"date_max", (SQLWCHAR*)L"time_max", - (SQLWCHAR*)L"timestamp_max"}; + const SQLWCHAR* column_names[] = {static_cast(L"sinteger_max"), + static_cast(L"sbigint_max"), + static_cast(L"decimal_positive"), + static_cast(L"float_max"), + static_cast(L"double_max"), + static_cast(L"bit_true"), + static_cast(L"date_max"), + static_cast(L"time_max"), + static_cast(L"timestamp_max")}; SQLSMALLINT column_data_types[] = {SQL_INTEGER, SQL_BIGINT, SQL_DECIMAL, SQL_FLOAT, SQL_DOUBLE, SQL_BIT, SQL_DATE, SQL_TIME, SQL_TIMESTAMP}; @@ -2458,8 +2492,10 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { SQLWCHAR sql_query[] = L"SELECT * from AllTypesTable LIMIT 1;"; SQLINTEGER query_length = static_cast(wcslen(sql_query)); - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"bigint_col", (SQLWCHAR*)L"char_col", - (SQLWCHAR*)L"varbinary_col", (SQLWCHAR*)L"double_col"}; + const SQLWCHAR* column_names[] = {static_cast(L"bigint_col"), + static_cast(L"char_col"), + static_cast(L"varbinary_col"), + static_cast(L"double_col")}; SQLSMALLINT column_data_types[] = {SQL_BIGINT, SQL_WVARCHAR, SQL_BINARY, SQL_DOUBLE}; SQLULEN column_sizes[] = {8, 0, 0, 8}; @@ -2540,16 +2576,24 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR* column_names[] = { - (SQLWCHAR*)L"TABLE_CAT", (SQLWCHAR*)L"TABLE_SCHEM", - (SQLWCHAR*)L"TABLE_NAME", (SQLWCHAR*)L"COLUMN_NAME", - (SQLWCHAR*)L"DATA_TYPE", (SQLWCHAR*)L"TYPE_NAME", - (SQLWCHAR*)L"COLUMN_SIZE", (SQLWCHAR*)L"BUFFER_LENGTH", - (SQLWCHAR*)L"DECIMAL_DIGITS", (SQLWCHAR*)L"NUM_PREC_RADIX", - (SQLWCHAR*)L"NULLABLE", (SQLWCHAR*)L"REMARKS", - (SQLWCHAR*)L"COLUMN_DEF", (SQLWCHAR*)L"SQL_DATA_TYPE", - (SQLWCHAR*)L"SQL_DATETIME_SUB", (SQLWCHAR*)L"CHAR_OCTET_LENGTH", - (SQLWCHAR*)L"ORDINAL_POSITION", (SQLWCHAR*)L"IS_NULLABLE"}; + const SQLWCHAR* column_names[] = {static_cast(L"TABLE_CAT"), + static_cast(L"TABLE_SCHEM"), + static_cast(L"TABLE_NAME"), + static_cast(L"COLUMN_NAME"), + static_cast(L"DATA_TYPE"), + static_cast(L"TYPE_NAME"), + static_cast(L"COLUMN_SIZE"), + static_cast(L"BUFFER_LENGTH"), + static_cast(L"DECIMAL_DIGITS"), + static_cast(L"NUM_PREC_RADIX"), + static_cast(L"NULLABLE"), + static_cast(L"REMARKS"), + static_cast(L"COLUMN_DEF"), + static_cast(L"SQL_DATA_TYPE"), + static_cast(L"SQL_DATETIME_SUB"), + static_cast(L"CHAR_OCTET_LENGTH"), + static_cast(L"ORDINAL_POSITION"), + static_cast(L"IS_NULLABLE")}; SQLSMALLINT column_data_types[] = { SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_SMALLINT, SQL_WVARCHAR, SQL_INTEGER, SQL_INTEGER, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, SQL_WVARCHAR, @@ -2595,24 +2639,24 @@ TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBC2) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"TABLE_QUALIFIER", - (SQLWCHAR*)L"TABLE_OWNER", - (SQLWCHAR*)L"TABLE_NAME", - (SQLWCHAR*)L"COLUMN_NAME", - (SQLWCHAR*)L"DATA_TYPE", - (SQLWCHAR*)L"TYPE_NAME", - (SQLWCHAR*)L"PRECISION", - (SQLWCHAR*)L"LENGTH", - (SQLWCHAR*)L"SCALE", - (SQLWCHAR*)L"RADIX", - (SQLWCHAR*)L"NULLABLE", - (SQLWCHAR*)L"REMARKS", - (SQLWCHAR*)L"COLUMN_DEF", - (SQLWCHAR*)L"SQL_DATA_TYPE", - (SQLWCHAR*)L"SQL_DATETIME_SUB", - (SQLWCHAR*)L"CHAR_OCTET_LENGTH", - (SQLWCHAR*)L"ORDINAL_POSITION", - (SQLWCHAR*)L"IS_NULLABLE"}; + const SQLWCHAR* column_names[] = {static_cast(L"TABLE_QUALIFIER"), + static_cast(L"TABLE_OWNER"), + static_cast(L"TABLE_NAME"), + static_cast(L"COLUMN_NAME"), + static_cast(L"DATA_TYPE"), + static_cast(L"TYPE_NAME"), + static_cast(L"PRECISION"), + static_cast(L"LENGTH"), + static_cast(L"SCALE"), + static_cast(L"RADIX"), + static_cast(L"NULLABLE"), + static_cast(L"REMARKS"), + static_cast(L"COLUMN_DEF"), + static_cast(L"SQL_DATA_TYPE"), + static_cast(L"SQL_DATETIME_SUB"), + static_cast(L"CHAR_OCTET_LENGTH"), + static_cast(L"ORDINAL_POSITION"), + static_cast(L"IS_NULLABLE")}; SQLSMALLINT column_data_types[] = { SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_SMALLINT, SQL_WVARCHAR, SQL_INTEGER, SQL_INTEGER, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, SQL_WVARCHAR, 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 a469c585f130..b7019cdda424 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; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc index 4e6707e7f646..d241510cea39 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc @@ -27,15 +27,13 @@ namespace arrow::flight::sql::odbc { template -class ConnectionInfoTest : public T { - public: - using List = std::list; -}; +class ConnectionInfoTest : public T {}; class ConnectionInfoMockTest : public FlightSQLODBCMockTestBase {}; using TestTypes = ::testing::Types; TYPED_TEST_SUITE(ConnectionInfoTest, TestTypes); +namespace { // Helper Functions // Validate unsigned short SQLUSMALLINT return value @@ -72,7 +70,8 @@ void Validate(SQLHDBC connection, SQLUSMALLINT info_type, SQLULEN expected_value } // Validate wchar string SQLWCHAR return value -void Validate(SQLHDBC connection, SQLUSMALLINT info_type, SQLWCHAR* expected_value) { +void Validate(SQLHDBC connection, SQLUSMALLINT info_type, + const SQLWCHAR* expected_value) { SQLWCHAR info_value[kOdbcBufferSize] = L""; SQLSMALLINT message_length; @@ -122,6 +121,7 @@ void ValidateNotEmptySQLWCHAR(SQLHDBC connection, SQLUSMALLINT info_type, EXPECT_GT(wcslen(info_value), 0); } +} // namespace // Driver Information @@ -156,13 +156,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchSupport) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceName) { - Validate(this->conn, SQL_DATA_SOURCE_NAME, (SQLWCHAR*)L""); + Validate(this->conn, SQL_DATA_SOURCE_NAME, static_cast(L"")); } #ifdef SQL_DRIVER_AWARE_POOLING_SUPPORTED TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) { - // A driver does not need to implement SQL_DRIVER_AWARE_POOLING_SUPPORTED and the - // Driver Manager will not honor to the driver's return value. + // According to Microsoft documentation, ODBC driver does not need to implement + // SQL_DRIVER_AWARE_POOLING_SUPPORTED and the Driver Manager will ignore the + // driver's return value for it. Validate(this->conn, SQL_DRIVER_AWARE_POOLING_SUPPORTED, static_cast(SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE)); @@ -211,15 +212,16 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHstmt) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverName) { - Validate(this->conn, SQL_DRIVER_NAME, (SQLWCHAR*)L"Arrow Flight ODBC Driver"); + Validate(this->conn, SQL_DRIVER_NAME, + static_cast(L"Arrow Flight ODBC Driver")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverOdbcVer) { - Validate(this->conn, SQL_DRIVER_ODBC_VER, (SQLWCHAR*)L"03.80"); + Validate(this->conn, SQL_DRIVER_ODBC_VER, static_cast(L"03.80")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverVer) { - Validate(this->conn, SQL_DRIVER_VER, (SQLWCHAR*)L"00.09.0000.0"); + Validate(this->conn, SQL_DRIVER_VER, static_cast(L"00.09.0000.0")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDynamicCursorAttributes1) { @@ -291,7 +293,7 @@ TYPED_TEST(ConnectionInfoTest, DISABLED_TestSQLGetInfoOdbcStandardCliConformance TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcVer) { // This is implemented only in the Driver Manager. - Validate(this->conn, SQL_ODBC_VER, (SQLWCHAR*)L"03.80.0000"); + Validate(this->conn, SQL_ODBC_VER, static_cast(L"03.80.0000")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArrayRowCounts) { @@ -305,11 +307,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArraySelects) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoRowUpdates) { - Validate(this->conn, SQL_ROW_UPDATES, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_ROW_UPDATES, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSearchPatternEscape) { - Validate(this->conn, SQL_SEARCH_PATTERN_ESCAPE, (SQLWCHAR*)L"\\"); + Validate(this->conn, SQL_SEARCH_PATTERN_ESCAPE, static_cast(L"\\")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoServerName) { @@ -327,7 +329,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes2) { // DBMS Product Information TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDatabaseName) { - Validate(this->conn, SQL_DATABASE_NAME, (SQLWCHAR*)L""); + Validate(this->conn, SQL_DATABASE_NAME, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsName) { @@ -341,11 +343,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { // Data Source Information TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleProcedures) { - Validate(this->conn, SQL_ACCESSIBLE_PROCEDURES, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_ACCESSIBLE_PROCEDURES, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleTables) { - Validate(this->conn, SQL_ACCESSIBLE_TABLES, (SQLWCHAR*)L"Y"); + Validate(this->conn, SQL_ACCESSIBLE_TABLES, static_cast(L"Y")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBookmarkPersistence) { @@ -353,11 +355,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBookmarkPersistence) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogTerm) { - Validate(this->conn, SQL_CATALOG_TERM, (SQLWCHAR*)L""); + Validate(this->conn, SQL_CATALOG_TERM, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCollationSeq) { - Validate(this->conn, SQL_COLLATION_SEQ, (SQLWCHAR*)L""); + Validate(this->conn, SQL_COLLATION_SEQ, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConcatNullBehavior) { @@ -379,7 +381,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorSensitivity) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceReadOnly) { - Validate(this->conn, SQL_DATA_SOURCE_READ_ONLY, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_DATA_SOURCE_READ_ONLY, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDefaultTxnIsolation) { @@ -387,19 +389,19 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDefaultTxnIsolation) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDescribeParameter) { - Validate(this->conn, SQL_DESCRIBE_PARAMETER, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_DESCRIBE_PARAMETER, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultResultSets) { - Validate(this->conn, SQL_MULT_RESULT_SETS, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_MULT_RESULT_SETS, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultipleActiveTxn) { - Validate(this->conn, SQL_MULTIPLE_ACTIVE_TXN, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_MULTIPLE_ACTIVE_TXN, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoNeedLongDataLen) { - Validate(this->conn, SQL_NEED_LONG_DATA_LEN, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_NEED_LONG_DATA_LEN, static_cast(L"N")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNullCollation) { @@ -407,11 +409,11 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNullCollation) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoProcedureTerm) { - Validate(this->conn, SQL_PROCEDURE_TERM, (SQLWCHAR*)L""); + Validate(this->conn, SQL_PROCEDURE_TERM, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaTerm) { - Validate(this->conn, SQL_SCHEMA_TERM, (SQLWCHAR*)L"schema"); + Validate(this->conn, SQL_SCHEMA_TERM, static_cast(L"schema")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoScrollOptions) { @@ -419,7 +421,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoScrollOptions) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTableTerm) { - Validate(this->conn, SQL_TABLE_TERM, (SQLWCHAR*)L"table"); + Validate(this->conn, SQL_TABLE_TERM, static_cast(L"table")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnCapable) { @@ -431,7 +433,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnIsolationOption) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoUserName) { - Validate(this->conn, SQL_USER_NAME, (SQLWCHAR*)L""); + Validate(this->conn, SQL_USER_NAME, static_cast(L"")); } // Supported SQL @@ -460,7 +462,8 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { TYPED_TEST(ConnectionInfoTest, DISABLED_TestSQLGetInfoAnsiSqlDatetimeLiterals) { // Type commented out in odbc_connection.cc // Type does not exist in sql.h - // Validate(this->conn, SQL_ANSI_SQL_DATETIME_LITERALS, (SQLWCHAR*)L""); + // Validate(this->conn, SQL_ANSI_SQL_DATETIME_LITERALS, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogLocation) { @@ -468,11 +471,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogLocation) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogName) { - Validate(this->conn, SQL_CATALOG_NAME, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_CATALOG_NAME, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogNameSeparator) { - Validate(this->conn, SQL_CATALOG_NAME_SEPARATOR, (SQLWCHAR*)L""); + Validate(this->conn, SQL_CATALOG_NAME_SEPARATOR, static_cast(L"")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCatalogUsage) { @@ -480,7 +483,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCatalogUsage) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoColumnAlias) { - Validate(this->conn, SQL_COLUMN_ALIAS, (SQLWCHAR*)L"Y"); + Validate(this->conn, SQL_COLUMN_ALIAS, static_cast(L"Y")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCorrelationName) { @@ -552,7 +555,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropView) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoExpressionsInOrderby) { - Validate(this->conn, SQL_EXPRESSIONS_IN_ORDERBY, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_EXPRESSIONS_IN_ORDERBY, static_cast(L"N")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoGroupBy) { @@ -565,7 +568,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierCase) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierQuoteChar) { - Validate(this->conn, SQL_IDENTIFIER_QUOTE_CHAR, (SQLWCHAR*)L"\""); + Validate(this->conn, SQL_IDENTIFIER_QUOTE_CHAR, static_cast(L"\")")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIndexKeywords) { @@ -579,7 +582,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoInsertStatement) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIntegrity) { - Validate(this->conn, SQL_INTEGRITY, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_INTEGRITY, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { @@ -587,7 +590,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { - Validate(this->conn, SQL_LIKE_ESCAPE_CLAUSE, (SQLWCHAR*)L"Y"); + Validate(this->conn, SQL_LIKE_ESCAPE_CLAUSE, static_cast(L"Y")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNonNullableColumns) { @@ -600,15 +603,16 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOjCapabilities) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOrderByColumnsInSelect) { - Validate(this->conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, (SQLWCHAR*)L"Y"); + Validate(this->conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, + static_cast(L"Y")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOuterJoins) { - Validate(this->conn, SQL_OUTER_JOINS, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_OUTER_JOINS, static_cast(L"N")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoProcedures) { - Validate(this->conn, SQL_PROCEDURES, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_PROCEDURES, static_cast(L"N")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoQuotedIdentifierCase) { @@ -621,7 +625,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSchemaUsage) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSpecialCharacters) { - Validate(this->conn, SQL_SPECIAL_CHARACTERS, (SQLWCHAR*)L""); + Validate(this->conn, SQL_SPECIAL_CHARACTERS, static_cast(L"")); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSqlConformance) { @@ -694,11 +698,12 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxProcedureNameLen) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxRowSize) { - Validate(this->conn, SQL_MAX_ROW_SIZE, (SQLWCHAR*)L""); + Validate(this->conn, SQL_MAX_ROW_SIZE, static_cast(L"")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxRowSizeIncludesLong) { - Validate(this->conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, (SQLWCHAR*)L"N"); + Validate(this->conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, + static_cast(L"N")); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxSchemaNameLen) { diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc index 5bd7caf06d60..a16c29dbf4e7 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc @@ -28,26 +28,19 @@ namespace arrow::flight::sql::odbc { template -class ConnectionTest : public T { - public: - using List = std::list; -}; +class ConnectionTest : public T {}; -class ConnectionRemoteTest : public FlightSQLODBCRemoteTestBase {}; -using TestTypes = ::testing::Types; +using TestTypes = + ::testing::Types; TYPED_TEST_SUITE(ConnectionTest, TestTypes); -TEST(ODBCHandles, TestSQLAllocAndFreeHandleEnv) { - // Allocate an environment handle - SQLHENV env = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env)); - - // Check for valid handle - ASSERT_NE(nullptr, env); +template +class ConnectionHandleTest : public T {}; - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); -} +class ConnectionRemoteTest : public FlightSQLOdbcHandleRemoteTestBase {}; +using TestTypesHandle = + ::testing::Types; +TYPED_TEST_SUITE(ConnectionHandleTest, TestTypesHandle); TEST(ODBCHandles, TestSQLAllocAndFreeEnv) { // Allocate an environment handle @@ -101,7 +94,7 @@ TEST(ODBCHandles, TestSQLAllocAndFreeConnect) { ASSERT_EQ(SQL_SUCCESS, SQLFreeEnv(env)); } -TEST(SQLFreeHandle, TestFreeNullHandles) { +TEST(ODBCHandles, TestFreeNullHandles) { SQLHENV env = NULL; SQLHDBC conn = NULL; SQLHSTMT stmt = NULL; @@ -222,19 +215,7 @@ TEST(SQLSetEnvAttr, TestSQLSetEnvAttrNullValuePointer) { ASSERT_EQ(SQL_SUCCESS, SQLFreeEnv(env)); } -TYPED_TEST(ODBCTestBase, TestSQLDriverConnect) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnect) { // Connect string std::string connect_str = this->GetConnectionString(); ASSERT_OK_AND_ASSIGN(std::wstring wconnect_str, @@ -246,10 +227,10 @@ TYPED_TEST(ODBCTestBase, TestSQLDriverConnect) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Check that out_str has same content as connect_str std::string out_connection_string = ODBC::SqlWcharToString(out_str, out_str_len); @@ -261,30 +242,12 @@ TYPED_TEST(ODBCTestBase, TestSQLDriverConnect) { ASSERT_TRUE(CompareConnPropertyMap(out_properties, in_properties)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } #if defined _WIN32 -TYPED_TEST(ODBCTestBase, TestSQLDriverConnectDsn) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnectDsn) { // Connect string std::string connect_str = this->GetConnectionString(); @@ -307,38 +270,20 @@ TYPED_TEST(ODBCTestBase, TestSQLDriverConnectDsn) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } -TYPED_TEST(ODBCTestBase, TestSQLConnect) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TYPED_TEST(ConnectionHandleTest, TestSQLConnect) { // Connect string std::string connect_str = this->GetConnectionString(); @@ -357,38 +302,20 @@ TYPED_TEST(ODBCTestBase, TestSQLConnect) { // Connecting to ODBC server. Empty uid and pwd should be ignored. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } -TEST_F(ODBCRemoteTestBase, TestSQLConnectInputUidPwd) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { // Connect string std::string connect_str = GetConnectionString(); @@ -416,7 +343,7 @@ TEST_F(ODBCRemoteTestBase, TestSQLConnectInputUidPwd) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); @@ -425,29 +352,11 @@ TEST_F(ODBCRemoteTestBase, TestSQLConnectInputUidPwd) { ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST_F(ODBCRemoteTestBase, TestSQLConnectInvalidUid) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { // Connect string std::string connect_str = GetConnectionString(); @@ -476,35 +385,17 @@ TEST_F(ODBCRemoteTestBase, TestSQLConnectInvalidUid) { // UID specified in DSN will take precedence, // so connection still fails despite passing valid uid in SQLConnect call ASSERT_EQ(SQL_ERROR, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState28000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState28000); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST_F(ODBCRemoteTestBase, TestSQLConnectDSNPrecedence) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TEST_F(ConnectionRemoteTest, TestSQLConnectDSNPrecedence) { // Connect string std::string connect_str = GetConnectionString(); @@ -526,7 +417,7 @@ TEST_F(ODBCRemoteTestBase, TestSQLConnectDSNPrecedence) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); @@ -535,31 +426,13 @@ TEST_F(ODBCRemoteTestBase, TestSQLConnectDSNPrecedence) { ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } #endif -TEST_F(ODBCRemoteTestBase, TestSQLDriverConnectInvalidUid) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { // Invalid connect string std::string connect_str = GetInvalidConnectionString(); @@ -572,46 +445,22 @@ TEST_F(ODBCRemoteTestBase, TestSQLDriverConnectInvalidUid) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState28000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState28000); std::string out_connection_string = ODBC::SqlWcharToString(out_str, out_str_len); ASSERT_TRUE(out_connection_string.empty()); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TEST(SQLDisconnect, TestSQLDisconnectWithoutConnection) { - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TYPED_TEST(ConnectionHandleTest, TestSQLDisconnectWithoutConnection) { // Attempt to disconnect without a connection, expect to fail - ASSERT_EQ(SQL_ERROR, SQLDisconnect(conn)); + ASSERT_EQ(SQL_ERROR, SQLDisconnect(this->conn)); // Expect ODBC driver manager to return error state - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState08003); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState08003); } TYPED_TEST(ConnectionTest, TestConnect) { @@ -634,20 +483,9 @@ TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) { ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_DROP)); } -TYPED_TEST(ODBCTestBase, TestCloseConnectionWithOpenStatement) { - SQLHENV env; - SQLHDBC conn; +TYPED_TEST(ConnectionHandleTest, TestCloseConnectionWithOpenStatement) { SQLHSTMT statement; - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - // Connect string std::string connect_str = this->GetConnectionString(); ASSERT_OK_AND_ASSIGN(std::wstring wconnect_str, @@ -659,21 +497,16 @@ TYPED_TEST(ODBCTestBase, TestCloseConnectionWithOpenStatement) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, - kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); + kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Allocate a statement using alloc statement - ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(conn, &statement)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement)); // Disconnect from ODBC without closing the statement first - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)); } TYPED_TEST(ConnectionTest, TestSQLAllocFreeDesc) { diff --git a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc index 7515a74753f6..ec46312aeadd 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -27,39 +27,27 @@ namespace arrow::flight::sql::odbc { template -class ErrorsTest : public T { - public: - using List = std::list; -}; +class ErrorsTest : public T {}; using TestTypes = ::testing::Types; TYPED_TEST_SUITE(ErrorsTest, TestTypes); template -class ErrorsOdbcV2Test : public T { - public: - using List = std::list; -}; +class ErrorsOdbcV2Test : public T {}; using TestTypesOdbcV2 = ::testing::Types; TYPED_TEST_SUITE(ErrorsOdbcV2Test, TestTypesOdbcV2); -TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { - // ODBC Environment - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); +template +class ErrorsHandleTest : public T {}; - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); +using TestTypesHandle = + ::testing::Types; +TYPED_TEST_SUITE(ErrorsHandleTest, TestTypesHandle); +TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { // Invalid connect string std::string connect_str = this->GetInvalidConnectionString(); @@ -72,7 +60,7 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -85,7 +73,7 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT diag_number_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, HEADER_LEVEL, SQL_DIAG_NUMBER, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, HEADER_LEVEL, SQL_DIAG_NUMBER, &diag_number, sizeof(SQLINTEGER), &diag_number_length)); EXPECT_EQ(1, diag_number); @@ -95,7 +83,7 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT server_name_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_SERVER_NAME, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_SERVER_NAME, server_name, kOdbcBufferSize, &server_name_length)); // SQL_DIAG_MESSAGE_TEXT @@ -103,7 +91,7 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT message_text_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, message_text, kOdbcBufferSize, &message_text_length)); EXPECT_GT(message_text_length, 100); @@ -113,8 +101,8 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT diag_native_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_NATIVE, &diag_native, - sizeof(diag_native), &diag_native_length)); + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_NATIVE, + &diag_native, sizeof(diag_native), &diag_native_length)); EXPECT_EQ(200, diag_native); @@ -123,34 +111,18 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagFieldWForConnectFailure) { SQLWCHAR sql_state[sql_state_size]; SQLSMALLINT sql_state_length; - EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_SQLSTATE, sql_state, - sql_state_size * arrow::flight::sql::odbc::GetSqlWCharSize(), - &sql_state_length)); + EXPECT_EQ( + SQL_SUCCESS, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_SQLSTATE, sql_state, + sql_state_size * arrow::flight::sql::odbc::GetSqlWCharSize(), + &sql_state_length)); EXPECT_EQ(std::wstring(L"28000"), std::wstring(sql_state)); - - // Free connection handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } -TYPED_TEST(ODBCTestBase, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { +TYPED_TEST(ErrorsHandleTest, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { // Test is disabled because driver manager on Windows does not pass through SQL_NTS // This test case can be potentially used on macOS/Linux - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); // Invalid connect string std::string connect_str = this->GetInvalidConnectionString(); @@ -164,7 +136,7 @@ TYPED_TEST(ODBCTestBase, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -178,16 +150,10 @@ TYPED_TEST(ODBCTestBase, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) { message_text[kOdbcBufferSize - 1] = '\0'; ASSERT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, message_text, SQL_NTS, &message_text_length)); EXPECT_GT(message_text_length, 100); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } TYPED_TEST(ErrorsTest, TestSQLGetDiagFieldWForDescriptorFailureFromDriverManager) { @@ -287,20 +253,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForDescriptorFailureFromDriverManager) { EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DESC, descriptor)); } -TYPED_TEST(ODBCTestBase, TestSQLGetDiagRecForConnectFailure) { - // ODBC Environment - SQLHENV env; - SQLHDBC conn; - - // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); - - ASSERT_EQ(SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)); - - // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); - +TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagRecForConnectFailure) { // Invalid connect string std::string connect_str = this->GetInvalidConnectionString(); @@ -313,7 +266,7 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagRecForConnectFailure) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -321,8 +274,9 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagRecForConnectFailure) { SQLINTEGER native_error; SQLWCHAR message[kOdbcBufferSize]; SQLSMALLINT message_length; - ASSERT_EQ(SQL_SUCCESS, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 1, sql_state, &native_error, - message, kOdbcBufferSize, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 1, sql_state, &native_error, + message, kOdbcBufferSize, &message_length)); EXPECT_GT(message_length, 120); @@ -331,12 +285,6 @@ TYPED_TEST(ODBCTestBase, TestSQLGetDiagRecForConnectFailure) { EXPECT_EQ(std::wstring(L"28000"), std::wstring(sql_state)); EXPECT_TRUE(!std::wstring(message).empty()); - - // Free connection handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); - - // Free environment handle - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); } TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) { diff --git a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index 8bfbef8dad54..35d7f2f935d6 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -27,20 +27,14 @@ namespace arrow::flight::sql::odbc { template -class GetFunctionsTest : public T { - public: - using List = std::list; -}; +class GetFunctionsTest : public T {}; using TestTypes = ::testing::Types; TYPED_TEST_SUITE(GetFunctionsTest, TestTypes); template -class GetFunctionsOdbcV2Test : public T { - public: - using List = std::list; -}; +class GetFunctionsOdbcV2Test : public T {}; using TestTypesOdbcV2 = ::testing::Types; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc index 19d5e3864b5c..f2e3e5da7207 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc @@ -73,6 +73,10 @@ void ODBCRemoteTestBase::Disconnect() { EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + FreeEnvConnHandles(); +} + +void ODBCRemoteTestBase::FreeEnvConnHandles() { // Free connection handle EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); @@ -178,6 +182,23 @@ void FlightSQLOdbcV2RemoteTestBase::SetUp() { connected_ = true; } +void FlightSQLOdbcHandleRemoteTestBase::SetUp() { + ODBCRemoteTestBase::SetUp(); + if (skipping_test_) { + return; + } + + this->AllocEnvConnHandles(); + allocated_ = true; +} + +void FlightSQLOdbcHandleRemoteTestBase::TearDown() { + if (allocated_) { + this->FreeEnvConnHandles(); + allocated_ = false; + } +} + std::string FindTokenInCallHeaders(const CallHeaders& incoming_headers) { // Lambda function to compare characters without case sensitivity. auto char_compare = [](const char& char1, const char& char2) { @@ -371,6 +392,16 @@ void FlightSQLOdbcV2MockTestBase::SetUp() { connected_ = true; } +void FlightSQLOdbcHandleMockTestBase::SetUp() { + ODBCMockTestBase::SetUp(); + this->AllocEnvConnHandles(); +} + +void FlightSQLOdbcHandleMockTestBase::TearDown() { + this->FreeEnvConnHandles(); + ODBCMockTestBase::TearDown(); +} + bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, Connection::ConnPropertyMap map2) { if (map1.size() != map2.size()) return false; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h index 5cac67d810c4..e043a459f0a1 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h @@ -50,6 +50,8 @@ class ODBCRemoteTestBase : public ::testing::Test { public: /// \brief Allocate environment and connection handles void AllocEnvConnHandles(SQLINTEGER odbc_ver = SQL_OV_ODBC3); + /// \brief Free environment and connection handles + void FreeEnvConnHandles(); /// \brief Connect to Arrow Flight SQL server using connection string defined in /// environment variable "ARROW_FLIGHT_SQL_ODBC_CONN", allocate statement handle. /// Connects using ODBC Ver 3 by default @@ -103,6 +105,14 @@ class FlightSQLOdbcV2RemoteTestBase : public FlightSQLODBCRemoteTestBase { void SetUp() override; }; +class FlightSQLOdbcHandleRemoteTestBase : public FlightSQLODBCRemoteTestBase { + protected: + void SetUp() override; + void TearDown() override; + + bool allocated_ = false; +}; + static constexpr std::string_view kAuthorizationHeader = "authorization"; static constexpr std::string_view kBearerPrefix = "Bearer "; static constexpr std::string_view kTestToken = "t0k3n"; @@ -166,7 +176,6 @@ class ODBCMockTestBase : public FlightSQLODBCRemoteTestBase { void TearDown() override; - private: std::shared_ptr server_; }; @@ -188,10 +197,11 @@ class FlightSQLOdbcV2MockTestBase : public FlightSQLODBCMockTestBase { void SetUp() override; }; -template -class ODBCTestBase : public T {}; -using OdbcBaseTestTypes = ::testing::Types; -TYPED_TEST_SUITE(ODBCTestBase, OdbcBaseTestTypes); +class FlightSQLOdbcHandleMockTestBase : public FlightSQLODBCMockTestBase { + protected: + void SetUp() override; + void TearDown() override; +}; /** ODBC read buffer size. */ static constexpr int kOdbcBufferSize = 1024; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc index 3e95f52add24..85cb2e96b596 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc @@ -30,15 +30,13 @@ namespace arrow::flight::sql::odbc { template -class StatementAttributeTest : public T { - public: - using List = std::list; -}; +class StatementAttributeTest : public T {}; using TestTypes = ::testing::Types; TYPED_TEST_SUITE(StatementAttributeTest, TestTypes); +namespace { // Helper Functions // Validate SQLULEN return value @@ -135,6 +133,7 @@ void ValidateSetStmtAttrErrorCode(SQLHSTMT statement, SQLINTEGER attribute, VerifyOdbcErrorState(SQL_HANDLE_STMT, statement, error_code); } +} // namespace // Test Cases diff --git a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc index 029a76bab228..fe8817df559d 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc @@ -30,10 +30,7 @@ namespace arrow::flight::sql::odbc { template -class StatementTest : public T { - public: - using List = std::list; -}; +class StatementTest : public T {}; class StatementMockTest : public FlightSQLODBCMockTestBase {}; class StatementRemoteTest : public FlightSQLODBCRemoteTestBase {}; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc index 762c6a05bcaf..91d079eb8445 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -27,10 +27,7 @@ namespace arrow::flight::sql::odbc { template -class TablesTest : public T { - public: - using List = std::list; -}; +class TablesTest : public T {}; class TablesMockTest : public FlightSQLODBCMockTestBase {}; class TablesRemoteTest : public FlightSQLODBCRemoteTestBase {}; @@ -38,15 +35,13 @@ using TestTypes = ::testing::Types; TYPED_TEST_SUITE(TablesTest, TestTypes); template -class TablesOdbcV2Test : public T { - public: - using List = std::list; -}; +class TablesOdbcV2Test : public T {}; using TestTypesOdbcV2 = ::testing::Types; TYPED_TEST_SUITE(TablesOdbcV2Test, TestTypesOdbcV2); +namespace { // Helper Functions std::wstring GetStringColumnW(SQLHSTMT stmt, int colId) { @@ -64,6 +59,7 @@ std::wstring GetStringColumnW(SQLHSTMT stmt, int colId) { size_t char_count = static_cast(len_indicator) / ODBC::GetSqlWCharSize(); return std::wstring(buf, buf + char_count); } +} // namespace // Test Cases @@ -125,8 +121,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { this->CreateTestTables(); SQLWCHAR catalog_name[] = L"main"; - SQLWCHAR* table_names[] = {(SQLWCHAR*)L"TestTable", (SQLWCHAR*)L"foreignTable", - (SQLWCHAR*)L"intTable", (SQLWCHAR*)L"sqlite_sequence"}; + const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), + static_cast(L"foreignTable"), + static_cast(L"intTable"), + static_cast(L"sqlite_sequence")}; std::wstring expected_catalog_name = std::wstring(catalog_name); std::wstring expected_table_type = std::wstring(L"table"); @@ -194,38 +192,38 @@ TEST_F(TablesRemoteTest, SQLTablesTestGetMetadataForAllSchemas) { TEST_F(TablesRemoteTest, SQLTablesTestFilterByAllSchema) { // Requires creation of user table named ODBCTest using schema $scratch in remote server SQLWCHAR SQL_ALL_SCHEMAS_W[] = L"%"; - SQLWCHAR* schema_names[] = {(SQLWCHAR*)L"INFORMATION_SCHEMA", - (SQLWCHAR*)L"INFORMATION_SCHEMA", - (SQLWCHAR*)L"INFORMATION_SCHEMA", - (SQLWCHAR*)L"INFORMATION_SCHEMA", - (SQLWCHAR*)L"INFORMATION_SCHEMA", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys", - (SQLWCHAR*)L"sys.cache", - (SQLWCHAR*)L"sys.cache", - (SQLWCHAR*)L"sys.cache", - (SQLWCHAR*)L"sys.cache", - (SQLWCHAR*)L"$scratch"}; + const SQLWCHAR* schema_names[] = {static_cast(L"INFORMATION_SCHEMA"), + static_cast(L"INFORMATION_SCHEMA"), + static_cast(L"INFORMATION_SCHEMA"), + static_cast(L"INFORMATION_SCHEMA"), + static_cast(L"INFORMATION_SCHEMA"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys"), + static_cast(L"sys.cache"), + static_cast(L"sys.cache"), + static_cast(L"sys.cache"), + static_cast(L"sys.cache"), + static_cast(L"$scratch")}; std::wstring expected_system_table_type = std::wstring(L"SYSTEM_TABLE"); std::wstring expected_user_table_type = std::wstring(L"TABLE"); @@ -276,8 +274,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { this->CreateTestTables(); SQLWCHAR SQL_ALL_TABLES_W[] = L"%"; - SQLWCHAR* table_names[] = {(SQLWCHAR*)L"TestTable", (SQLWCHAR*)L"foreignTable", - (SQLWCHAR*)L"intTable", (SQLWCHAR*)L"sqlite_sequence"}; + const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), + static_cast(L"foreignTable"), + static_cast(L"intTable"), + static_cast(L"sqlite_sequence")}; std::wstring expected_catalog_name = std::wstring(L"main"); std::wstring expected_table_type = std::wstring(L"table"); @@ -303,8 +303,14 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { this->CreateTestTables(); - SQLWCHAR* table_names[] = {(SQLWCHAR*)L"TestTable", (SQLWCHAR*)L"foreignTable", - (SQLWCHAR*)L"intTable", (SQLWCHAR*)L"sqlite_sequence"}; + // Use mutable arrays to pass SQLWCHAR parameters to SQLTables + SQLWCHAR test_table[] = L"TestTable"; + SQLWCHAR foreign_table[] = L"foreignTable"; + SQLWCHAR int_table[] = L"intTable"; + SQLWCHAR sqlite_sequence[] = L"sqlite_sequence"; + + SQLWCHAR* table_names[] = {test_table, foreign_table, int_table, sqlite_sequence}; + std::wstring expected_catalog_name = std::wstring(L"main"); std::wstring expected_table_type = std::wstring(L"table"); @@ -370,8 +376,10 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { SQLWCHAR table_type_table_uppercase[] = L"TABLE"; SQLWCHAR table_type_view[] = L"VIEW"; SQLWCHAR table_type_table_view[] = L"TABLE,VIEW"; - SQLWCHAR* table_names[] = {(SQLWCHAR*)L"TestTable", (SQLWCHAR*)L"foreignTable", - (SQLWCHAR*)L"intTable", (SQLWCHAR*)L"sqlite_sequence"}; + const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), + static_cast(L"foreignTable"), + static_cast(L"intTable"), + static_cast(L"sqlite_sequence")}; std::wstring expected_catalog_name = std::wstring(L"main"); std::wstring expected_table_name = std::wstring(L"TestTable"); std::wstring expected_table_type = std::wstring(table_type_table_lowercase); @@ -413,7 +421,13 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { // Requires creation of user table named ODBCTest using schema $scratch in remote server - SQLWCHAR* type_list[] = {(SQLWCHAR*)L"TABLE", (SQLWCHAR*)L"TABLE,VIEW"}; + + // Use mutable arrays to pass SQLWCHAR parameters to SQLTables + SQLWCHAR table[] = L"TABLE"; + SQLWCHAR table_view[] = L"TABLE,VIEW"; + + SQLWCHAR* type_list[] = {table, table_view}; + std::wstring expected_schema_name = std::wstring(L"$scratch"); std::wstring expected_table_name = std::wstring(L"ODBCTest"); std::wstring expected_table_type = std::wstring(L"TABLE"); @@ -472,8 +486,9 @@ TEST_F(TablesMockTest, SQLTablesGetSupportedTableTypes) { TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { SQLWCHAR empty[] = L""; SQLWCHAR SQL_ALL_TABLE_TYPES_W[] = L"%"; - SQLWCHAR* type_lists[] = {(SQLWCHAR*)L"TABLE", (SQLWCHAR*)L"SYSTEM_TABLE", - (SQLWCHAR*)L"VIEW"}; + const SQLWCHAR* type_lists[] = {static_cast(L"TABLE"), + static_cast(L"SYSTEM_TABLE"), + static_cast(L"VIEW")}; ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); @@ -502,9 +517,11 @@ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"TABLE_CAT", (SQLWCHAR*)L"TABLE_SCHEM", - (SQLWCHAR*)L"TABLE_NAME", (SQLWCHAR*)L"TABLE_TYPE", - (SQLWCHAR*)L"REMARKS"}; + const SQLWCHAR* column_names[] = {static_cast(L"TABLE_CAT"), + static_cast(L"TABLE_SCHEM"), + static_cast(L"TABLE_NAME"), + static_cast(L"TABLE_TYPE"), + static_cast(L"REMARKS")}; SQLSMALLINT column_data_types[] = {SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; @@ -547,9 +564,11 @@ TYPED_TEST(TablesOdbcV2Test, SQLTablesGetMetadataBySQLDescribeColODBC2) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"TABLE_QUALIFIER", (SQLWCHAR*)L"TABLE_OWNER", - (SQLWCHAR*)L"TABLE_NAME", (SQLWCHAR*)L"TABLE_TYPE", - (SQLWCHAR*)L"REMARKS"}; + const SQLWCHAR* column_names[] = {static_cast(L"TABLE_QUALIFIER"), + static_cast(L"TABLE_OWNER"), + static_cast(L"TABLE_NAME"), + static_cast(L"TABLE_TYPE"), + static_cast(L"REMARKS")}; SQLSMALLINT column_data_types[] = {SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc index 0bd438e6ede8..9ed6c823af83 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc @@ -29,10 +29,7 @@ namespace arrow::flight::sql::odbc { using std::optional; template -class TypeInfoTest : public T { - public: - using List = std::list; -}; +class TypeInfoTest : public T {}; class TypeInfoMockTest : public FlightSQLODBCMockTestBase {}; using TestTypes = ::testing::Types; @@ -40,6 +37,9 @@ TYPED_TEST_SUITE(TypeInfoTest, TestTypes); class TypeInfoOdbcV2MockTest : public FlightSQLOdbcV2MockTestBase {}; +namespace { +// Helper Functions + void CheckSQLDescribeCol(SQLHSTMT stmt, const SQLUSMALLINT column_index, const std::wstring& expected_name, const SQLSMALLINT& expected_data_type, @@ -70,25 +70,25 @@ void CheckSQLDescribeCol(SQLHSTMT stmt, const SQLUSMALLINT column_index, } void CheckSQLDescribeColODBC2(SQLHSTMT stmt) { - SQLWCHAR* column_names[] = {(SQLWCHAR*)L"TYPE_NAME", - (SQLWCHAR*)L"DATA_TYPE", - (SQLWCHAR*)L"PRECISION", - (SQLWCHAR*)L"LITERAL_PREFIX", - (SQLWCHAR*)L"LITERAL_SUFFIX", - (SQLWCHAR*)L"CREATE_PARAMS", - (SQLWCHAR*)L"NULLABLE", - (SQLWCHAR*)L"CASE_SENSITIVE", - (SQLWCHAR*)L"SEARCHABLE", - (SQLWCHAR*)L"UNSIGNED_ATTRIBUTE", - (SQLWCHAR*)L"MONEY", - (SQLWCHAR*)L"AUTO_INCREMENT", - (SQLWCHAR*)L"LOCAL_TYPE_NAME", - (SQLWCHAR*)L"MINIMUM_SCALE", - (SQLWCHAR*)L"MAXIMUM_SCALE", - (SQLWCHAR*)L"SQL_DATA_TYPE", - (SQLWCHAR*)L"SQL_DATETIME_SUB", - (SQLWCHAR*)L"NUM_PREC_RADIX", - (SQLWCHAR*)L"INTERVAL_PRECISION"}; + const SQLWCHAR* column_names[] = {static_cast(L"TYPE_NAME"), + static_cast(L"DATA_TYPE"), + static_cast(L"PRECISION"), + static_cast(L"LITERAL_PREFIX"), + static_cast(L"LITERAL_SUFFIX"), + static_cast(L"CREATE_PARAMS"), + static_cast(L"NULLABLE"), + static_cast(L"CASE_SENSITIVE"), + static_cast(L"SEARCHABLE"), + static_cast(L"UNSIGNED_ATTRIBUTE"), + static_cast(L"MONEY"), + static_cast(L"AUTO_INCREMENT"), + static_cast(L"LOCAL_TYPE_NAME"), + static_cast(L"MINIMUM_SCALE"), + static_cast(L"MAXIMUM_SCALE"), + static_cast(L"SQL_DATA_TYPE"), + static_cast(L"SQL_DATETIME_SUB"), + static_cast(L"NUM_PREC_RADIX"), + static_cast(L"INTERVAL_PRECISION")}; SQLSMALLINT column_data_types[] = { SQL_WVARCHAR, SQL_SMALLINT, SQL_INTEGER, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, @@ -112,17 +112,25 @@ void CheckSQLDescribeColODBC2(SQLHSTMT stmt) { } void CheckSQLDescribeColODBC3(SQLHSTMT stmt) { - SQLWCHAR* column_names[] = { - (SQLWCHAR*)L"TYPE_NAME", (SQLWCHAR*)L"DATA_TYPE", - (SQLWCHAR*)L"COLUMN_SIZE", (SQLWCHAR*)L"LITERAL_PREFIX", - (SQLWCHAR*)L"LITERAL_SUFFIX", (SQLWCHAR*)L"CREATE_PARAMS", - (SQLWCHAR*)L"NULLABLE", (SQLWCHAR*)L"CASE_SENSITIVE", - (SQLWCHAR*)L"SEARCHABLE", (SQLWCHAR*)L"UNSIGNED_ATTRIBUTE", - (SQLWCHAR*)L"FIXED_PREC_SCALE", (SQLWCHAR*)L"AUTO_UNIQUE_VALUE", - (SQLWCHAR*)L"LOCAL_TYPE_NAME", (SQLWCHAR*)L"MINIMUM_SCALE", - (SQLWCHAR*)L"MAXIMUM_SCALE", (SQLWCHAR*)L"SQL_DATA_TYPE", - (SQLWCHAR*)L"SQL_DATETIME_SUB", (SQLWCHAR*)L"NUM_PREC_RADIX", - (SQLWCHAR*)L"INTERVAL_PRECISION"}; + const SQLWCHAR* column_names[] = {static_cast(L"TYPE_NAME"), + static_cast(L"DATA_TYPE"), + static_cast(L"COLUMN_SIZE"), + static_cast(L"LITERAL_PREFIX"), + static_cast(L"LITERAL_SUFFIX"), + static_cast(L"CREATE_PARAMS"), + static_cast(L"NULLABLE"), + static_cast(L"CASE_SENSITIVE"), + static_cast(L"SEARCHABLE"), + static_cast(L"UNSIGNED_ATTRIBUTE"), + static_cast(L"FIXED_PREC_SCALE"), + static_cast(L"AUTO_UNIQUE_VALUE"), + static_cast(L"LOCAL_TYPE_NAME"), + static_cast(L"MINIMUM_SCALE"), + static_cast(L"MAXIMUM_SCALE"), + static_cast(L"SQL_DATA_TYPE"), + static_cast(L"SQL_DATETIME_SUB"), + static_cast(L"NUM_PREC_RADIX"), + static_cast(L"INTERVAL_PRECISION")}; SQLSMALLINT column_data_types[] = { SQL_WVARCHAR, SQL_SMALLINT, SQL_INTEGER, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, SQL_SMALLINT, @@ -195,6 +203,7 @@ void CheckSQLGetTypeInfo( CheckIntColumn(stmt, 18, expected_num_prec_radix); // num prec radix CheckIntColumn(stmt, 19, expected_interval_prec); // interval prec } +} // namespace TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(this->stmt, SQL_ALL_TYPES));