From 8a462e4a2c48e0dd8ef9cdec1f5cc4d6009aabd8 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 30 Mar 2026 16:01:02 -0700 Subject: [PATCH 01/17] Add Arrow Flight SQL ODBC driver Co-authored-by: alinalibq Co-authored-by: justing-bq Co-authored-by: vic-tsang ODBC commits squashed into 1 to make rebasing to main easier. Add initial framework for odbc dll - Add ARROW_FLIGHT_SQL_ODBC option. If we set `ARROW_FLIGHT_SQL_ODBC=ON`, the flightsql odbc folder will be built - Add odbc api layer for entry_point.cc - builds odbc dll file, with ODBC APIs exported in odbc.def Address James' comments Fix `odbcabstraction` build errors and partially fix `flightsql_odbc` errors Fix boost-variant not found error - Adding dependencies from odbc/vcpkg.json to cpp/vcpkg.json - Fix whereami.cc and .h dependency; ported lates code Update whereami.cc - use `long` instead of `int64`. Fixed namespace issues. - PR CI fix: Add `parquet-testing` back Partial build fix for `flight_sql` folder - Replaced `namespace arrow` and `namespace odbcabstraction` with `using namespace ...` - fix flight_sql_connection.cc Fix `util::nullopt` to use `std::nullopt` - fix std::optional - fix BufferReader - Fix GetSchema - fix json_converter.cc - partial fix configuration.h - partial fix get_info_cache.cc - Fix winsock build error - Comment out `flight_sql` files that cannot build - Comment out configuration and unit tests - Comment out get info cache and system trust store Create initial odbc tests folder Implement SQLAllocEnv Fix cmake build Implement SQLFreeEnv Fix rest of build errors from `flightsql-odbc` - Fix get info errors - Fix for configuration window - added odbcinst library - Fix system trust store - unit test fixes - Add dependency of ARROW_COMPUTE. `arrow/compute/api.h` is used in `flight_sql`. Adding `ARROW_COMPUTE=ON` during build fixed run time unit tests failures. Implement SQLAllocConnect and SQLFreeConnect Fix build issue from static flight sql driver Lint and code style fixes Re-add deleted submodule parquet-testing clang-format lint fix cpplint lint fix Exclude whereami in rat exclude list C++/CLI lint fix Update parquet-testing to match commit from `main` Address Kou's comments ODBC directory lint fixes Catching the lint fixes outside of `flightsql-odbc` code Fix build warnings that get treated as error Implement SQLSetEnvAttr and SQLGetEnvAttr Implement use of ExecuteWithDiagnostics Doxygen Error Fixes and Address comments from Kou and James Address comments from Kou - Updates License.txt - Update cmake toolchain - Move whereami to `vendored` - Use string_view instead of NOLINT std::string Remove `whereami.cc` from arrow util build We are building whereami.cc as part of odbc Fix include headers to replace <> with "" Address comments from James Implement SQLGetDiagField SQLDriverConnect, SQLConnect and SQLDisconnect Implement stubs for SQLGetInfo, SQLGetDiagField and SQLGetDiagRec Separate RegisterDsn and UnregisterDsn from windows build Update code to save driver value from connection string Add ReadMes for ODBC and tests Fix test issues with string_view Address code reviews Update entry_points.cc to fix build issue Remove Dremio references Use emplace properly Address comment from Rob and add SQLDisconnect test case Add odbc.def and cmd file to rat_exclude Nit - remove duplicate lines Accidentally committed the change during git rebase Nit - remove usage of nullptr DSN window implementation Add licenses to `.cmd` and `.def` files Implement SQLGetDiagRec Build ODBC in Windows Workflow Tests are skipped for now. Updates for SQLGetDiagFieldW Enable Driver Logging Add todo to update logging system later Add logs Implement ODBC API with debug logging Enable mock test * Add todo for noauth validation * mock server with token auth Add tests * run same test with both modes * Enable ODBC tests in workflow * Switch current test cases to use FlightSQLODBCTestBase So the tests can be skipped when `TEST_CONNECT_STR` is not set. * Change tests to run on both mock and remote modes Wrap usage of TEST_CONNECT_STR where possible * Rename test fixtures and make connection string functions virtual * Fix lint issue * Attempt to enable ODBC build on Windows platforms * Attempt to fix clang64 and MinGW errors * Attempt to register ODBC * Address James' comments Use constant string for token * use ServerMiddleware to validate token Fix connection issues to DBT Labs PopulateCallOptions before making a connection Fix dsn window bug with advance properties Fix seg fault issue from empty string Implement SQLAllocStmt Follow-up DBT Labs connection fix Implement SQLGetDiag Rec and Field for statement Unicode support for DSN ODBC APIs * Let compiler append `W` to ODBC APIs where applicable. Initialize Kernel functions As per changes from #46261, we need to initialize Kernel library explicitly to get the functions registered Implement SQLSetConnectAttr and SQLGetConnectAttr ODBC Test Segfault Fix * Move `connection_test.cc` to last in `CMakeLists.txt`, this resolves the seg fault. The seg fault was not reproducible on my local environment, even when I use the msys2 shell. * Rename test executable to flight_sql_odbc_test SQLExecDirect implementation * SQLGetStmtAttr stub implementation * Fix missing break statement in SQLGetDiagRec * Run ShutdownProtobufLibrary as part of test environment * Add comment for GH-46889 * Pass call options to executed prepared statement `call_options_` contains the authentication token which is needed Implement SQLGetInfo SQLGetInfo Workflow Fixes SQLFetch & SQLGetData Implementation SQLGetStmtAttr stub implementation Stub call for SQLGetStmtAttr Enable statement handle allocation Implement SQLExecDirect - test hang issue Update odbc_api.cc Run `ShutdownProtobufLibrary` after all ODBC tests Resolves test hanging problem Fix missing break statement in SQLGetDiagRec Add tests Lint fixes Run ShutdownProtobufLibrary as part of test environment Add debug messages Draft code Remove drafts Add comment Add comment for GH-46889 Update statement test headers Pass call options to executed prepared statement `call_options_` contains the authentication token which is needed SQLFetch & SQLGetData initial impl EVERYTHING before this commit is for SQLExecDirect SQLFetch and SQLGetData TestSQLExecDirectSimpleQuery test Make GetData() return SQLRETURN `TestSQLExecDirectDataQuery` for remote and mock servers Remove unneeded test case Add more data types * Add SQL_GUID in getCTypeForSQLType * Add data types in query * Add checks for columns 1 to 25 * Update statement_test.cc Add varbinary test * Implement SQLNumResultCols Will leave tests for later * Implement SQLRowCount * Implement SQLMoreResults * Work on date retrieval fix The `TestSQLExecDirectDataQuery` checks for date is not working. * Fix date retrieval error by importing fix from Paul * imported fix from https://github.com/dremio/flightsql-odbc/commit/d44d862bd07f05328f5fcfd68a8f40357aa072fa, an Apache-Licensed repository * Add more checks for get data * Add more tests * Continue work on float truncation test * Disable float truncation test * Address comments from James - do not return errors for invalid rowCountPtr and columnCountPtr - add static cast for columnCount - Add tests with SQL_C_DEFAULT as target type - Add test checks for indicator - Fix SQL_NUMERIC, SQL_BIT, SQL_FLOAT target type * Fix build issues in CI * More fix for CI * Add test for invalid buffer length SQLPrepare & SQLExecute Implementation * Add tests * Address comments from Rob Code Style fixes * Move ifdefs outside of test cases * use `stmt` * Move logs to first line * fix test for `SQL_DRIVER_HSTMT` * Use camel case for tests Implement SQLGetStmtAttr and SQLSetStmtAttr SQLBindCol Implementation * SQL_UNBIND implementation + tests * Add tests for `SQL_ATTR_ROW_ARRAY_SIZE` * Add check for `SQL_ATTR_ROWS_FETCHED_PTR` Enable TestCloseConnectionWithOpenStatement test case SQLFetchScroll Implementation * Add checks for SQL_ATTR_ROWS_FETCHED_PTR * SQLFetchScroll is supposed to return the number of rows fetched using SQL_ATTR_ROWS_FETCHED_PTR SQLExtendedFetch Implementation * Implement rowCountPtr and rowStatusArray for SQLExtendedFetch * Add tests for SQLExtendedFetch * `SQLExtendedFetch` doesn't return `SQL_SUCCESS_WITH_INFO` for error state 22002. * Add tests for `SQL_ROWSET_SIZE` * Address comments from James GH-46584 Iterate endpoint * use suggestion from James for one-liner change to return `Status::OK` directly * fix for iterating endpoints, it is based on JDBC's fix for the same bug * save value of `FlightClientOptions` * Use `TestFlightServer` Add `arrow_flight_sql_shared` to enable usages for `TestFlightServer` * Fix build errors from missing `gmock` * Add checks for array data Update flight_sql_stream_chunk_buffer_test.cc Add `FlightStreamChunkBufferTest` unit test Draft test with `FlightSQLODBCMockEndpointTestBase` * Reference GH-47117 and Clean up code * Add driver and DSN to built-in properties to not pass driver/dsn as attributes to server * Allow `=` in values inside connection strings, fixes connectivity problems * Address comments from Rob SQLColumns Implementation * Initial impl for SQLColumns * Add test for SQLColumns * Add columns test with all supported column types - mock server doesn't support schema * Address comments from James - Test different data type return value for SQLColumns - Add todo comment for SQLDescribeCol tests --------- Co-authored-by: rscales Fix bug of DSN not read properly * Fix reading DSN bug Use a simpler, more robust way to load the DSN SQLColAttribute implementation * SQLColAttribute initial impl * Switch to use `GetAttributeSQLWCHAR` to be unicode-compatible * Add SQLColAttribute tests and fix bugs in `flightsql-odbc` impl * Fixed bug with incorrect column count. It was returning column count + 1. * Fixed bug with incorrect numPrecRadix. It was returning SQL_NO_TOTAL (maps to -4) for non-numeric columns, but the correct value is 0. * Fixed bug with unsigned column to return true for unsigned columns (non-numeric columns or unsigned numeric columns) and false for signed columns (numeric columns) * Fixed bug with incorrect non-concise data type return value for date time type types. The correct return is SQL_DATETIME for all date time types * Address comments from James * use const for `ConvertToWString` * add nullptr check in odbc_api.cc layer * Add support for `SQL_COLUMN_LENGTH`, `SQL_COLUMN_PRECISION`, and `SQL_COLUMN_SCALE`. The driver will return the same values for ODBC2 and ODBC3. * Add tests for ODBC v2 SQLColAttributes values * I converted tests that can be run on remote servers where possible * Address comment from Rob Implement SQLTables Use C++ 20 standard for ODBC * Add support for building with C++20 * Upgrade spdlogs version as an attempt to fix build issues * Fix issue of missing unique_ptr definition Add tests for SQLMoreResults Implement SQLNativeSql Add diagnostic records * remove `SQLErrors`, as the driver manager is supposed to map `SQLErrors` to `SQLGetDiagRec` Implement tests for SQLNumResultCols SQLCloseCursor Implementation * fix error state to return the correct state 24000. * add tests for SQLCloseCursor and SQLFreeStmt(SQL_CLOSE) Add SQLColumns and SQLColAttribute tests with nullptr * Modify SQLTables test to run on both mock and remote * reorder error msg alphabetically Implement tests for SQLRowCount Fix merge conflicts Adjust searchable return value based on GH-46920 fix Fix `getCTypeForSQLType` return for interval types - Fix `getCTypeForSQLType` function to return the correct `C type` for interval SQL data types. Previously the function was checking for interval `C type` and returning interval `SQL type`, which was the opposite of the intended functionality. SQLGetTypeInfo implementation * Add tests for SQLGetTypeInfo * fix bug of createParams returning empty string instead of null * fix bug of non-concise data type being returned for datetime/interval * fix bug of longvarchar not converted to wlongvarchar when driver has unicode enabled * Address comments from James and add checks * test SQL_ALL_TYPES in ODBC 2.x. * test SQL_TYPE_* in ODBC 2.x, the driver manager reports invalid data type error. * test SQL_* datetime in ODBC 3.x for backwards compatibility. * add check for valid/invalid data type. Fix segfault issue from empty metadata * Use empty map in bug fix * Address comments from James Implement SQLDescribeCol Add SQLError Tests * add test to free null handles. Without handle value initialization, segfault error was seen Move `SQLGetDiagField` and `SQLGetDiagRec` tests to `errors_test.cc` * Address comments from James * Add ODBC Ver 2 tests * update test name to indicate if error handling is from driver manager. * add tests for warnings. * fix lint errors. * remove SQL_ATTR_APP_ROW_DESC that is not applicable to Environment Attribute. Add tests for SQLGetFunctions * Using `SQL_FUNC_EXISTS` macro fixed the issue of `api_exists` not read correctly * Fix SQLGetTypeInfo naming for ODBC ver 2 tests * Add more tests Add unsupported API checks. Add `TestSQLGetFunctionsODBCVer2`. Add `TestSQLGetFunctionsCheckSingleAPI`. * Update reset value * Add SQLDescribeCol function check Add additional SQLDescribeCol test cases Add Descriptor support in SQLAllocHandle and SQLFreeHandle * Descriptor allocation initial impl * Add descriptor handle tests * Add diagnostic error test for descriptor handle * the error is from driver manager as our driver doesn't have descriptor-specific APIs implemented yet * Add SQLGetDescField test from driver manager * Add doxygen doc comment Fix connection issues servers that require data in handshake * revert back to passing empty string in handshake Fix bug of system trust store not loaded properly * Bug: system trust store has default value of "true" regardless of "encryption" value. * But if encryption is set to false, system trust store cannot be used, so system trust store should be saved as false if user does not enable encryption. * It may confuse the user if they see encryption is set to false but system trust store is set to true. In this case, the driver will not do system trust store verification. The DSN window should reflect this accurately. CPack ODBC Windows msi installer Add ARROW_FLIGHT_SQL_ODBC_INSTALLER environment variable to enable creation of Windows installer. * Use CPack + WiX to create a `msi` installer. * run command `cpack` under the build directory to generate the installer. Register ODBC Driver on Windows in installer * In `wxs`, cannot use `package`, need to use `fragment` instead * Use component as feature will automatically be generated * Set Patch version + add installer instructions Use Arrow logo banner * replaces default banner with Arrow logo banner Indicate Driver Company and Version on Driver Manager * use versioninfo.rc.in template * use `1 VERSIONINFO` for it to work properly * Set version variables * Add `.rc` to gitignore * Add `@` variables to rc template Return nameLengthPtr value as length in characters Allow spaces while parsing Table Type mac changes added changes to build in MacOS Enable ODBC build on Windows Glib & Ruby workflows * Fix `boost::get` issue on GLib workflow * Fix GLib build issue with conflicts Compile entry_points.cc before odbc_api.cc due to conflict from sql.h and flight/types.h. Fix build warnings treated as error on Windows SQLDescribeCol expects `bufCharLen` to be of type `SQLSMALLINT`, so build warnings occur when `bufCharLen` is set to `SQLINTEGER`. Add more types for Array Conversion Set column attribute SQL_DESC_TYPE_NAME [Refactor] Remove reference of `Configuration` in odbc_connection.cc Remove reference of `Configuration` in odbc_connection.cc which is in library `odbcabstraction`. The reasoning is that `Configuration` is in `arrow_odbc_spi_impl` and this is a library that `odbcabstraction` depends on. I moved the logic for reading DSN values into `odbc_api.cc` instead, since that is a place that will result in no conflicts. The ODBC driver now does not save the DSN value in the connection string if the DSN value is put after Driver value. * Address comments from James Simply logic to check for first key value pair only Add TODO for non-UTC time zone support * Currently, the driver only supports UTC time zone Replace `spdlogs` with Arrow's Internal Logging * Add logging README * register kernel function conditionally * Resolves errors of kernel function already registered Logging files are not supported since GLOG is not enabled on Windows in Arrow repo. We can work + test on log file support on macOS/Linux phase Remove `RUN_ALL_TESTS` as they are not needed Previously, tests on Windows were not being run due to https://github.com/apache/arrow/issues/47434. So we added `RUN_ALL_TESTS` as a workaround in early May, before https://github.com/apache/arrow/issues/47434 was raised. Now that https://github.com/apache/arrow/issues/47434 is resolved, we can remove `RUN_ALL_TESTS` as they are not needed. Other changes: * Renamed `arrow_odbc_spi_impl_test` to `odbc_spi_impl_test` so the test executable will be `arrow_odbc_spi_impl_test.exe` instead of `arrow_arrow_odbc_spi_impl_test.exe` Fix Function & Variable Naming Fix member variable naming Address code review comments for Arrow#40939 * Reword comment on null check Addresses comment https://github.com/apache/arrow/pull/40939#discussion_r2099120394 * Use `std::memcpy` instead of `memcpy` Addresses comment https://github.com/apache/arrow/pull/40939#discussion_r2099120764 * add include cstring * Remove warpdrive mentions * Fix lint * Address Justin's comments Combine utils and define utils namespace Use arrow::flight::sql::odbc namespace Update namespaces driver::flight_sql and driver::odbcabstraction to arrow::flight::sql::odbc. Fix seg fault from register log PR to keep apache-odbc in sync with arrow main branch. I found that, if the driver registers logs before compute kernel registration, segfault somehow occurs at when register kernel function is being used. I am not sure the root cause, but registering the logs after compute kernel registration seems to resolve the issue. Refactor odbcabstraction and odbc_impl flight_sql is renamed to odbc_impl. The files inside odbcabstraction have been moved to odbc_impl and odbcabstraction is removed. Replace boost::variant with std::variant * Remove `boost-optional` and `boost-variant` dependencies from vcpkg.json * Replace boost::variant with std::variant Fix EXPECT_EQ() to have expected on the left and actual on the right Code style naming convention Remove underscores in test names Sync arrow_flight_testing changes from Arrow::main branch Fix test failure due to typo Fix `FlightSQLODBCRemoteTestBase.TestSQLExecDirectDataQueryDefaultType` test failure due to typo The precision should be 38 in the original code. I think it got changed to 0 by accident somewhere. Disable tests with `DISABLED_` * Enable `TestSQLGetInfoDriverHdesc` We missed this test before, enabling the test now * Disable tests with `DISABLED_` Fix test assertions Define Test Fixtures * Connect/disconnect in SetUp/TearDown * Define Test Fixtures Resolve ODBC CI Build Errors * Fix `ConfigDSNW` not found error * Fix `TestFreeNullHandles` test `ConnectionTest` sets up the handles, so the `this->...` handles will not be null at beginning of test. Define New Base Test Fixtures Skip tests without connecting/disconnecting Address general test code review comments * Use RAII helper for allocating and freeing env/conn handles Avoids duplicated code Move test helper functions to anonymous namespace Add `[[nodiscard]]` for ODBC APIs Addresses community comment: https://github.com/apache/arrow/pull/47763/files#r2450014186 Remove `using List=` in test suite definitions Use static_cast for `SQLWCHAR` in type info test Use static_cast for `SQLWCHAR` in tables test * use mutable arrays for places where characters cannot be const Use static_cast for `SQLWCHAR` in columns test Update comment Use static_cast for `SQLWCHAR` in SQLGetInfo test * Address Justin's comments * Add fix for skipping the allocation of handles Enable ODBC build in MacOS CI ODBC Standalone MSVC Build CI Remove DataSet Fix cache key Use odbc-specific cache key Fix Lint and Add odbc registration step Link appropriate GitHub issues that blocks ODBC tests Disable test phase and add schedule Run everyday 7 am Vancouver time Enable ODBC build on MSVC CI Code Clean up and enable ODBC tests in CI Still need to modify ODBCUtilEnvironment if we decide to use it. Still need to add ODBC V2 support so a different env and conn is used for ODBC 2 tests. Draft enable ODBC global setup/teardown Run ODBC test once outside of test script If ODBC test is run using MinGW Shell, segfault occurs. I am not getting any seg fault on my local MSVC Windows when I run the tests without the bash script. But if Windows CI breaks from running the standalone exe then I will look into this Prepend vcpkg to search vcpkg before `/lib/cmake` Since we are installing dependencies on vcpkg, if `lib/cmake` is searched first, then cmake will look into that directory and use the wrong paths. Convert VCPKG Windows path to MSYS path Set `VCPKG_ROOT` in test phase Fix ODBC dll name Use `arrow_flight_sql_odbc.dll` instead of `libarrow_flight_sql_odbc.dll` which is the naming convention used on MinGW Windows Link ODBC library on all platforms On my local MSVC Windows machine, Visual Studio is used to build without needing to link ` ${ODBCINST}` explicitly, its behavior might be different from Ninja which is what CI uses. `${ODBCINST}` is likely needed by Linux as well, so adding it for all platforms. Attempt to resolve `arrow-compute-grouper-benchmark` build issue I think `if(ARROW_FLIGHT_TEST_LINKAGE STREQUAL "static")` might be more appropriate here, as I am seeing build issues due to both dynamic and static linking occurring. I see in https://github.com/apache/arrow/commit/59903d089ec5b1766e1622d94c1f618b539b205d, this check is used for `arrow-filesystem-s3fs-benchmark` Disable `UNITY_BUILD` for ODBC test due to conflict on `sqlite_sql_info.cc` On some workflows, unity build is set to ON to make the build faster. This is an attempt to resolve the build issue. Remove debug messages Fix lint Add `sql_info_undef.h` to sqlite_sql_info.cc Undefine duplicates in SQLGetInfo Add `#pragma once` to odbc_test_suite.h To avoid redefinition error Attempt to resolve conflict with sql/types.h Attempt to include Arrow headers before ODBC headers to avoid conflict with arrow/flight/sql/types.h [GH-48084] Replace boost::optional with std::optional Addresses comment https://github.com/apache/arrow/pull/40939#discussion_r2099118497 Replace boost::optional with std::optional in ODBC codebase https://github.com/apache/arrow/issues/48084 Fix lint Remove `BOOST_SOURCE=BUNDLED` to use vcpkg's dynamic link to boost Since we need to use link to boost dynamically, we need to remove the bundled boost library flag. Add debug messages. Remove `ARROW_BOOST_USE_SHARED = OFF` Since we have a release build, can enable boost as shared. With `ARROW_BOOST_USE_SHARED = OFF`, I am getting error ``` D:\a\arrow\arrow\build\cpp\vcpkg_installed\x64-windows\include\boost/filesystem/config.hpp(96): fatal error C1189: #error: Must not define both BOOST_FILESYSTEM_DYN_LINK and BOOST_FILESYSTEM_STATIC_LINK ``` Also increased time limit, since 2 hours don't seem to be enough to finish the vcpkg build Change to release build Getting ``` orc.lib(Exceptions.cc.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in unity_2_cxx.cxx.obj orc.lib(Exceptions.cc.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in unity_2_cxx.cxx.obj ``` when building with debug and presumably ARROW_ORC Set ARROW_BOOST_USE_SHARED to OFF `ARROW_BOOST_USE_SHARED` is restored to `OFF`, which according to Windows doc should help with the debug build now. Retore value of `ARROW_BUILD_BENCHMARKS`, though noting it is set to `OFF` in GLib MSVC workflow. Add VCPKG set up Borrowed from the Glib workflow Add `/EHsc` flag * Add back `CMAKE_CXX_STANDARD: "17"` Remove `CMAKE_CXX_STANDARD` 17 * reason: gtest can't be used with C++17. Arrow project doesn't support C++ 17 yet. Extend run-time to 2hr windows-mingw also has timeout of 2hr Empty commit to trigger CI Specify `VCPKG_BINARY_SOURCES` and `VCPKG_DEFAULT_TRIPLET` Specify VCPKG_TARGET_TRIPLET as x64 windows Set ARROW_DEPENDENCY_SOURCE to VCPKG To make it easier to manage dependencies Enable static build on MSVC `ARROW_BUILD_BENCHMARKS` prevents Flight from being built Remove `ARROW_BOOST_USE_SHARED` Having static vs. shared issue Enable Flight & Flight SQL for ODBC Enable ODBC build on MSVC CI Enable regular ctest tests Remove undef items Add concurrency and permissions to odbc yml Create cpp_odbc.yml Fix architecture in CI * Add ODBC installer MSVC CI Mac Setup ODBC ini Script * added setup script for mac and platform folders updated read me windows file path updated windows folder related file paths added license Fix Lint issues Add install ODBC script Update install_odbc_ini.sh This script depends on the ODBC install script. Add TODO note and update DSN * Fix typo in README --------- Fix lint Fix lint Update flight_sql_stream_chunk_buffer.cc Update statement_test.cc Move MacOS ODBC workflows to cpp_odbc.yml Fix Lint Fix `ODBC::GetSqlWCharSize()` Add back missing checks for error handle tests SQLError implementation in macOS * SQLError implementation for macOS Disable `SQLGetConnectOption` on macOS. Still need to check if SQLGetConnectOption is needed on macOS Excel. Update type_info_test.cc Update columns_test.cc Remove unneeded component code - Removed unneeded code for `COMPONENT` - Use `install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}` to include MSVC redistributable DLLs instead of picking them up with `unspecified` components. - Use better way to include ODBC dll files: replace DLL filtering with `install(TARGETS` Fix deadlock error from C++ 20 * Fix ODBC deadlock issue `absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);` fixes ODBC deadlock issue. We turn off the detection as the deadlock originated from upstream projects. * Fix ODBC Extra slow CI issue Attempt to resolve caching issue with ODBC CI Add write permission to store vcpkg cache Check nuget paths in Ruby Glib and ODBC Run vcpkg install after vcpkg is set in GLib Enable vcpkg verbose in GLib * confirmed `vcpkg install` command returns 403 error Add ARROW_HOME Remove `ARROW_SIMD_LEVEL` as it is not required for ODBC. Remove debug msgs Cannot get vcpkg in cpp_build to show debug messages Move location of `packages: write` Attempt to add `ARROW_DEPENDENCY_USE_SHARED - off` Revert "Move location of `packages: write`" This reverts commit b62e04ed6d88296217bd8ed05d67ee2fb0b927c2. Revert "Attempt to add `ARROW_DEPENDENCY_USE_SHARED - off`" This reverts commit 5fdf4251df18a4f2c1b7c697f99fe91ef6e1b9aa. Add GLib MSVC build to C++ Extra TEMP disable ODBC build Disable cmake and enable build Re-enable cmake 4.1.2 and use install_vcpkg.sh to install vcpkg Clean up test changes Push after previous run is complete. Revert "Re-enable cmake 4.1.2 and use install_vcpkg.sh to install vcpkg" This reverts commit dfea3774de18f764ee6bcba8293d347e4e358813. Trigger CI Apply Kou's suggestion for nuget timeout Remove `C++ ODBC` workflow * missed item from rebase Remove changes added from rebase Co-Authored-By: Victor Tsang Co-Authored-By: Alina (Xi) Li Co-Authored-By: vic-tsang Build ODBC statically on macOS * Link ODBC library statically on unix Change unit tests to re-use code. Testing on windows is needed. Now seeing error ``` Library not loaded: /usr/local/opt/grpc/lib/libgrpc++.1.76.dylib ``` on Excel. Attempt to unlink arrow_flight.proto Now I see ODBC.dylib has 100MB, and error from Excel is ``` Library not loaded: /usr/local/opt/libiodbc/lib/libiodbc.2.dylib ``` instead of looking for flightsql. `iodbctest` command outside of Excel works. in-progress link arrow statically for `flightsql-odbc` * both ODBC driver and `arrow_odbc_spi_impl` need to link Arrow statically for tests to work. * getting error `File already exists in database: Flight.proto` since the ODBC layer is linking dynamically while I successfully got `arrow_odbc_spi_impl` to link to Arrow statically Draft for resolving `File already exists in database: FlightSql.proto` error Note: make ODBC available on Excel first, test with `iodbctest`, worry about ODBC test executable later. Add unix build (same as Windows build) * Attempted to link static libraries with `arrow_odbc_spi_impl`, failed as it caused linking errors and rendered the ODBC driver unusable. Undo changes to resolve broken driver Resolves dependency errors Attempt to switch to static build Still getting error ``` [iODBC][Driver Manager]dlopen(/Library/ODBC/arrow-odbc/libarrow_flight_sql_odbc.2300.0.0.dylib, 0x0006): Library not loaded: @rpath/libarrow_flight_sql.2300.dylib ``` In-progress attempt to build ODBC statically on unix systems In-progress changes to enable static odbc_impl library pushing the changes just for saving my code. Currently odbc test still has double registration issue, work on this next. I think it should be solvable by either adding library flags or just using odbc spi shared. Because `odbc_spi_impl_test` works. And the ODBC tests worked just fine before I switched to static odbc spi impl. Fix for gtest missing issue Attempting to fix for issue: IMPORTANT NOTICE - DO NOT IGNORE: This test program did NOT call testing::InitGoogleTest() before calling RUN_ALL_TESTS(). This is INVALID. Soon Google Test will start to enforce the valid usage. Please fix it ASAP, or IT WILL START TO FAIL. Issue fixed with adding `${ARROW_TEST_LINK_LIBS}`. It is needed alongside `arrow_flight_testing_shared`. IN-PROGRESS build static test on macOS * Trying to have 2 builds. One `arrow_odbc_spi_impl_static` for static build and one `arrow_odbc_spi_impl_shared` for a shared lib that links Arrow dynamically --- only committing the approach that worked. Trying to work from `flight_sql_odbc_test` to debug the real issue. Link 3rd party dependencies statically Fix 3rd party headers cannot find issue for: - boost xpressive and beast headers - rapidjson headers Resolve unneeded link for ODBC ---- Moving `set(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a")` up didn't seem to have any effect ---- Fix for static gRPC connection issue: export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=/etc/ssl/cert.pem Fix cares `cannot modify alias target` issue Make arrow_odbc_spi_impl static lib In progress for getting gprc linked statically Add debug msgs in add_arrow_lib BuildUtils.cmake Remove commented out code in odbc lib Fix build issue from odbc impl tests Added draft code for Link Arrow libs statically on Unix for unit tests Add commented out code`ARROW_DEPENDENCY_USE_SHARED` in ODBC cpp yml Uncomment when it is verified to work. In-progress Fix ODBC test build and make it run. Build executable from scratch Revert "Build executable from scratch" This reverts commit a51dc395d69c50b42090f50c22cdc9247d3baf9f. Dummy test dummy test without using ODBC passed without double registration issue Make ODBC test run Issue to resolve: [libprotobuf FATAL /path/to/arrow/cpp/debug-build/_deps/protobuf-src/src/google/protobuf/extension_set.cc:100] Multiple extension registrations for type "google.protobuf.MessageOptions", field number 1000. unknown file: Failure C++ exception with description "Multiple extension registrations for type "google.protobuf.MessageOptions", field number 1000." thrown in SetUp(). Fix: only link test executable directly with ODBC shared dylib. Do not link test executable with odbc spi impl dylib. And change ODBC to link odbc spi impl dylib publicly instead of privately in-progress changes to accomodate macos CI Test ODBC CI - to be reverted Can revert later Only install ODBC dependencies in mac As dependencies are static and built from source Uninstall absl as attempt to resolve build on Intel Add C++ standard 20 Remove absl header from intel Use static linking in dependency install step Use bundled boost for static linking In-progress Fix Windows build Fix macOS (after Windows build) Remove unneeded ODBC link Resolves the issue of ODBC on macOS being dynamically linked to ODBC Fix ODBC double proto issue on macOS Need to check if Windows CI passes Clean up PR - Remove dummy tests - Remove unneeded changes Revert "Test ODBC CI - to be reverted" This reverts commit 711b3e0863ebbf5fe2c5cb1401fbaf72eed58aa4. Remove unneeded code Attempt to revert c-ares change Fix `set_target_properties can not be used on an ALIAS target.` error. Example of failed run in forked repo: https://github.com/Bit-Quill/arrow/actions/runs/21459770235/job/61809740997?pr=153#step:7:540 Fix descriptor pointer tests on static macOS Fix mimalloc issue Fixes issue: ``` mimalloc: assertion failed: at "arrow/cpp/debug-build/mimalloc_ep-prefix/src/mimalloc_ep/include/mimalloc/internal.h":658, _mi_ptr_page assertion: "p==NULL || mi_is_in_heap_region(p)" zsh: abort debug/arrow-flight-sql-odbc-test ``` Enable ODBC tests for static build Add iodbc link to macOS build on ODBC layer Add iodbc link to macOS build on ODBC Test Add iodbc link to macOS build on ODBC layer did not resolve issue of unixodbc being picked in CI * Fix segfault at SQLError * work on Justin's comments Fix rebase conflicts Remove code added during conflict resolution Implement system_dsn for Mac Address community comments for `install_odbc_ini.sh` Add separate release & debug workflows for MacOS Disable DSN default values on macOS * Remove DSN default values on macOS * Work on Justin's comment Refactor test setup/teardown to reuse connection across tests * Define Mock Server SetUp/TearDown at Environment level * Refactor test setup/teardown to reuse connection across tests * In-progress fix DSN write issue on macOS without `sudo` * Getting errors of `SQLSetConfigMode` flagged as `void`, ``` error: cannot initialize return object of type 'bool' with an rvalue of type 'void' 502 | ASSERT_TRUE(SQLSetConfigMode(ODBC_BOTH_DSN)); ``` * Clean Up PR * Remove unneeded changes --------- Fix rebase errors Change `GetInfo` disabled tests to start new connection * Enable disabled tests * Fix getinfo tests to use standalone connection Windows CI to Support ODBC DLL & MSI Signing * Add draft code for CI A and CI B Attempt workflow dispatch Only ODBC Windows original workflow should run. Later need to add `github.event_name != 'workflow_dispatch' ||` to all existing workflows after uncomment Use `GITHUB_REF_NAME` directly via push Add `workflow_dispatch` definitions Add `ODBC Windows Upload DLL` Use common ODBC Windows environment variables Use ODBC as composite action Create cpp_odbc.yml Initial draft temp disable test step Temp disable non-ODBC Windows workflows * Clean Up Code * Remove comments * Fix Installer path for MSI Fix issue with `secrets.GITHUB_TOKEN` Co-Authored-By: Alina (Xi) Li --- .github/actions/odbc-windows/action.yml | 95 ++++++ .github/workflows/cpp_extra.yml | 276 ++++++++++-------- .gitignore | 1 + ci/docker/debian-13-cpp.dockerfile | 2 + compose.yaml | 49 ++++ cpp/cmake_modules/ThirdpartyToolchain.cmake | 95 +++--- cpp/src/arrow/flight/sql/odbc/README | 83 ++++++ .../sql/odbc/install/unix/install_odbc_ini.sh | 85 ++++++ cpp/src/arrow/flight/sql/odbc/odbc_api.cc | 3 +- .../accessors/binary_array_accessor.cc | 3 +- .../accessors/binary_array_accessor_test.cc | 7 +- .../accessors/boolean_array_accessor_test.cc | 5 +- .../sql/odbc/odbc_impl/accessors/common.h | 5 +- .../accessors/date_array_accessor_test.cc | 7 +- .../accessors/decimal_array_accessor_test.cc | 5 +- .../primitive_array_accessor_test.cc | 23 +- .../accessors/string_array_accessor.cc | 3 +- .../accessors/string_array_accessor_test.cc | 11 +- .../accessors/time_array_accessor_test.cc | 11 +- .../accessors/timestamp_array_accessor.cc | 10 +- .../timestamp_array_accessor_test.cc | 11 +- .../sql/odbc/odbc_impl/accessors/types.h | 2 +- .../flight/sql/odbc/odbc_impl/address_info.cc | 5 +- .../flight/sql/odbc/odbc_impl/address_info.h | 5 +- .../sql/odbc/odbc_impl/calendar_utils.cc | 3 + .../odbc/odbc_impl/flight_sql_auth_method.cc | 28 +- .../odbc/odbc_impl/flight_sql_connection.cc | 13 +- .../odbc/odbc_impl/flight_sql_connection.h | 2 +- .../odbc_impl/flight_sql_connection_test.cc | 18 +- .../odbc_impl/flight_sql_get_tables_reader.cc | 6 +- .../flight_sql_result_set_metadata.cc | 16 +- .../odbc/odbc_impl/flight_sql_ssl_config.h | 4 +- .../odbc/odbc_impl/flight_sql_statement.cc | 4 +- .../flight_sql_statement_get_columns.cc | 13 +- .../flight_sql_statement_get_tables.h | 1 - .../flight_sql_stream_chunk_buffer.cc | 14 +- .../sql/odbc/odbc_impl/get_info_cache.h | 5 +- .../sql/odbc/odbc_impl/json_converter.cc | 2 +- .../sql/odbc/odbc_impl/json_converter.h | 2 +- .../sql/odbc/odbc_impl/json_converter_test.cc | 5 +- .../sql/odbc/odbc_impl/odbc_connection.cc | 23 +- .../sql/odbc/odbc_impl/odbc_connection.h | 12 +- .../sql/odbc/odbc_impl/odbc_descriptor.cc | 14 +- .../sql/odbc/odbc_impl/odbc_descriptor.h | 6 +- .../flight/sql/odbc/odbc_impl/odbc_handle.h | 5 +- .../sql/odbc/odbc_impl/odbc_statement.cc | 8 +- .../sql/odbc/odbc_impl/odbc_statement.h | 5 +- .../odbc/odbc_impl/parse_table_types_test.cc | 3 +- .../odbc/odbc_impl/record_batch_transformer.h | 4 +- .../record_batch_transformer_test.cc | 3 +- .../odbc/odbc_impl/scalar_function_reporter.h | 2 +- .../sql/odbc/odbc_impl/spi/connection.h | 6 +- .../flight/sql/odbc/odbc_impl/spi/statement.h | 4 +- .../sql/odbc/odbc_impl/ui/custom_window.cc | 1 + .../odbc_impl/ui/dsn_configuration_window.cc | 6 +- .../flight/sql/odbc/odbc_impl/ui/window.cc | 1 - .../arrow/flight/sql/odbc/odbc_impl/util.cc | 19 +- .../arrow/flight/sql/odbc/odbc_impl/util.h | 2 +- .../flight/sql/odbc/odbc_impl/util_test.cc | 11 +- cpp/src/arrow/flight/sql/odbc/tests/README | 23 ++ .../sql/odbc/tests/dremio/docker-compose.yml | 35 +++ .../tests/dremio/set_up_dremio_instance.sh | 66 +++++ cpp/vcpkg.json | 2 - 63 files changed, 862 insertions(+), 337 deletions(-) create mode 100644 .github/actions/odbc-windows/action.yml create mode 100644 cpp/src/arrow/flight/sql/odbc/README create mode 100755 cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh create mode 100644 cpp/src/arrow/flight/sql/odbc/tests/README create mode 100644 cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml create mode 100644 cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh diff --git a/.github/actions/odbc-windows/action.yml b/.github/actions/odbc-windows/action.yml new file mode 100644 index 000000000000..10ba9ebbc15c --- /dev/null +++ b/.github/actions/odbc-windows/action.yml @@ -0,0 +1,95 @@ +# 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. + +name: ODBC Windows Reusable +inputs: + github-token: + description: 'GITHUB_TOKEN for vcpkg caching' + required: true +runs: + using: "composite" + steps: + - name: Disable Crash Dialogs + shell: pwsh + run: | + reg add ` + "HKCU\SOFTWARE\Microsoft\Windows\Windows Error Reporting" ` + /v DontShowUI ` + /t REG_DWORD ` + /d 1 ` + /f + - name: Download Timezone Database + shell: bash + run: ci/scripts/download_tz_database.sh + - name: Install ccache + shell: bash + run: | + ci/scripts/install_ccache.sh 4.12.1 /usr + - name: Setup ccache + shell: bash + run: | + ci/scripts/ccache_setup.sh + - name: ccache info + id: ccache-info + shell: bash + run: | + echo "cache-dir=$(ccache --get-config cache_dir)" >> $GITHUB_OUTPUT + - name: Cache ccache + uses: actions/cache@v5 + with: + path: ${{ steps.ccache-info.outputs.cache-dir }} + key: cpp-odbc-ccache-windows-x64-${{ hashFiles('cpp/**') }} + restore-keys: cpp-odbc-ccache-windows-x64- + - name: Checkout vcpkg + uses: actions/checkout@v6 + with: + fetch-depth: 0 + path: vcpkg + repository: microsoft/vcpkg + - name: Bootstrap vcpkg + shell: pwsh + run: | + vcpkg\bootstrap-vcpkg.bat + $VCPKG_ROOT = $(Resolve-Path -LiteralPath "vcpkg").ToString() + Write-Output ${VCPKG_ROOT} | ` + Out-File -FilePath ${Env:GITHUB_PATH} -Encoding utf8 -Append + Write-Output "VCPKG_ROOT=${VCPKG_ROOT}" | ` + Out-File -FilePath ${Env:GITHUB_ENV} -Encoding utf8 -Append + - name: Setup NuGet credentials for vcpkg caching + shell: bash + run: | + $(vcpkg fetch nuget | tail -n 1) \ + sources add \ + -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ + -storepasswordincleartext \ + -name "GitHub" \ + -username "$GITHUB_REPOSITORY_OWNER" \ + -password "${{ inputs.github-token }}" + $(vcpkg fetch nuget | tail -n 1) \ + setapikey "${{ inputs.github-token }}" \ + -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" + - name: Build + shell: cmd + run: | + set VCPKG_ROOT_KEEP=%VCPKG_ROOT% + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 + set VCPKG_ROOT=%VCPKG_ROOT_KEEP% + bash -c "ci/scripts/cpp_build.sh $(pwd) $(pwd)/build" + - name: Register Flight SQL ODBC Driver + shell: cmd + run: | + call "cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd" ${{ github.workspace }}\build\cpp\%ARROW_BUILD_TYPE%\arrow_flight_sql_odbc.dll diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index c762b7cfcdb4..998b83a0b46e 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -73,6 +73,16 @@ on: schedule: - cron: | 0 0 * * * + workflow_dispatch: + inputs: + odbc_upload: + description: 'ODBC Component Upload' + required: true + default: 'dll' + type: choice + options: + - dll + - msi concurrency: group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} @@ -95,9 +105,10 @@ jobs: name: ${{ matrix.title }} runs-on: ${{ matrix.runs-on }} if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 75 strategy: fail-fast: false @@ -184,9 +195,10 @@ jobs: msvc-arm64: needs: check-labels if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) name: ARM64 Windows 11 MSVC uses: ./.github/workflows/cpp_windows.yml with: @@ -199,9 +211,10 @@ jobs: name: JNI ${{ matrix.platform.runs-on }} ${{ matrix.platform.arch }} runs-on: ${{ matrix.platform.runs-on }} if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 240 permissions: # This is for using GitHub Packages for vcpkg cache @@ -264,9 +277,10 @@ jobs: name: JNI macOS runs-on: macos-14 if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 45 env: MACOSX_DEPLOYMENT_TARGET: "14.0" @@ -350,15 +364,22 @@ jobs: odbc-linux: needs: check-labels - name: ODBC Linux + name: ODBC ${{ matrix.title }} runs-on: ubuntu-latest if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 75 strategy: fail-fast: false + matrix: + include: + - image: ubuntu-cpp-odbc + title: AMD64 Ubuntu + - image: debian-cpp-odbc + title: AMD64 Debian env: ARCH: amd64 ARCHERY_DEBUG: 1 @@ -376,8 +397,8 @@ jobs: uses: actions/cache@v5 with: path: .docker - key: ubuntu-cpp-odbc-${{ hashFiles('cpp/**') }} - restore-keys: ubuntu-cpp-odbc- + key: ${{ matrix.image }}-${{ hashFiles('cpp/**') }} + restore-keys: ${{ matrix.image }}- - name: Setup Python on hosted runner uses: actions/setup-python@v6 with: @@ -392,7 +413,7 @@ jobs: # GH-40558: reduce ASLR to avoid ASAN/LSAN crashes sudo sysctl -w vm.mmap_rnd_bits=28 source ci/scripts/util_enable_core_dumps.sh - archery docker run ubuntu-cpp-odbc + archery docker run ${{ matrix.image }} - name: Docker Push if: >- success() && @@ -403,16 +424,17 @@ jobs: ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }} ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }} continue-on-error: true - run: archery docker push ubuntu-cpp-odbc + run: archery docker push ${{ matrix.image }} odbc-macos: needs: check-labels name: ODBC ${{ matrix.build-type }} ${{ matrix.architecture }} macOS ${{ matrix.macos-version }} runs-on: macos-${{ matrix.macos-version }} if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 120 strategy: fail-fast: false @@ -522,13 +544,15 @@ jobs: name: ODBC Windows runs-on: windows-2022 if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + ) timeout-minutes: 240 permissions: packages: write - env: + env: &odbc_msvc_env ARROW_BUILD_SHARED: ON ARROW_BUILD_STATIC: OFF ARROW_BUILD_TESTS: ON @@ -545,81 +569,16 @@ jobs: VCPKG_BINARY_SOURCES: 'clear;nugettimeout,600;nuget,GitHub,readwrite' VCPKG_DEFAULT_TRIPLET: x64-windows steps: - - name: Disable Crash Dialogs - run: | - reg add ` - "HKCU\SOFTWARE\Microsoft\Windows\Windows Error Reporting" ` - /v DontShowUI ` - /t REG_DWORD ` - /d 1 ` - /f - name: Checkout Arrow uses: actions/checkout@v6 with: persist-credentials: false fetch-depth: 0 submodules: recursive - - name: Download Timezone Database - shell: bash - run: ci/scripts/download_tz_database.sh - - name: Install ccache - shell: bash - run: | - ci/scripts/install_ccache.sh 4.12.1 /usr - - name: Setup ccache - shell: bash - run: | - ci/scripts/ccache_setup.sh - - name: ccache info - id: ccache-info - shell: bash - run: | - echo "cache-dir=$(ccache --get-config cache_dir)" >> $GITHUB_OUTPUT - - name: Cache ccache - uses: actions/cache@v5 - with: - path: ${{ steps.ccache-info.outputs.cache-dir }} - key: cpp-odbc-ccache-windows-x64-${{ hashFiles('cpp/**') }} - restore-keys: cpp-odbc-ccache-windows-x64- - - name: Checkout vcpkg - uses: actions/checkout@v6 + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows with: - persist-credentials: false - fetch-depth: 0 - path: vcpkg - repository: microsoft/vcpkg - - name: Bootstrap vcpkg - run: | - vcpkg\bootstrap-vcpkg.bat - $VCPKG_ROOT = $(Resolve-Path -LiteralPath "vcpkg").ToString() - Write-Output ${VCPKG_ROOT} | ` - Out-File -FilePath ${Env:GITHUB_PATH} -Encoding utf8 -Append - Write-Output "VCPKG_ROOT=${VCPKG_ROOT}" | ` - Out-File -FilePath ${Env:GITHUB_ENV} -Encoding utf8 -Append - - name: Setup NuGet credentials for vcpkg caching - shell: bash - run: | - $(vcpkg fetch nuget | tail -n 1) \ - sources add \ - -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ - -storepasswordincleartext \ - -name "GitHub" \ - -username "$GITHUB_REPOSITORY_OWNER" \ - -password "${{ secrets.GITHUB_TOKEN }}" - $(vcpkg fetch nuget | tail -n 1) \ - setapikey "${{ secrets.GITHUB_TOKEN }}" \ - -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" - - name: Build - shell: cmd - run: | - set VCPKG_ROOT_KEEP=%VCPKG_ROOT% - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 - set VCPKG_ROOT=%VCPKG_ROOT_KEEP% - bash -c "ci/scripts/cpp_build.sh $(pwd) $(pwd)/build" - - name: Register Flight SQL ODBC Driver - shell: cmd - run: | - call "cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd" ${{ github.workspace }}\build\cpp\%ARROW_BUILD_TYPE%\arrow_flight_sql_odbc.dll + github-token: ${{ secrets.GITHUB_TOKEN }} - name: Test shell: cmd run: | @@ -642,7 +601,7 @@ jobs: wix --version cd build/cpp cpack - - name: Upload the artifacts to the job + - name: Upload ODBC MSI to the job uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-msi-installer @@ -684,6 +643,125 @@ jobs: Write-Error "ODBC DLL not found" exit 1 + odbc-msvc-upload-dll: + needs: check-labels + name: ODBC Windows Upload Unsigned DLL + runs-on: windows-2022 + if: inputs.odbc_upload == 'dll' + timeout-minutes: 240 + permissions: + packages: write + env: *odbc_msvc_env + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Name Unsigned ODBC DLL + run: | + Rename-Item ` + -Path build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc.dll ` + -NewName arrow_flight_sql_odbc_unsigned.dll + - name: Upload ODBC DLL to the job + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-dll + path: build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc_unsigned.dll + if-no-files-found: error + + odbc-dll-release: + needs: odbc-msvc-upload-dll + name: Upload Unsigned ODBC DLL + runs-on: ubuntu-latest + permissions: + # Upload to GitHub Release + contents: write + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Download the artifacts + uses: actions/download-artifact@v8 + with: + name: flight-sql-odbc-dll + - name: Wait for creating GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + dev/release/utils-watch-gh-workflow.sh \ + ${GITHUB_REF_NAME} \ + release_candidate.yml + - name: Upload the artifacts to GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload ${GITHUB_REF_NAME} \ + --clobber \ + arrow_flight_sql_odbc_unsigned.dll + + odbc-msvc-upload-msi: + needs: check-labels + name: ODBC Windows Upload Unsigned MSI + runs-on: windows-2022 + if: inputs.odbc_upload == 'msi' + timeout-minutes: 240 + permissions: + # Upload to GitHub Release + contents: write + packages: write + env: *odbc_msvc_env + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Download signed ODBC DLL + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download $env:GITHUB_REF_NAME ` + --pattern arrow_flight_sql_odbc.dll ` + --clobber + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Replace signed DLL with unsigned DLL + run: | + Move-Item ` + -Path ./arrow_flight_sql_odbc.dll ` + -Destination build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc.dll ` + -Force + - name: Install WiX Toolset + shell: pwsh + run: | + Invoke-WebRequest -Uri https://github.com/wixtoolset/wix/releases/download/v6.0.0/wix-cli-x64.msi -OutFile wix-cli-x64.msi + Start-Process -FilePath wix-cli-x64.msi -ArgumentList '/quiet', 'Include_freethreaded=1' -Wait + echo "C:\Program Files\WiX Toolset v6.0\bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: Build MSI ODBC installer + shell: pwsh + run: | + # Verify WiX version + wix --version + cd build/cpp + cpack + - name: Upload the artifacts to GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd build/cpp + gh release upload $env:GITHUB_REF_NAME ` + --clobber ` + Apache-Arrow-Flight-SQL-ODBC-*-win64.msi + odbc-nightly: needs: odbc-msvc name: ODBC nightly @@ -731,40 +809,6 @@ jobs: remote_key: ${{ secrets.NIGHTLIES_RSYNC_KEY }} remote_host_key: ${{ secrets.NIGHTLIES_RSYNC_HOST_KEY }} - odbc-release: - needs: odbc-msvc - name: ODBC release - runs-on: ubuntu-latest - if: ${{ startsWith(github.ref_name, 'apache-arrow-') && contains(github.ref_name, '-rc') }} - permissions: - # Upload to GitHub Release - contents: write - steps: - - name: Checkout Arrow - uses: actions/checkout@v6 - with: - persist-credentials: false - fetch-depth: 0 - submodules: recursive - - name: Download the artifacts - uses: actions/download-artifact@v8 - with: - name: flight-sql-odbc-msi-installer - - name: Wait for creating GitHub Release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - dev/release/utils-watch-gh-workflow.sh \ - ${GITHUB_REF_NAME} \ - release_candidate.yml - - name: Upload the artifacts to GitHub Release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release upload ${GITHUB_REF_NAME} \ - --clobber \ - Apache-Arrow-Flight-SQL-ODBC-*-win64.msi - report-extra-cpp: if: github.event_name == 'schedule' && always() needs: @@ -775,6 +819,8 @@ jobs: - odbc-linux - odbc-macos - odbc-msvc + - odbc-msvc-upload-dll + - odbc-msvc-upload-msi - odbc-nightly uses: ./.github/workflows/report_ci.yml secrets: diff --git a/.gitignore b/.gitignore index 83458ab2057b..c7690ec2637f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ dependency-reduced-pom.xml MANIFEST compile_commands.json build.ninja +build*/ # Generated Visual Studio files *.vcxproj diff --git a/ci/docker/debian-13-cpp.dockerfile b/ci/docker/debian-13-cpp.dockerfile index 4f0529ab50e5..c55f5d69008c 100644 --- a/ci/docker/debian-13-cpp.dockerfile +++ b/ci/docker/debian-13-cpp.dockerfile @@ -88,8 +88,10 @@ RUN apt-get update -y -q && \ rapidjson-dev \ rsync \ rustc \ + sudo \ tzdata \ tzdata-legacy \ + unixodbc-dev \ zlib1g-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* diff --git a/compose.yaml b/compose.yaml index be32a95dd945..2fa4c5a9aa93 100644 --- a/compose.yaml +++ b/compose.yaml @@ -133,6 +133,7 @@ x-hierarchy: - debian-cpp: - debian-c-glib: - debian-ruby + - debian-cpp-odbc - debian-python: - debian-docs - fedora-cpp: @@ -371,6 +372,54 @@ services: /arrow/ci/scripts/cpp_build.sh /arrow /build && /arrow/ci/scripts/cpp_test.sh /arrow /build" + debian-cpp-odbc: + # Usage: + # docker compose build debian-cpp-odbc + # docker compose run --rm debian-cpp-odbc + # Parameters: + # ARCH: amd64, arm64v8, ... + # DEBIAN: 12, experimental + image: ${REPO}:${ARCH}-debian-${DEBIAN}-cpp + build: + context: . + dockerfile: ci/docker/debian-${DEBIAN}-cpp.dockerfile + cache_from: + - ${REPO}:${ARCH}-debian-${DEBIAN}-cpp + args: + arch: ${ARCH} + gcc: ${GCC} + llvm: ${LLVM} + shm_size: *shm-size + ulimits: *ulimits + environment: + <<: [*common, *ccache, *sccache, *cpp] + ARROW_ACERO: "OFF" + ARROW_AZURE: "OFF" + ARROW_BUILD_TYPE: RELEASE + ARROW_CSV: "OFF" + ARROW_DATASET: "OFF" + ARROW_ENABLE_TIMING_TESTS: # inherit + ARROW_DEPENDENCY_SOURCE: BUNDLED + ARROW_DEPENDENCY_USE_SHARED: "OFF" + ARROW_FILESYSTEM: "OFF" + ARROW_FLIGHT_SQL_ODBC: "ON" + ARROW_GANDIVA: "OFF" + ARROW_GCS: "OFF" + ARROW_HDFS: "OFF" + ARROW_ORC: "OFF" + ARROW_PARQUET: "OFF" + ARROW_S3: "OFF" + ARROW_SUBSTRAIT: "OFF" + volumes: &debian-volumes + - .:/arrow:delegated + - ${DOCKER_VOLUME_PREFIX}debian-ccache:/ccache:delegated + # Register ODBC before running tests + command: > + /bin/bash -c " + /arrow/ci/scripts/cpp_build.sh /arrow /build && + sudo /arrow/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /usr/local/lib/libarrow_flight_sql_odbc.so && + /arrow/ci/scripts/cpp_test.sh /arrow /build" + ubuntu-cpp: &ubuntu-cpp-base # Usage: # docker compose build ubuntu-cpp diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index cc632a62fe4d..ac037f99691f 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -1108,19 +1108,10 @@ function(build_boost) endif() if(ARROW_FLIGHT_SQL_ODBC) # GH-49244: Replace boost beast with alternatives in ODBC - # GH-49243: Replace boost variant with std::variant in ODBC # GH-49245: Replace boost xpressive with alternatives in ODBC - list(APPEND - BOOST_INCLUDE_LIBRARIES - beast - variant - xpressive) + list(APPEND BOOST_INCLUDE_LIBRARIES beast xpressive) else() - list(APPEND - BOOST_EXCLUDE_LIBRARIES - beast - variant - xpressive) + list(APPEND BOOST_EXCLUDE_LIBRARIES beast xpressive) endif() set(BOOST_SKIP_INSTALL_RULES ON) if(NOT ARROW_ENABLE_THREADING) @@ -2754,51 +2745,53 @@ macro(build_zlib) # bundled. We need to do this for all packages # not just zlib as some depend on zlib, but we don't rebuild # if it exists already - if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - # build zlib using Emscripten ports - if(NOT EXISTS ${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a) - execute_process(COMMAND embuilder --pic --force build zlib) - endif() - add_library(ZLIB::ZLIB STATIC IMPORTED) - set_property(TARGET ZLIB::ZLIB - PROPERTY IMPORTED_LOCATION - "${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a") - target_include_directories(ZLIB::ZLIB INTERFACE "${EMSCRIPTEN_SYSROOT}/include") - list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) - else() - set(ZLIB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib_ep/src/zlib_ep-install") - if(MSVC) - if(${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG") - set(ZLIB_STATIC_LIB_NAME zlibstaticd.lib) - else() - set(ZLIB_STATIC_LIB_NAME zlibstatic.lib) + if(NOT TARGET ZLIB::ZLIB) + if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + # build zlib using Emscripten ports + if(NOT EXISTS ${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a) + execute_process(COMMAND embuilder --pic --force build zlib) endif() + add_library(ZLIB::ZLIB STATIC IMPORTED) + set_property(TARGET ZLIB::ZLIB + PROPERTY IMPORTED_LOCATION + "${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a") + target_include_directories(ZLIB::ZLIB INTERFACE "${EMSCRIPTEN_SYSROOT}/include") + list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) else() - set(ZLIB_STATIC_LIB_NAME libz.a) + set(ZLIB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib_ep/src/zlib_ep-install") + if(MSVC) + if(${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG") + set(ZLIB_STATIC_LIB_NAME zlibstaticd.lib) + else() + set(ZLIB_STATIC_LIB_NAME zlibstatic.lib) + endif() + else() + set(ZLIB_STATIC_LIB_NAME libz.a) + endif() + set(ZLIB_STATIC_LIB "${ZLIB_PREFIX}/lib/${ZLIB_STATIC_LIB_NAME}") + set(ZLIB_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=${ZLIB_PREFIX}") + + externalproject_add(zlib_ep + ${EP_COMMON_OPTIONS} + URL ${ZLIB_SOURCE_URL} + URL_HASH "SHA256=${ARROW_ZLIB_BUILD_SHA256_CHECKSUM}" + BUILD_BYPRODUCTS "${ZLIB_STATIC_LIB}" + CMAKE_ARGS ${ZLIB_CMAKE_ARGS}) + + file(MAKE_DIRECTORY "${ZLIB_PREFIX}/include") + + add_library(ZLIB::ZLIB STATIC IMPORTED) + set(ZLIB_LIBRARIES ${ZLIB_STATIC_LIB}) + set(ZLIB_INCLUDE_DIRS "${ZLIB_PREFIX}/include") + set_target_properties(ZLIB::ZLIB PROPERTIES IMPORTED_LOCATION ${ZLIB_LIBRARIES}) + target_include_directories(ZLIB::ZLIB BEFORE INTERFACE "${ZLIB_INCLUDE_DIRS}") + + add_dependencies(ZLIB::ZLIB zlib_ep) + list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) endif() - set(ZLIB_STATIC_LIB "${ZLIB_PREFIX}/lib/${ZLIB_STATIC_LIB_NAME}") - set(ZLIB_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=${ZLIB_PREFIX}") - - externalproject_add(zlib_ep - ${EP_COMMON_OPTIONS} - URL ${ZLIB_SOURCE_URL} - URL_HASH "SHA256=${ARROW_ZLIB_BUILD_SHA256_CHECKSUM}" - BUILD_BYPRODUCTS "${ZLIB_STATIC_LIB}" - CMAKE_ARGS ${ZLIB_CMAKE_ARGS}) - - file(MAKE_DIRECTORY "${ZLIB_PREFIX}/include") - add_library(ZLIB::ZLIB STATIC IMPORTED) - set(ZLIB_LIBRARIES ${ZLIB_STATIC_LIB}) - set(ZLIB_INCLUDE_DIRS "${ZLIB_PREFIX}/include") - set_target_properties(ZLIB::ZLIB PROPERTIES IMPORTED_LOCATION ${ZLIB_LIBRARIES}) - target_include_directories(ZLIB::ZLIB BEFORE INTERFACE "${ZLIB_INCLUDE_DIRS}") - - add_dependencies(ZLIB::ZLIB zlib_ep) - list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) + set(ZLIB_VENDORED TRUE) endif() - - set(ZLIB_VENDORED TRUE) endmacro() if(ARROW_WITH_ZLIB) diff --git a/cpp/src/arrow/flight/sql/odbc/README b/cpp/src/arrow/flight/sql/odbc/README new file mode 100644 index 000000000000..f119efc82790 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/README @@ -0,0 +1,83 @@ + + +## Steps to Register the 64-bit Apache Arrow ODBC driver on Windows + +After the build succeeds, the ODBC DLL will be located in +`build\debug\Debug` for a debug build and `build\release\Release` for a release build. + +1. Open Power Shell as administrator. + +2. Register your ODBC DLL: + Need to replace with actual path to repository in the commands. + + i. `cd to repo.` + ii. `cd ` + iii. Run script to register your ODBC DLL as Apache Arrow Flight SQL ODBC Driver + `.\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd \cpp\build\< release | debug >\< Release | Debug>\arrow_flight_sql_odbc.dll` + Example command for reference: + `.\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd C:\path\to\arrow\cpp\build\release\Release\arrow_flight_sql_odbc.dll` + +If the registration is successful, then Apache Arrow Flight SQL ODBC Driver +should show as an available ODBC driver in the x64 ODBC Driver Manager. + +## Steps to Generate Windows Installer +1. Build with `ARROW_FLIGHT_SQL_ODBC=ON` and `ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON`. +2. `cd` to `build` folder. +3. Run `cpack`. + +If the generation is successful, you will find `Apache Arrow Flight SQL ODBC--win64.msi` generated under the `build` folder. + +## Steps to Register the 64-bit Apache Arrow ODBC driver on macOS + +After the build succeeds, the ODBC DYLIB will be located in +`build\debug` for a debug build and `build\release` for a release build. + +1. Open terminal shell. + +2. Register your ODBC DYLIB: + Need to replace with actual path to repository in the commands. + + i. `cd to repo.` + ii. `cd ` + iii. Give script permission to execute + `chmod +x cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh` + iv. Run script with `sudo` to register your ODBC DYLIB as Apache Arrow Flight SQL ODBC Driver + `sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.dylib` + Example command for reference: + `sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /path/to/arrow/cpp/build/release/libarrow_flight_sql_odbc.dylib` + +If the registration is successful, then Apache Arrow Flight SQL ODBC Driver +should be shown at `~/Library/ODBC/odbcinst.ini` + +## Steps to Enable Logging +Arrow Flight SQL ODBC driver uses Arrow's internal logging framework. By default, the log messages are printed to the terminal. +1. Set environment variable `ARROW_ODBC_LOG_LEVEL` to any of the following valid values to enable logging. If `ARROW_ODBC_LOG_LEVEL` is set to a non-empty string that does not match any of the following values, `DEBUG` level is used by default. + +The characters are case-insensitive. +- TRACE +- DEBUG +- INFO +- WARNING +- ERROR +- FATAL + +The Windows ODBC driver currently does not support writing log files. `ARROW_USE_GLOG` is required to write log files, and `ARROW_USE_GLOG` is disabled on Windows platform since plasma using `glog` is not fully tested on windows. + +Note: GH-47670 running more than 1 tests with logging enabled is not fully supported. diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh new file mode 100755 index 000000000000..84de8e0e1464 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# +# 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. + +# GH-47876 TODO: create macOS ODBC Installer. +# Script for installing macOS ODBC driver, to be used for macOS installer. +# This script assumes ODBC driver is at +# /Library/ODBC/arrow-odbc/libarrow_flight_sql_odbc.dylib + +set -euo pipefail + +if [ $EUID -ne 0 ]; then + echo "Please run this script with sudo" + exit 1 +fi + +source_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +odbc_install_script="${source_dir}/../unix/install_odbc.sh" + +"$odbc_install_script" /Library/ODBC/arrow-odbc/libarrow_flight_sql_odbc.dylib + +USER_ODBC_FILE="$HOME/Library/ODBC/odbc.ini" +DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" +DSN_NAME="Apache Arrow Flight SQL ODBC DSN" + +touch "$USER_ODBC_FILE" + +if grep -q "^\[$DSN_NAME\]" "$USER_ODBC_FILE"; then + echo "DSN [$DSN_NAME] already exists in $USER_ODBC_FILE" +else + echo "Adding [$DSN_NAME] to $USER_ODBC_FILE..." + cat >> "$USER_ODBC_FILE" < "${USER_ODBC_FILE}.tmp" && mv "${USER_ODBC_FILE}.tmp" "$USER_ODBC_FILE" + fi +else + # Section doesn't exist, append section and DSN entry at end + { + echo "" + echo "[ODBC Data Sources]" + echo "${DSN_NAME}=${DRIVER_NAME}" + } >> "$USER_ODBC_FILE" +fi + diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc index 7c64dee21f5b..e2358e9a9f8f 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc @@ -588,7 +588,6 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT r << ", message_text: " << static_cast(message_text) << ", buffer_length: " << buffer_length << ", text_length_ptr: " << static_cast(text_length_ptr); - using arrow::flight::sql::odbc::Diagnostics; using ODBC::GetStringAttribute; using ODBC::ODBCConnection; using ODBC::ODBCDescriptor; @@ -1435,7 +1434,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, } SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT data_type) { - // GH-47237 TODO: return SQL_PRED_CHAR and SQL_PRED_BASIC for + // GH-47237 return SQL_PRED_CHAR and SQL_PRED_BASIC for // appropriate data types in `SEARCHABLE` field ARROW_LOG(DEBUG) << "SQLGetTypeInfoW called with stmt: " << stmt << " data_type: " << data_type; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc index e4625ace370f..939264bedb7d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc @@ -19,6 +19,7 @@ #include #include +#include #include "arrow/array.h" namespace arrow::flight::sql::odbc { @@ -39,7 +40,7 @@ inline RowStatus MoveSingleCellToBinaryBuffer(ColumnBinding* binding, BinaryArra auto* byte_buffer = static_cast(binding->buffer) + i * binding->buffer_length; - memcpy(byte_buffer, ((char*)value) + value_offset, value_length); + std::memcpy(byte_buffer, ((char*)value) + value_offset, value_length); if (remaining_length > binding->buffer_length) { result = RowStatus_SUCCESS_WITH_INFO; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc index 55ef46458e21..502eaf730689 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc @@ -18,11 +18,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.h" #include "arrow/testing/builder.h" #include "arrow/testing/gtest_util.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Basic) { +TEST(BinaryArrayAccessor, TestCDataTypeBinaryBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -53,7 +54,7 @@ TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Basic) { } } -TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Truncation) { +TEST(BinaryArrayAccessor, TestCDataTypeBinaryTruncation) { std::vector values = {"ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEF"}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc index 68583b3f15e0..9299ee7602f0 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc @@ -17,11 +17,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(BooleanArrayFlightSqlAccessor, Test_BooleanArray_CDataType_BIT) { +TEST(BooleanArrayFlightSqlAccessor, TestBooleanArrayCDataTypeBit) { const std::vector values = {true, false, true}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h index 0a79bc39dfb8..45f88b50fb8c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h @@ -19,6 +19,7 @@ #include #include +#include #include "arrow/array.h" #include "arrow/flight/sql/odbc/odbc_impl/accessors/types.h" #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -42,7 +43,7 @@ inline size_t CopyFromArrayValuesToBinding(ARRAY_TYPE* array, ColumnBinding* bin } } } else { - // Duplicate this loop to avoid null checks within the loop. + // Duplicate above for-loop to exit early when null value is found for (int64_t i = starting_row; i < starting_row + cells; ++i) { if (array->IsNull(i)) { throw NullWithoutIndicatorException(); @@ -54,7 +55,7 @@ inline size_t CopyFromArrayValuesToBinding(ARRAY_TYPE* array, ColumnBinding* bin // Note that the array should already have been sliced down to the same number // of elements in the ODBC data array by the point in which this function is called. const auto* values = array->raw_values(); - memcpy(binding->buffer, &values[starting_row], element_size * cells); + std::memcpy(binding->buffer, &values[starting_row], element_size * cells); return cells; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc index 03716e2477a4..a482a838101c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor.h" #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(DateArrayAccessor, Test_Date32Array_CDataType_DATE) { +TEST(DateArrayAccessor, TestDate32ArrayCDataTypeDate) { std::vector values = {7589, 12320, 18980, 19095, -1, 0}; std::vector expected = { {1990, 10, 12}, {2003, 9, 25}, {2021, 12, 19}, @@ -57,7 +58,7 @@ TEST(DateArrayAccessor, Test_Date32Array_CDataType_DATE) { } } -TEST(DateArrayAccessor, Test_Date64Array_CDataType_DATE) { +TEST(DateArrayAccessor, TestDate64ArrayCDataTypeDate) { std::vector values = { 86400000, 172800000, 259200000, 1649793238110, 0, 345600000, 432000000, 518400000, -86400000, -17987443200000, -24268068949000}; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc index 9833ea1d59c7..1b589b41c049 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc @@ -19,7 +19,8 @@ #include "arrow/builder.h" #include "arrow/testing/builder.h" #include "arrow/util/decimal.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { namespace { @@ -93,7 +94,7 @@ void AssertNumericOutput(int input_precision, int input_scale, } } -TEST(DecimalArrayFlightSqlAccessor, Test_Decimal128Array_CDataType_NUMERIC_SameScale) { +TEST(DecimalArrayFlightSqlAccessor, TestDecimal128ArrayCDataTypeNumericSameScale) { const std::vector& input_values = {"25.212", "-25.212", "-123456789.123", "123456789.123"}; const std::vector& output_values = diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc index bd9ecf3314fd..521a9c48b9aa 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc @@ -19,7 +19,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -52,43 +53,43 @@ void TestPrimitiveArraySqlAccessor() { } } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int64Array_CDataType_SBIGINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt64ArrayCDataTypeSbigint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int32Array_CDataType_SLONG) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt32ArrayCDataTypeSlong) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int16Array_CDataType_SSHORT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt16ArrayCDataTypeSshort) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int8Array_CDataType_STINYINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt8ArrayCDataTypeStinyint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt64Array_CDataType_UBIGINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt64ArrayCDataTypeUbigint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt32Array_CDataType_ULONG) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt32ArrayCDataTypeUlong) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt16Array_CDataType_USHORT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt16ArrayCDataTypeUshort) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt8Array_CDataType_UTINYINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt8ArrayCDataTypeUtinyint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_FloatArray_CDataType_FLOAT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestFloatArrayCDataTypeFloat) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_DoubleArray_CDataType_DOUBLE) { +TEST(PrimitiveArrayFlightSqlAccessor, TestDoubleArrayCDataTypeDouble) { TestPrimitiveArraySqlAccessor(); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc index 69b3b3049454..441b2a3394e7 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc @@ -18,6 +18,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.h" #include +#include #include "arrow/array.h" #include "arrow/flight/sql/odbc/odbc_impl/encoding.h" @@ -79,7 +80,7 @@ inline RowStatus MoveSingleCellToCharBuffer( auto* byte_buffer = static_cast(binding->buffer) + i * binding->buffer_length; auto* char_buffer = (CHAR_TYPE*)byte_buffer; - memcpy(char_buffer, ((char*)value) + value_offset, value_length); + std::memcpy(char_buffer, ((char*)value) + value_offset, value_length); // Write a NUL terminator if (binding->buffer_length >= remaining_length + sizeof(CHAR_TYPE)) { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc index 9316571dd7b3..6950f3351b7c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc @@ -19,11 +19,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/encoding.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(StringArrayAccessor, Test_CDataType_CHAR_Basic) { +TEST(StringArrayAccessor, TestCDataTypeCharBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -49,7 +50,7 @@ TEST(StringArrayAccessor, Test_CDataType_CHAR_Basic) { } } -TEST(StringArrayAccessor, Test_CDataType_CHAR_Truncation) { +TEST(StringArrayAccessor, TestCDataTypeCharTruncation) { std::vector values = {"ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEF"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -82,7 +83,7 @@ TEST(StringArrayAccessor, Test_CDataType_CHAR_Truncation) { ASSERT_EQ(values[0], ss.str()); } -TEST(StringArrayAccessor, Test_CDataType_WCHAR_Basic) { +TEST(StringArrayAccessor, TestCDataTypeWcharBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -112,7 +113,7 @@ TEST(StringArrayAccessor, Test_CDataType_WCHAR_Basic) { } } -TEST(StringArrayAccessor, Test_CDataType_WCHAR_Truncation) { +TEST(StringArrayAccessor, TestCDataTypeWcharTruncation) { std::vector values = {"ABCDEFA"}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc index eb49e4078cd8..41bd0d73ea77 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(TEST_TIME32, TIME_WITH_SECONDS) { +TEST(TestTime32, TimeWithSeconds) { auto value_field = field("f0", time32(TimeUnit::SECOND)); std::vector t32_values = {14896, 14897, 14892, 85400, 14893, 14895}; @@ -58,7 +59,7 @@ TEST(TEST_TIME32, TIME_WITH_SECONDS) { } } -TEST(TEST_TIME32, TIME_WITH_MILLI) { +TEST(TestTime32, TimeWithMilli) { auto value_field = field("f0", time32(TimeUnit::MILLI)); std::vector t32_values = {14896000, 14897000, 14892000, 85400000, 14893000, 14895000}; @@ -94,7 +95,7 @@ TEST(TEST_TIME32, TIME_WITH_MILLI) { } } -TEST(TEST_TIME64, TIME_WITH_MICRO) { +TEST(TestTime32, TimeWithMicro) { auto value_field = field("f0", time64(TimeUnit::MICRO)); std::vector t64_values = {14896000, 14897000, 14892000, @@ -131,7 +132,7 @@ TEST(TEST_TIME64, TIME_WITH_MICRO) { } } -TEST(TEST_TIME64, TIME_WITH_NANO) { +TEST(TestTime32, TimeWithNano) { auto value_field = field("f0", time64(TimeUnit::NANO)); std::vector t64_values = {14896000000, 14897000000, 14892000000, 85400000000, 14893000000, 14895000000}; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc index 37f14ebd9c52..93af94655769 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc @@ -19,12 +19,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" -using arrow::TimeUnit; +#include +#include namespace arrow::flight::sql::odbc { namespace { - -int64_t GetConversionToSecondsDivisor(TimeUnit::type unit) { +inline int64_t GetConversionToSecondsDivisor(TimeUnit::type unit) { int64_t divisor = 1; switch (unit) { case TimeUnit::SECOND: @@ -79,6 +79,10 @@ template RowStatus TimestampArrayFlightSqlAccessor::MoveSingleCellImpl( ColumnBinding* binding, int64_t arrow_row, int64_t cell_counter, int64_t& value_offset, bool update_value_offset, Diagnostics& diagnostics) { + // Times less than the minimum integer number of seconds that can be represented + // for each time unit will not convert correctly. This is mostly interesting for + // nanoseconds as timestamps in other units are outside of the accepted range of + // Gregorian dates. auto* buffer = static_cast(binding->buffer); int64_t value = this->GetArray()->Value(arrow_row); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc index 393dd98501d9..dd4917b0e378 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) { +TEST(TestTimestamp, TimestampWithMilli) { std::vector values = {86400370, 172800000, 259200000, 1649793238110LL, 345600000, 432000000, 518400000, -86399000, 0, @@ -88,7 +89,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) { +TEST(TestTimestamp, TimestampWithSeconds) { std::vector values = {86400, 172800, 259200, 1649793238, 345600, 432000, 518400}; @@ -130,7 +131,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) { +TEST(TestTimestamp, TimestampWithMicro) { std::vector values = {86400000000, 1649793238000000}; std::shared_ptr timestamp_array; @@ -174,7 +175,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_NANO) { +TEST(TestTimestamp, TimestampWithNano) { std::vector values = {86400000010000, 1649793238000000000}; std::shared_ptr timestamp_array; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h index f75d2894af99..7cd52af1bd02 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h @@ -102,7 +102,7 @@ class FlightSqlAccessor : public Accessor { throw NullWithoutIndicatorException(); } } else { - // TODO: Optimize this by creating different versions of MoveSingleCell + // GH-47849 TODO: Optimize this by creating different versions of MoveSingleCell // depending on if str_len_buffer is null. auto row_status = MoveSingleCell(binding, current_arrow_row, i, value_offset, update_value_offset, diagnostics); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc index 7bdb4d58cf82..5dfc85a58f77 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc @@ -18,7 +18,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/address_info.h" #include -namespace driver { +namespace arrow::flight::sql::odbc { bool AddressInfo::GetAddressInfo(const std::string& host, char* host_name_info, int64_t max_host) { @@ -47,4 +47,5 @@ AddressInfo::~AddressInfo() { } AddressInfo::AddressInfo() : addrinfo_result_(nullptr) {} -} // namespace driver + +} // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h index c127c0f4a29d..7d538f912e0d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h @@ -27,7 +27,7 @@ # include #endif -namespace driver { +namespace arrow::flight::sql::odbc { class AddressInfo { private: @@ -40,4 +40,5 @@ class AddressInfo { bool GetAddressInfo(const std::string& host, char* host_name_info, int64_t max_host); }; -} // namespace driver + +} // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc index 1dddae2a7c71..b47b33f2d93f 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc @@ -40,6 +40,9 @@ int64_t GetTodayTimeFromEpoch() { #endif } +// GH-47631: add support for non-UTC time zone data. +// Read the time zone value from Arrow::Timestamp, and use the time zone value to convert +// seconds_since_epoch instead of converting to UTC time zone by default void GetTimeForSecondsSinceEpoch(const int64_t seconds_since_epoch, std::tm& out_tm) { std::memset(&out_tm, 0, sizeof(std::tm)); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc index 587dbdfb96ba..5da662e7aded 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc @@ -37,6 +37,9 @@ class NoOpAuthMethod : public FlightSqlAuthMethod { void Authenticate(FlightSqlConnection& connection, FlightCallOptions& call_options) override { // Do nothing + + // GH-46733 TODO: implement NoOpAuthMethod to validate server address. + // Can use NoOpClientAuthHandler. } }; @@ -66,10 +69,10 @@ class UserPasswordAuthMethod : public FlightSqlAuthMethod { FlightCallOptions auth_call_options; const std::optional& login_timeout = connection.GetAttribute(Connection::LOGIN_TIMEOUT); - if (login_timeout && boost::get(*login_timeout) > 0) { + if (login_timeout && std::get(*login_timeout) > 0) { // ODBC's LOGIN_TIMEOUT attribute and FlightCallOptions.timeout use // seconds as time unit. - double timeout_seconds = static_cast(boost::get(*login_timeout)); + double timeout_seconds = static_cast(std::get(*login_timeout)); if (timeout_seconds > 0) { auth_call_options.timeout = TimeoutDuration{timeout_seconds}; } @@ -94,7 +97,9 @@ class UserPasswordAuthMethod : public FlightSqlAuthMethod { throw DriverException(bearer_result.status().message()); } - call_options.headers.push_back(bearer_result.ValueOrDie()); + // call_options may have already been populated with data from the connection string + // or DSN. Ensure auth-generated headers are placed at the front of the header list. + call_options.headers.insert(call_options.headers.begin(), bearer_result.ValueOrDie()); } std::string GetUser() override { return user_; } @@ -116,10 +121,11 @@ class TokenAuthMethod : public FlightSqlAuthMethod { void Authenticate(FlightSqlConnection& connection, FlightCallOptions& call_options) override { - // add the token to the headers + // add the token to the front of the headers. For consistency auth headers should be + // at the front. const std::pair token_header("authorization", "Bearer " + token_); - call_options.headers.push_back(token_header); + call_options.headers.insert(call_options.headers.begin(), token_header); const Status status = client_.Authenticate( call_options, std::unique_ptr(new NoOpClientAuthHandler())); @@ -143,22 +149,22 @@ std::unique_ptr FlightSqlAuthMethod::FromProperties( const std::unique_ptr& client, const Connection::ConnPropertyMap& properties) { // Check if should use user-password authentication - auto it_user = properties.find(FlightSqlConnection::USER); + auto it_user = properties.find(std::string(FlightSqlConnection::USER)); if (it_user == properties.end()) { // The Microsoft OLE DB to ODBC bridge provider (MSDASQL) will write // "User ID" and "Password" properties instead of mapping // to ODBC compliant UID/PWD keys. - it_user = properties.find(FlightSqlConnection::USER_ID); + it_user = properties.find(std::string(FlightSqlConnection::USER_ID)); } - auto it_password = properties.find(FlightSqlConnection::PASSWORD); - auto it_token = properties.find(FlightSqlConnection::TOKEN); + auto it_password = properties.find(std::string(FlightSqlConnection::PASSWORD)); + auto it_token = properties.find(std::string(FlightSqlConnection::TOKEN)); if (it_user == properties.end() || it_password == properties.end()) { // Accept UID/PWD as aliases for User/Password. These are suggested as // standard properties in the documentation for SQLDriverConnect. - it_user = properties.find(FlightSqlConnection::UID); - it_password = properties.find(FlightSqlConnection::PWD); + it_user = properties.find(std::string(FlightSqlConnection::UID)); + it_password = properties.find(std::string(FlightSqlConnection::PWD)); } if (it_user != properties.end() || it_password != properties.end()) { const std::string& user = it_user != properties.end() ? it_user->second : ""; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc index f00ce85d9f3e..e33268476d23 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc @@ -120,7 +120,7 @@ const std::set BUILT_IN_PROPERTIES Connection::ConnPropertyMap::const_iterator TrackMissingRequiredProperty( std::string_view property, const Connection::ConnPropertyMap& properties, std::vector& missing_attr) { - auto prop_iter = properties.find(property); + auto prop_iter = properties.find(std::string(property)); if (properties.end() == prop_iter) { missing_attr.push_back(property); } @@ -139,6 +139,7 @@ std::shared_ptr LoadFlightSslConfigs( AsBool(conn_property_map, FlightSqlConnection::USE_SYSTEM_TRUST_STORE) .value_or(SYSTEM_TRUST_STORE_DEFAULT); + // GH-47630: find co-located TLS certificate if `trusted certs` path is not specified auto trusted_certs_iterator = conn_property_map.find(std::string(FlightSqlConnection::TRUSTED_CERTS)); auto trusted_certs = trusted_certs_iterator != conn_property_map.end() @@ -244,9 +245,9 @@ const FlightCallOptions& FlightSqlConnection::PopulateCallOptions( // is the first request. const std::optional& connection_timeout = closed_ ? GetAttribute(LOGIN_TIMEOUT) : GetAttribute(CONNECTION_TIMEOUT); - if (connection_timeout && boost::get(*connection_timeout) > 0) { + if (connection_timeout && std::get(*connection_timeout) > 0) { call_options_.timeout = - TimeoutDuration{static_cast(boost::get(*connection_timeout))}; + TimeoutDuration{static_cast(std::get(*connection_timeout))}; } for (auto prop : props) { @@ -321,7 +322,7 @@ Location FlightSqlConnection::BuildLocation( Location location; if (ssl_config->UseEncryption()) { - driver::AddressInfo address_info; + AddressInfo address_info; char host_name_info[NI_MAXHOST] = ""; bool operation_result = false; @@ -335,7 +336,7 @@ Location FlightSqlConnection::BuildLocation( ThrowIfNotOK(Location::ForGrpcTls(host_name_info, port).Value(&location)); return location; } - // TODO: We should log that we could not convert an IP to hostname here. + // GH-47852 TODO: We should log that we could not convert an IP to hostname here. } } catch (...) { // This is expected. The Host attribute can be an IP or name, but make_address will @@ -403,7 +404,7 @@ Connection::Info FlightSqlConnection::GetInfo(uint16_t info_type) { if (info_type == SQL_DBMS_NAME || info_type == SQL_SERVER_NAME) { // Update the database component reported in error messages. // We do this lazily for performance reasons. - diagnostics_.SetDataSourceComponent(boost::get(result)); + diagnostics_.SetDataSourceComponent(std::get(result)); } return result; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h index 2561ea492f05..d1a194abcbd8 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h @@ -34,7 +34,7 @@ class FlightSqlSslConfig; /// \brief Create an instance of the FlightSqlSslConfig class, from the properties passed /// into the map. /// \param conn_property_map the map with the Connection properties. -/// \return An instance of the FlightSqlSslConfig. +/// \return An instance of the FlightSqlSslConfig. std::shared_ptr LoadFlightSslConfigs( const Connection::ConnPropertyMap& conn_property_map); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc index 87ae526f1582..bc26a113d77e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc @@ -19,7 +19,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include "arrow/flight/types.h" -#include "gtest/gtest.h" + +#include #include @@ -33,17 +34,16 @@ TEST(AttributeTests, SetAndGetAttribute) { const std::optional first_value = connection.GetAttribute(Connection::CONNECTION_TIMEOUT); - EXPECT_TRUE(first_value); - - EXPECT_EQ(static_cast(200), boost::get(*first_value)); + ASSERT_TRUE(first_value); + ASSERT_EQ(static_cast(200), std::get(*first_value)); connection.SetAttribute(Connection::CONNECTION_TIMEOUT, static_cast(300)); const std::optional change_value = connection.GetAttribute(Connection::CONNECTION_TIMEOUT); - EXPECT_TRUE(change_value); - EXPECT_EQ(static_cast(300), boost::get(*change_value)); + ASSERT_TRUE(change_value); + ASSERT_EQ(static_cast(300), std::get(*change_value)); connection.Close(); } @@ -55,7 +55,7 @@ TEST(AttributeTests, GetAttributeWithoutSetting) { connection.GetAttribute(Connection::CONNECTION_TIMEOUT); connection.SetClosed(false); - EXPECT_EQ(0, boost::get(*optional)); + EXPECT_EQ(0, std::get(*optional)); connection.Close(); } @@ -77,8 +77,8 @@ TEST(MetadataSettingsTest, StringColumnLengthTest) { const std::optional actual_string_column_length = connection.GetStringColumnLength(properties); - EXPECT_TRUE(actual_string_column_length); - EXPECT_EQ(expected_string_column_length, *actual_string_column_length); + ASSERT_TRUE(actual_string_column_length); + ASSERT_EQ(expected_string_column_length, *actual_string_column_length); connection.Close(); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc index ebff8c40f2cb..a668353272b5 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc @@ -77,9 +77,9 @@ std::shared_ptr GetTablesReader::GetSchema() { const arrow::Result>& result = arrow::ipc::ReadSchema(&dataset_schema_reader, &in_memo); if (!result.ok()) { - // TODO: Ignoring this error until we fix the problem on Dremio server - // The problem is that complex types columns are being returned without the children - // types. + // GH-46561 TODO: Test and build the driver against a server that returns + // complex types columns with the children + // types and handle the failure properly return nullptr; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc index 9e2f45647a52..8278b42e36b1 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc @@ -158,19 +158,27 @@ size_t FlightSqlResultSetMetadata::GetLength(int column_position) { } std::string FlightSqlResultSetMetadata::GetLiteralPrefix(int column_position) { - // TODO: Flight SQL column metadata does not have this, should we add to the spec? + // GH-47853 TODO: use `ColumnMetadata` to get literal prefix after Flight SQL protocol + // adds support for it + + // Flight SQL column metadata does not have literal prefix, empty string is returned return ""; } std::string FlightSqlResultSetMetadata::GetLiteralSuffix(int column_position) { - // TODO: Flight SQL column metadata does not have this, should we add to the spec? + // GH-47853 TODO: use `ColumnMetadata` to get literal suffix after Flight SQL protocol + // adds support for it + + // Flight SQL column metadata does not have literal suffix, empty string is returned return ""; } std::string FlightSqlResultSetMetadata::GetLocalTypeName(int column_position) { ColumnMetadata metadata = GetMetadata(schema_->field(column_position - 1)); - // TODO: Is local type name the same as type name? + // Local type name is for display purpose only. + // Return type name as local type name as Flight SQL protocol doesn't have support for + // local type name. return metadata.GetTypeName().ValueOrElse([] { return ""; }); } @@ -193,7 +201,7 @@ size_t FlightSqlResultSetMetadata::GetOctetLength(int column_position) { // Workaround to get the precision for Decimal and Numeric types, since server doesn't // return it currently. - // TODO: Use the server precision when its fixed. + // GH-47854 TODO: Use the server precision when its fixed. std::shared_ptr arrow_type = field->type(); if (arrow_type->id() == Type::DECIMAL128) { int32_t precision = util::GetDecimalTypePrecision(arrow_type); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h index 10b121497121..c2d1423e97e6 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h @@ -17,9 +17,9 @@ #pragma once -#include -#include #include +#include "arrow/flight/types.h" +#include "arrow/status.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc index 46456e8c3c91..c75631222605 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc @@ -83,9 +83,9 @@ bool FlightSqlStatement::SetAttribute(StatementAttributeId attribute, case MAX_LENGTH: return CheckIfSetToOnlyValidValue(value, static_cast(0)); case QUERY_TIMEOUT: - if (boost::get(value) > 0) { + if (std::get(value) > 0) { call_options_.timeout = - TimeoutDuration{static_cast(boost::get(value))}; + TimeoutDuration{static_cast(std::get(value))}; } else { call_options_.timeout = TimeoutDuration{-1}; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc index 914cd8fa4520..a6200c0b1c15 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc @@ -26,6 +26,8 @@ namespace arrow::flight::sql::odbc { using arrow::Result; +using arrow::Schema; +using arrow::flight::sql::ColumnMetadata; using util::AppendToBuilder; using std::make_optional; @@ -99,10 +101,9 @@ Result> TransformInner( const auto& table_name = reader.GetTableName(); const std::shared_ptr& schema = reader.GetSchema(); if (schema == nullptr) { - // TODO: Remove this if after fixing TODO on GetTablesReader::GetSchema() - // This is because of a problem on Dremio server, where complex types columns - // are being returned without the children types, so we are simply ignoring - // it by now. + // GH-46561 TODO: Test and build the driver against a server that returns + // complex types columns with the children + // types and handle the failure properly. continue; } for (int i = 0; i < schema->num_fields(); ++i) { @@ -126,8 +127,8 @@ Result> TransformInner( ? data_type_v3 : util::ConvertSqlDataTypeFromV3ToV2(data_type_v3); - // TODO: Use `metadata.GetTypeName()` when ARROW-16064 is merged. - const auto& type_name_result = field->metadata()->Get("ARROW:FLIGHT:SQL:TYPE_NAME"); + const auto& type_name_result = metadata.GetTypeName(); + data.type_name = type_name_result.ok() ? type_name_result.ValueOrDie() : util::GetTypeNameFromSqlDataType(data_type_v3); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h index 0c3ad10f97b5..5687134f1eb7 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h @@ -61,5 +61,4 @@ std::shared_ptr GetTablesForGenericUse( const std::string* catalog_name, const std::string* schema_name, const std::string* table_name, const std::vector& table_types, Diagnostics& diagnostics, const MetadataSettings& metadata_settings); - } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc index be788d9d08aa..d4812e30eee4 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc @@ -20,8 +20,6 @@ namespace arrow::flight::sql::odbc { -using arrow::Result; - FlightStreamChunkBuffer::FlightStreamChunkBuffer( FlightSqlClient& flight_sql_client, const FlightClientOptions& client_options, const FlightCallOptions& call_options, const std::shared_ptr& flight_info, @@ -58,10 +56,10 @@ FlightStreamChunkBuffer::FlightStreamChunkBuffer( util::ThrowIfNotOK(result.status()); std::shared_ptr stream_reader_ptr(std::move(result.ValueOrDie())); - BlockingQueue, - std::shared_ptr>>::Supplier supplier = [=]() - -> std::optional< - std::pair, std::shared_ptr>> { + BlockingQueue, + std::shared_ptr>>::Supplier supplier = + [=]() -> std::optional, + std::shared_ptr>> { auto result = stream_reader_ptr->Next(); bool is_not_ok = !result.ok(); bool is_not_empty = result.ok() && (result.ValueOrDie().data != nullptr); @@ -82,13 +80,13 @@ FlightStreamChunkBuffer::FlightStreamChunkBuffer( } bool FlightStreamChunkBuffer::GetNext(FlightStreamChunk* chunk) { - std::pair, std::shared_ptr> + std::pair, std::shared_ptr> closeable_endpoint_stream_pair; if (!queue_.Pop(&closeable_endpoint_stream_pair)) { return false; } - Result result = closeable_endpoint_stream_pair.first; + arrow::Result result = closeable_endpoint_stream_pair.first; if (!result.status().ok()) { Close(); throw DriverException(result.status().message()); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h index a1452e4b466f..693ee000de52 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h @@ -17,13 +17,12 @@ #pragma once -#include "arrow/flight/sql/client.h" -#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" - #include #include #include #include +#include "arrow/flight/sql/client.h" +#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc index db6170f31027..acd68f0eef3c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc @@ -221,7 +221,7 @@ class ScalarToJson : public ScalarVisitor { } Status Visit(const DurationScalar& scalar) override { - // TODO: Append TimeUnit on conversion + // GH-47857 TODO: Append TimeUnit on conversion return ConvertScalarToStringAndWrite(scalar, writer_); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h index 9c0b42748a8c..44321398b6fa 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h @@ -17,8 +17,8 @@ #pragma once -#include #include +#include "arrow/type_fwd.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc index a3c3275affd5..d6d7a3ed5062 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc @@ -19,7 +19,8 @@ #include "arrow/scalar.h" #include "arrow/testing/builder.h" #include "arrow/type.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -163,7 +164,7 @@ TEST(ConvertToJson, MonthInterval) { } TEST(ConvertToJson, Duration) { - // TODO: Append TimeUnit on conversion + // GH-47857 TODO: Append TimeUnit on conversion ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::SECOND))); ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::MILLI))); ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::MICRO))); 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 142dac53ab6f..c92012cc84f9 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 @@ -22,6 +22,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/odbc_connection.h" #include "arrow/flight/sql/odbc/odbc_impl/attribute_utils.h" +#include "arrow/flight/sql/odbc/odbc_impl/config/configuration.h" #include "arrow/flight/sql/odbc/odbc_impl/exceptions.h" #include "arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h" #include "arrow/flight/sql/odbc/odbc_impl/odbc_environment.h" @@ -236,8 +237,8 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_COLUMN_ALIAS: case SQL_DBMS_NAME: case SQL_DBMS_VER: - case SQL_DRIVER_NAME: // TODO: This should be the driver's filename and shouldn't - // come from the SPI. + case SQL_DRIVER_NAME: // GH-47858 TODO: This should be the driver's filename and + // shouldn't come from the SPI. case SQL_DRIVER_VER: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: @@ -263,7 +264,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_SPECIAL_CHARACTERS: case SQL_XOPEN_CLI_YEAR: { const auto& info = spi_connection_->GetInfo(info_type); - const std::string& info_value = boost::get(info); + const std::string& info_value = std::get(info); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -353,7 +354,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_SQL92_VALUE_EXPRESSIONS: case SQL_STANDARD_CLI_CONFORMANCE: { const auto& info = spi_connection_->GetInfo(info_type); - uint32_t info_value = boost::get(info); + uint32_t info_value = std::get(info); GetAttribute(info_value, value, buffer_length, output_length); return SQL_SUCCESS; } @@ -388,7 +389,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_ODBC_SQL_CONFORMANCE: case SQL_ODBC_SAG_CLI_CONFORMANCE: { const auto& info = spi_connection_->GetInfo(info_type); - uint16_t info_value = boost::get(info); + uint16_t info_value = std::get(info); GetAttribute(info_value, value, buffer_length, output_length); return SQL_SUCCESS; } @@ -399,7 +400,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, if (!attr) { throw DriverException("Optional feature not supported.", "HYC00"); } - const std::string& info_value = boost::get(*attr); + const std::string& info_value = std::get(*attr); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -417,7 +418,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, bool successfully_written = false; switch (attribute) { // Internal connection attributes -#ifdef SQL_ATR_ASYNC_DBC_EVENT +#ifdef SQL_ATTR_ASYNC_DBC_EVENT case SQL_ATTR_ASYNC_DBC_EVENT: throw DriverException("Optional feature not supported.", "HYC00"); #endif @@ -425,7 +426,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE: throw DriverException("Optional feature not supported.", "HYC00"); #endif -#ifdef SQL_ATTR_ASYNC_PCALLBACK +#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK case SQL_ATTR_ASYNC_DBC_PCALLBACK: throw DriverException("Optional feature not supported.", "HYC00"); #endif @@ -453,7 +454,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, throw DriverException("Cannot set read-only attribute", "HY092"); case SQL_ATTR_TRACE: // DM-only throw DriverException("Cannot set read-only attribute", "HY092"); - case SQL_ATTR_TRACEFILE: + case SQL_ATTR_TRACEFILE: // DM-only throw DriverException("Optional feature not supported.", "HYC00"); case SQL_ATTR_TRANSLATE_LIB: throw DriverException("Optional feature not supported.", "HYC00"); @@ -594,7 +595,7 @@ SQLRETURN ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, if (!catalog) { throw DriverException("Optional feature not supported.", "HYC00"); } - const std::string& info_value = boost::get(*catalog); + const std::string& info_value = std::get(*catalog); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -623,7 +624,7 @@ SQLRETURN ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, throw DriverException("Invalid attribute", "HY092"); } - GetAttribute(static_cast(boost::get(*spi_attribute)), value, + GetAttribute(static_cast(std::get(*spi_attribute)), value, buffer_length, output_length); return SQL_SUCCESS; } 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 d50e99d0b619..4b7519f74a4e 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 @@ -17,8 +17,8 @@ #pragma once -#include #include "arrow/flight/sql/odbc/odbc_impl/odbc_handle.h" +#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" #include "arrow/flight/sql/odbc/odbc_impl/type_fwd.h" #include @@ -37,6 +37,9 @@ class ODBCConnection : public ODBCHandle { ODBCConnection(const ODBCConnection&) = delete; ODBCConnection& operator=(const ODBCConnection&) = delete; + /// \brief Constructor for ODBCConnection. + /// \param[in] environment the parent environment. + /// \param[in] spi_connection the underlying spi connection. ODBCConnection(ODBCEnvironment& environment, std::shared_ptr spi_connection); @@ -44,6 +47,11 @@ class ODBCConnection : public ODBCHandle { const std::string& GetDSN() const; bool IsConnected() const; + + /// \brief Connect to Arrow Flight SQL server. + /// \param[in] dsn the dsn name. + /// \param[in] properties the connection property map extracted from connection string. + /// \param[out] missing_properties report the properties that are missing void Connect(std::string dsn, const arrow::flight::sql::odbc::Connection::ConnPropertyMap& properties, std::vector& missing_properties); @@ -51,7 +59,7 @@ class ODBCConnection : public ODBCHandle { SQLRETURN GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, SQLSMALLINT buffer_length, SQLSMALLINT* output_length, bool is_unicode); void SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length, - bool isUnicode); + bool is_unicode); SQLRETURN GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER* output_length, bool is_unicode); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc index e54fbf601eb6..ebb69720c887 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc @@ -64,7 +64,7 @@ ODBCDescriptor::ODBCDescriptor(Diagnostics& base_diagnostics, ODBCConnection* co parent_statement_(stmt), array_status_ptr_(nullptr), bind_offset_ptr_(nullptr), - rows_processed_ptr_(nullptr), + rows_proccessed_ptr_(nullptr), array_size_(1), bind_type_(SQL_BIND_BY_COLUMN), highest_one_based_bound_record_(0), @@ -111,7 +111,7 @@ void ODBCDescriptor::SetHeaderField(SQLSMALLINT field_identifier, SQLPOINTER val has_bindings_changed_ = true; break; case SQL_DESC_ROWS_PROCESSED_PTR: - SetPointerAttribute(value, rows_processed_ptr_); + SetPointerAttribute(value, rows_proccessed_ptr_); has_bindings_changed_ = true; break; case SQL_DESC_COUNT: { @@ -275,7 +275,7 @@ void ODBCDescriptor::GetHeaderField(SQLSMALLINT field_identifier, SQLPOINTER val GetAttribute(bind_type_, value, buffer_length, output_length); break; case SQL_DESC_ROWS_PROCESSED_PTR: - GetAttribute(rows_processed_ptr_, value, buffer_length, output_length); + GetAttribute(rows_proccessed_ptr_, value, buffer_length, output_length); break; case SQL_DESC_COUNT: { // highest_one_based_bound_record_ equals number of records + 1 @@ -509,10 +509,12 @@ void ODBCDescriptor::PopulateFromResultSetMetadata(ResultSetMetadata* rsmd) { rsmd->IsAutoUnique(one_based_index) ? SQL_TRUE : SQL_FALSE; records_[i].case_sensitive = rsmd->IsCaseSensitive(one_based_index) ? SQL_TRUE : SQL_FALSE; - records_[i].datetime_interval_precision; // TODO - update when rsmd adds this + records_[i].datetime_interval_precision; // GH-47869 TODO implement + // `SQL_DESC_DATETIME_INTERVAL_PRECISION` SQLINTEGER num_prec_radix = rsmd->GetNumPrecRadix(one_based_index); records_[i].num_prec_radix = num_prec_radix > 0 ? num_prec_radix : 0; - records_[i].datetime_interval_code; // TODO + records_[i].datetime_interval_code; // GH-47868 TODO implement + // `SQL_DESC_DATETIME_INTERVAL_CODE` records_[i].fixed_prec_scale = rsmd->IsFixedPrecScale(one_based_index) ? SQL_TRUE : SQL_FALSE; records_[i].nullable = rsmd->IsNullable(one_based_index); @@ -581,5 +583,5 @@ void ODBCDescriptor::SetDataPtrOnRecord(SQLPOINTER data_ptr, SQLSMALLINT record_ } void DescriptorRecord::CheckConsistency() { - // TODO + // GH-47870 TODO implement } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h index f0259d40098c..7d59db91b6ef 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h @@ -121,8 +121,8 @@ class ODBCDescriptor : public ODBCHandle { inline SQLUSMALLINT* GetArrayStatusPtr() { return array_status_ptr_; } inline void SetRowsProcessed(SQLULEN rows) { - if (rows_processed_ptr_) { - *rows_processed_ptr_ = rows; + if (rows_proccessed_ptr_) { + *rows_proccessed_ptr_ = rows; } } @@ -139,7 +139,7 @@ class ODBCDescriptor : public ODBCHandle { ODBCStatement* parent_statement_; SQLUSMALLINT* array_status_ptr_; SQLULEN* bind_offset_ptr_; - SQLULEN* rows_processed_ptr_; + SQLULEN* rows_proccessed_ptr_; SQLULEN array_size_; SQLINTEGER bind_type_; SQLSMALLINT highest_one_based_bound_record_; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h index 9dd8fe37baf6..4674a4c9ff16 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h @@ -17,13 +17,14 @@ #pragma once -#include -#include +// platform.h includes windows.h, so it needs to be included first +#include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include #include #include #include +#include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" /** * @brief An abstraction over a generic ODBC handle. diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc index 51152c64782e..02579aaf5f74 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -255,7 +254,7 @@ void ODBCStatement::CopyAttributesFromConnection(ODBCConnection& connection) { ODBCStatement& tracking_statement = connection.GetTrackingStatement(); // Get abstraction attributes and copy to this spi_statement_. - // Possible ODBC attributes are below, but many of these are not supported by warpdrive + // Possible ODBC attributes are below, but many of these are not supported by Arrow ODBC // or ODBCAbstaction: // SQL_ATTR_ASYNC_ENABLE: // SQL_ATTR_METADATA_ID: @@ -333,7 +332,7 @@ bool ODBCStatement::Fetch(size_t rows, SQLULEN* row_count_ptr, } if (current_ard_->HaveBindingsChanged()) { - // TODO: Deal handle when offset != buffer_length. + // GH-47871 TODO: handle when offset != buffer_length. // Wipe out all bindings in the ResultSet. // Note that the number of ARD records can both be more or less @@ -541,7 +540,7 @@ void ODBCStatement::GetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER outpu } if (spi_attribute) { - GetAttribute(static_cast(boost::get(*spi_attribute)), output, + GetAttribute(static_cast(std::get(*spi_attribute)), output, buffer_size, str_len_ptr); return; } @@ -625,6 +624,7 @@ void ODBCStatement::SetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER value return; case SQL_ATTR_ASYNC_ENABLE: + throw DriverException("Unsupported attribute", "HYC00"); #ifdef SQL_ATTR_ASYNC_STMT_EVENT case SQL_ATTR_ASYNC_STMT_EVENT: throw DriverException("Unsupported attribute", "HYC00"); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h index b5ee264f5544..f2226e84f6c9 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h @@ -17,10 +17,12 @@ #pragma once +// platform.h platform.h includes windows.h so it needs to be included first +#include "arrow/flight/sql/odbc/odbc_impl/platform.h" + #include "arrow/flight/sql/odbc/odbc_impl/odbc_handle.h" #include "arrow/flight/sql/odbc/odbc_impl/type_fwd.h" -#include #include #include #include @@ -57,7 +59,6 @@ class ODBCStatement : public ODBCHandle { /// row_count_ptr and row_status_array are optional arguments, they are only needed for /// SQLExtendedFetch bool Fetch(size_t rows, SQLULEN* row_count_ptr = 0, SQLUSMALLINT* row_status_array = 0); - bool IsPrepared() const; void GetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER output, diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc index cf1e5930a827..3749c276d4f3 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc @@ -18,7 +18,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h" #include "arrow/flight/sql/odbc/odbc_impl/platform.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h index 539583aac29f..15548b52c63d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h @@ -17,9 +17,9 @@ #pragma once -#include -#include #include +#include "arrow/flight/client.h" +#include "arrow/type.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc index 9727167a500c..a5e094317ead 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc @@ -20,7 +20,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include "arrow/record_batch.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { namespace { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h index f4855812bf93..e9cf18dc55a3 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h @@ -17,7 +17,7 @@ #pragma once -#include +#include "arrow/type.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h index 42dc4d8edb15..3e4c08c9cdd2 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h @@ -19,11 +19,11 @@ #define BOOST_NO_CXX98_FUNCTION_BASE // ARROW-17805 #include -#include #include #include #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -67,8 +67,8 @@ class Connection { PACKET_SIZE, // uint32_t - The Packet Size }; - typedef boost::variant Attribute; - typedef boost::variant Info; + typedef std::variant Attribute; + typedef std::variant Info; typedef PropertyMap ConnPropertyMap; /// \brief Establish the connection. diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h index bdfeea3b79da..f5157b00bc2c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h @@ -17,9 +17,9 @@ #pragma once -#include #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -51,7 +51,7 @@ class Statement { QUERY_TIMEOUT, }; - typedef boost::variant Attribute; + typedef std::variant Attribute; /// \brief Set a statement attribute (may be called at any time) /// diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc index 47149a33a560..ff8416a43a86 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/exceptions.h" diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc index 0432836a16f8..be6b3fe4799b 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc @@ -44,9 +44,9 @@ std::string TestConnection(const config::Configuration& config) { // This should have been checked before enabling the Test button. assert(missing_properties.empty()); std::string server_name = - boost::get(flight_sql_conn->GetInfo(SQL_SERVER_NAME)); + std::get(flight_sql_conn->GetInfo(SQL_SERVER_NAME)); std::string server_version = - boost::get(flight_sql_conn->GetInfo(SQL_DBMS_VER)); + std::get(flight_sql_conn->GetInfo(SQL_DBMS_VER)); return "Server Name: " + server_name + "\n" + "Server Version: " + server_version; } } // namespace @@ -565,7 +565,7 @@ bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wparam, LPARAM lparam) { open_file_name.lpstrFile = file_name; open_file_name.lpstrFile[0] = '\0'; open_file_name.nMaxFile = FILENAME_MAX; - // TODO: What type should this be? + // GH-47851 TODO: Update `lpstrFilter` to correct value open_file_name.lpstrFilter = L"All\0*.*"; open_file_name.nFilterIndex = 1; open_file_name.lpstrFileTitle = NULL; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc index f21329977ba2..ce10ddd3bf9e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc @@ -36,7 +36,6 @@ HINSTANCE GetHInstance() { TCHAR sz_file_name[MAX_PATH]; GetModuleFileName(NULL, sz_file_name, MAX_PATH); - // TODO: This needs to be the module name. HINSTANCE h_instance = GetModuleHandle(sz_file_name); if (h_instance == NULL) { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc index fe6a2d4d7c38..6792f7f7f52a 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc @@ -117,12 +117,13 @@ SqlDataType GetDataTypeFromArrowFieldV3(const std::shared_ptr& field, case Type::TIME64: return SqlDataType_TYPE_TIME; case Type::INTERVAL_MONTHS: - return SqlDataType_INTERVAL_MONTH; // TODO: maybe - // SqlDataType_INTERVAL_YEAR_TO_MONTH + return SqlDataType_INTERVAL_MONTH; // GH-47873 TODO: check and update to + // SqlDataType_INTERVAL_YEAR_TO_MONTH if it is + // more appropriate case Type::INTERVAL_DAY_TIME: return SqlDataType_INTERVAL_DAY; - // TODO: Handle remaining types. + // GH-47873 TODO: Handle remaining types. case Type::INTERVAL_MONTH_DAY_NANO: case Type::LIST: case Type::STRUCT: @@ -671,7 +672,7 @@ optional GetDisplaySize(SqlDataType data_type, case SqlDataType_INTERVAL_HOUR_TO_MINUTE: case SqlDataType_INTERVAL_HOUR_TO_SECOND: case SqlDataType_INTERVAL_MINUTE_TO_SECOND: - return nullopt; // TODO: Implement for INTERVAL types + return nullopt; // GH-47874 TODO: Implement for INTERVAL types case SqlDataType_GUID: return 36; default: @@ -938,9 +939,9 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type auto seconds_from_epoch = GetTodayTimeFromEpoch(); - auto third_converted_array = CheckConversion( - arrow::compute::Add(second_converted_array, - std::make_shared(seconds_from_epoch * 1000))); + auto third_converted_array = CheckConversion(arrow::compute::Add( + second_converted_array, + std::make_shared(seconds_from_epoch * 1000))); arrow::compute::CastOptions cast_options_2; cast_options_2.to_type = arrow::timestamp(TimeUnit::MILLI); @@ -959,7 +960,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type auto second_converted_array = CheckConversion(arrow::compute::Add( first_converted_array, - std::make_shared(seconds_from_epoch * 1000000000))); + std::make_shared(seconds_from_epoch * 1000000000))); arrow::compute::CastOptions cast_options_2; cast_options_2.to_type = arrow::timestamp(TimeUnit::NANO); @@ -983,7 +984,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type } else if (original_type_id == Type::DECIMAL128 && (target_type == CDataType_CHAR || target_type == CDataType_WCHAR)) { return [=](const std::shared_ptr& original_array) { - StringBuilder builder; + arrow::StringBuilder builder; int64_t length = original_array->length(); ThrowIfNotOK(builder.ReserveData(length)); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h index 63ce6d6549d6..b6165d1f5161 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h @@ -73,7 +73,7 @@ inline void ThrowIfNotOK(const Status& status) { template inline bool CheckIfSetToOnlyValidValue(const AttributeTypeT& value, T allowed_value) { - return boost::get(value) == allowed_value; + return std::get(value) == allowed_value; } template diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc index bfcec15b4dac..c5f4ac5c2c47 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc @@ -23,7 +23,8 @@ #include "arrow/testing/builder.h" #include "arrow/testing/gtest_util.h" #include "arrow/testing/util.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -48,7 +49,7 @@ void AssertConvertedArray(const std::shared_ptr& expected_array, ASSERT_EQ(expected_array->ToString(), converted_array->ToString()); } -std::shared_ptr convertArray(const std::shared_ptr& original_array, +std::shared_ptr ConvertArray(const std::shared_ptr& original_array, CDataType c_type) { auto converter = util::GetConverter(original_array->type_id(), c_type); return converter(original_array); @@ -60,7 +61,7 @@ void TestArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } @@ -71,7 +72,7 @@ void TestTime32ArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(time32(TimeUnit::MILLI), input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } @@ -82,7 +83,7 @@ void TestTime64ArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(time64(TimeUnit::NANO), input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/README b/cpp/src/arrow/flight/sql/odbc/tests/README new file mode 100644 index 000000000000..fe74c98b72f1 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/README @@ -0,0 +1,23 @@ + + +Prior to running the tests, set environment variable `ARROW_FLIGHT_SQL_ODBC_CONN` +to a valid connection string. +A valid connection string looks like: +driver={Apache Arrow Flight SQL ODBC Driver};HOST=localhost;port=32010;pwd=myPassword;uid=myName;useEncryption=false; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml new file mode 100644 index 000000000000..eaab4d02b731 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml @@ -0,0 +1,35 @@ +# 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. + +# GH-48068 TODO: run remote ODBC tests on Linux + +services: + dremio: + platform: linux/x86_64 + image: dremio/dremio-oss:latest + ports: + - 9047:9047 # REST API + - 31010:31010 # JDBC/ODBC + - 32010:32010 + container_name: dremio_container + environment: + - DREMIO_JAVA_SERVER_EXTRA_OPTS=-Dsaffron.default.charset=UTF-8 -Dsaffron.default.nationalcharset=UTF-8 -Dsaffron.default.collation.name=UTF-8$$en_US + healthcheck: + test: curl --fail http://localhost:9047 || exit 1 + interval: 10s + timeout: 5s + retries: 30 diff --git a/cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh b/cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh new file mode 100644 index 000000000000..8d632bb2c3e1 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh @@ -0,0 +1,66 @@ +# 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. + +# GH-48068 TODO: run remote ODBC tests on Linux + +#!/bin/bash +set -e + +HOST_URL="http://localhost:9047" +NEW_USER_URL="$HOST_URL/apiv2/bootstrap/firstuser" +LOGIN_URL="$HOST_URL/apiv2/login" +SQL_URL="$HOST_URL/api/v3/sql" + +ADMIN_USER="admin" +ADMIN_PASSWORD="admin2025" + +# Wait for Dremio to be available. +until curl -s "$NEW_USER_URL"; do + echo 'Waiting for Dremio to start...' + sleep 5 +done + +echo "" +echo 'Creating admin user...' + +# Create new admin account. +curl -X PUT "$NEW_USER_URL" \ + -H "Content-Type: application/json" \ + -d "{ \"userName\": \"$ADMIN_USER\", \"password\": \"$ADMIN_PASSWORD\" }" + +echo "" +echo "Created admin user." + +# Use admin account to login and acquire a token. +TOKEN=$(curl -s -X POST "$LOGIN_URL" \ + -H "Content-Type: application/json" \ + -d "{ \"userName\": \"$ADMIN_USER\", \"password\": \"$ADMIN_PASSWORD\" }" \ + | grep -oP '(?<="token":")[^"]+') + +SQL_QUERY="Create Table \$scratch.ODBCTest As SELECT CAST(2147483647 AS INTEGER) AS sinteger_max, CAST(9223372036854775807 AS BIGINT) AS sbigint_max, CAST(999999999 AS DECIMAL(38,0)) AS decimal_positive, CAST(3.40282347E38 AS FLOAT) AS float_max, CAST(1.7976931348623157E308 AS DOUBLE) AS double_max, CAST(true AS BOOLEAN) AS bit_true, CAST(DATE '9999-12-31' AS DATE) AS date_max, CAST(TIME '23:59:59' AS TIME) AS time_max, CAST(TIMESTAMP '9999-12-31 23:59:59' AS TIMESTAMP) AS timestamp_max;" +ESCAPED_QUERY=$(printf '%s' "$SQL_QUERY" | sed 's/"/\\"/g') + +echo "Creating \$scratch.ODBCTest table." + +# Create a new table by sending a SQL query. +curl -i -X POST "$SQL_URL" \ + -H "Authorization: _dremio$TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"sql\": \"$ESCAPED_QUERY\"}" + +echo "" +echo "Finished setting up dremio docker instance." diff --git a/cpp/vcpkg.json b/cpp/vcpkg.json index ba3c8e1851b0..5fa97292ff01 100644 --- a/cpp/vcpkg.json +++ b/cpp/vcpkg.json @@ -21,10 +21,8 @@ "boost-filesystem", "boost-locale", "boost-multiprecision", - "boost-optional", "boost-process", "boost-system", - "boost-variant", "boost-xpressive", "brotli", "bzip2", From 0428407701d8127e30908f64909217cbebaabe37 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:43:26 -0700 Subject: [PATCH 02/17] Get test suite building on Linux --- ci/scripts/cpp_test.sh | 1 + cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 5 +- .../flight/sql/odbc/tests/columns_test.cc | 391 ++++----- .../sql/odbc/tests/connection_info_test.cc | 271 +++--- .../flight/sql/odbc/tests/connection_test.cc | 6 +- .../flight/sql/odbc/tests/errors_test.cc | 42 +- .../flight/sql/odbc/tests/odbc_test_suite.cc | 21 +- .../flight/sql/odbc/tests/odbc_test_suite.h | 19 + .../sql/odbc/tests/statement_attr_test.cc | 3 +- .../flight/sql/odbc/tests/statement_test.cc | 208 ++--- .../flight/sql/odbc/tests/tables_test.cc | 180 ++-- .../flight/sql/odbc/tests/type_info_test.cc | 772 +++++++++--------- 12 files changed, 921 insertions(+), 998 deletions(-) diff --git a/ci/scripts/cpp_test.sh b/ci/scripts/cpp_test.sh index 241addbfebd2..2f88cdc819b2 100755 --- a/ci/scripts/cpp_test.sh +++ b/ci/scripts/cpp_test.sh @@ -55,6 +55,7 @@ if ! type minio >/dev/null 2>&1; then fi case "$(uname)" in Linux) + exclude_tests+=("arrow-flight-sql-odbc-test") n_jobs=$(nproc) ;; Darwin) diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 4227873706ff..48fab25a29b1 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -29,10 +29,7 @@ endif() add_subdirectory(odbc_impl) if(ARROW_BUILD_TESTS) - if(WIN32 OR APPLE) - # GH-49552 TODO: Enable Linux test build - add_subdirectory(tests) - endif() + add_subdirectory(tests) endif() arrow_install_all_headers("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 d88a569c8ffc..e4468d277ff4 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -364,7 +364,6 @@ void GetSQLColAttributeNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMAL ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - SQLLEN num_val = 0; ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, field_identifier, 0, 0, nullptr, value)); } @@ -379,7 +378,6 @@ void GetSQLColAttributesNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMA ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - SQLLEN num_val = 0; ASSERT_EQ(SQL_SUCCESS, SQLColAttributes(stmt, idx, field_identifier, 0, 0, nullptr, value)); } @@ -387,10 +385,10 @@ void GetSQLColAttributesNumeric(SQLHSTMT stmt, const std::wstring& wsql, SQLUSMA } // namespace TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) { - SQLWCHAR catalog_name[] = L""; - SQLWCHAR schema_name[] = L""; - SQLWCHAR table_name[] = L""; - SQLWCHAR column_name[] = L""; + SQLWCHAR catalog_name[] = {0}; + SQLWCHAR schema_name[] = {0}; + SQLWCHAR table_name[] = {0}; + SQLWCHAR column_name[] = {0}; // All values populated EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, catalog_name, sizeof(catalog_name), schema_name, @@ -421,8 +419,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { // Check table pattern and column pattern returns all columns // Attempt to get all columns - SQLWCHAR table_pattern[] = L"%"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"%"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -446,7 +444,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -467,7 +465,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 0, // expected_octet_char_length 2, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -487,7 +485,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 3, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -507,7 +505,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -528,7 +526,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 0, // expected_octet_char_length 2, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -548,7 +546,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 3, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -568,7 +566,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 4, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -583,8 +581,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { CreateAllDataTypeTable(); // Attempt to get all columns from AllTypesTable - SQLWCHAR table_pattern[] = L"AllTypesTable"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"AllTypesTable"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -606,7 +604,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -627,7 +625,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 0, // expected_octet_char_length 2, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -648,7 +646,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BINARY, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 0, // expected_octet_char_length 3, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -668,7 +666,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { 2, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 4, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -686,8 +684,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { CreateUnicodeTable(); // Attempt to get all columns - SQLWCHAR table_pattern[] = L"数据"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"数据"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -708,7 +706,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 0, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -723,8 +721,8 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { // GH-47159 TODO: Return NUM_PREC_RADIX based on whether COLUMN_SIZE contains number of // digits or bits - SQLWCHAR table_pattern[] = L"ODBCTest"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"ODBCTest"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -745,7 +743,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_INTEGER, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 4, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -766,7 +764,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 2, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -786,7 +784,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_DECIMAL, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 2, // expected_octet_char_length 3, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -806,7 +804,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 2, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_FLOAT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 4, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -826,7 +824,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 2, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 5, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -847,7 +845,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 1, // expected_octet_char_length 6, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -926,8 +924,8 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { // GH-47159 TODO: Return NUM_PREC_RADIX based on whether COLUMN_SIZE contains number of // digits or bits - SQLWCHAR table_pattern[] = L"ODBCTest"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"ODBCTest"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -948,7 +946,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_INTEGER, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 4, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -969,7 +967,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 2, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -989,7 +987,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_DECIMAL, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 2, // expected_octet_char_length 3, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1009,7 +1007,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 2, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_FLOAT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 4, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1029,7 +1027,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 2, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 5, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1050,7 +1048,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { 0, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 1, // expected_octet_char_length 6, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1128,8 +1126,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { // Checks filtering table with column name pattern. // Only check table and column name - SQLWCHAR table_pattern[] = L"%"; - SQLWCHAR column_pattern[] = L"id"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"%"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"id"); EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -1149,7 +1147,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1169,7 +1167,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1182,8 +1180,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { // Checks filtering table with table and column name pattern. // Only check table and column name - SQLWCHAR table_pattern[] = L"foreignTable"; - SQLWCHAR column_pattern[] = L"id"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"foreignTable"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"id"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -1203,7 +1201,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { 10, // expected_num_prec_radix SQL_NULLABLE, // expected_nullable SQL_BIGINT, // expected_sql_data_type - NULL, // expected_date_time_sub + 0, // expected_date_time_sub 8, // expected_octet_char_length 1, // expected_ordinal_position std::wstring(L"YES")); // expected_is_nullable @@ -1213,8 +1211,8 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { } TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { - SQLWCHAR table_pattern[] = L"non-existent-table"; - SQLWCHAR column_pattern[] = L"%"; + ASSIGN_SQLWCHAR_ARR(table_pattern, L"non-existent-table"); + ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); @@ -1224,8 +1222,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { } TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { - SQLWCHAR wsql[] = L"SELECT 1 as col1;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)) << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); @@ -1238,9 +1235,8 @@ TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { SQLLEN numeric_attr = 0; // All character values populated - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_NAME, character_attr, - std::wcslen(character_attr), &character_attr_len, nullptr)); + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_NAME, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // All numeric values populated EXPECT_EQ(SQL_SUCCESS, @@ -1255,8 +1251,7 @@ TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { } TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { - SQLWCHAR wsql[] = L"SELECT 1 as col1;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1271,8 +1266,7 @@ TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { } TYPED_TEST(ColumnsTest, SQLColAttributeInvalidFieldId) { - SQLWCHAR wsql[] = L"SELECT 1 as col1;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1282,18 +1276,15 @@ TYPED_TEST(ColumnsTest, SQLColAttributeInvalidFieldId) { SQLUSMALLINT idx = 1; SQLWCHAR character_attr[kOdbcBufferSize]; SQLSMALLINT character_attr_len = 0; - SQLLEN numeric_attr = 0; - ASSERT_EQ(SQL_ERROR, - SQLColAttribute(stmt, idx, invalid_field_id, character_attr, - std::wcslen(character_attr), &character_attr_len, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLColAttribute(stmt, idx, invalid_field_id, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor field identifier error state is returned VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY091); } TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { - SQLWCHAR wsql[] = L"SELECT 1 as col1;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1304,7 +1295,7 @@ TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { SQLSMALLINT character_attr_len = 0; ASSERT_EQ(SQL_ERROR, SQLColAttribute(stmt, invalid_col_id, SQL_DESC_BASE_COLUMN_NAME, - character_attr, std::wcslen(character_attr), + character_attr, kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor index error state is returned VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); @@ -1313,8 +1304,7 @@ TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { CreateAllDataTypeTable(); - SQLWCHAR wsql[] = L"SELECT * from AllTypesTable;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from AllTypesTable;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1397,8 +1387,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { // Tests ODBC 2.0 API SQLColAttributes CreateAllDataTypeTable(); - SQLWCHAR wsql[] = L"SELECT * from AllTypesTable;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from AllTypesTable;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1458,8 +1447,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { // Test assumes there is a table $scratch.ODBCTest in remote server - SQLWCHAR wsql[] = L"SELECT * from $scratch.ODBCTest;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1623,8 +1611,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { #ifndef __APPLE__ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { // Test assumes there is a table $scratch.ODBCTest in remote server - SQLWCHAR wsql[] = L"SELECT * from $scratch.ODBCTest;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1788,8 +1775,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { // Tests ODBC 2.0 API SQLColAttributes // Test assumes there is a table $scratch.ODBCTest in remote server - SQLWCHAR wsql[] = L"SELECT * from $scratch.ODBCTest;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -2239,22 +2225,20 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesUpdatable) { TEST_F(ColumnsMockTest, SQLDescribeColValidateInput) { CreateTestTable(); - SQLWCHAR sql_query[] = L"SELECT * FROM TestTable LIMIT 1;"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * FROM TestTable LIMIT 1;"); SQLUSMALLINT bookmark_column = 0; SQLUSMALLINT out_of_range_column = 4; SQLUSMALLINT negative_column = -1; SQLWCHAR column_name[1024] = {0}; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT data_type = 0; SQLULEN column_size = 0; SQLSMALLINT decimal_digits = 0; SQLSMALLINT nullable = 0; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2289,8 +2273,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { // from SELECT AS queries SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2301,38 +2284,15 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); - 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")}; + const std::wstring column_names[] = { + L"stiny_int_min", L"stiny_int_max", L"utiny_int_min", L"utiny_int_max", + L"ssmall_int_min", L"ssmall_int_max", L"usmall_int_min", L"usmall_int_max", + L"sinteger_min", L"sinteger_max", L"uinteger_min", L"uinteger_max", + L"sbigint_min", L"sbigint_max", L"ubigint_min", L"ubigint_max", + L"decimal_negative", L"decimal_positive", L"float_min", L"float_max", + L"double_min", L"double_max", L"bit_false", L"bit_true", + L"c_char", L"c_wchar", L"c_wvarchar", L"c_varchar", + L"date_min", L"date_max", L"timestamp_min", 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, @@ -2352,7 +2312,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2371,8 +2331,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2383,38 +2342,15 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); - 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")}; + const std::wstring column_names[] = { + L"stiny_int_min", L"stiny_int_max", L"utiny_int_min", L"utiny_int_max", + L"ssmall_int_min", L"ssmall_int_max", L"usmall_int_min", L"usmall_int_max", + L"sinteger_min", L"sinteger_max", L"uinteger_min", L"uinteger_max", + L"sbigint_min", L"sbigint_max", L"ubigint_min", L"ubigint_max", + L"decimal_negative", L"decimal_positive", L"float_min", L"float_max", + L"double_min", L"double_max", L"bit_false", L"bit_true", + L"c_char", L"c_wchar", L"c_wvarchar", L"c_varchar", + L"date_min", L"date_max", L"timestamp_min", 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, @@ -2441,7 +2377,7 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2462,8 +2398,7 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { // Test assumes there is a table $scratch.ODBCTest in remote server SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2471,25 +2406,19 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR sql_query[] = L"SELECT * from $scratch.ODBCTest LIMIT 1;"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); - - 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")}; + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from $scratch.ODBCTest LIMIT 1;"); + + const std::wstring column_names[] = { + L"sinteger_max", L"sbigint_max", L"decimal_positive", + L"float_max", L"double_max", L"bit_true", + L"date_max", L"time_max", 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}; SQLULEN column_sizes[] = {4, 8, 19, 8, 8, 1, 10, 12, 23}; SQLULEN columndecimal_digits[] = {0, 0, 0, 0, 0, 0, 10, 12, 23}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2500,7 +2429,7 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2520,8 +2449,7 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBCVer2) { // Test assumes there is a table $scratch.ODBCTest in remote server SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2529,25 +2457,19 @@ TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBCVer2) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR sql_query[] = L"SELECT * from $scratch.ODBCTest LIMIT 1;"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); - - 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")}; + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from $scratch.ODBCTest LIMIT 1;"); + + const std::wstring column_names[] = { + L"sinteger_max", L"sbigint_max", L"decimal_positive", + L"float_max", L"double_max", L"bit_true", + L"date_max", L"time_max", 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}; SQLULEN column_sizes[] = {4, 8, 19, 8, 8, 1, 10, 12, 23}; SQLULEN columndecimal_digits[] = {0, 0, 0, 0, 0, 0, 10, 12, 23}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2558,7 +2480,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBCVer2) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2579,8 +2501,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { CreateAllDataTypeTable(); SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2588,17 +2509,14 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { SQLSMALLINT nullable = 0; size_t column_index = 0; - SQLWCHAR sql_query[] = L"SELECT * from AllTypesTable LIMIT 1;"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from AllTypesTable LIMIT 1;"); - const SQLWCHAR* column_names[] = {static_cast(L"bigint_col"), - static_cast(L"char_col"), - static_cast(L"varbinary_col"), - static_cast(L"double_col")}; + const std::wstring column_names[] = {L"bigint_col", L"char_col", L"varbinary_col", + L"double_col"}; SQLSMALLINT column_data_types[] = {SQL_BIGINT, SQL_WVARCHAR, SQL_BINARY, SQL_DOUBLE}; SQLULEN column_sizes[] = {8, 0, 0, 8}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2609,7 +2527,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2632,8 +2550,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { CreateUnicodeTable(); SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2641,14 +2558,13 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { SQLSMALLINT nullable = 0; size_t column_index = 1; - SQLWCHAR sql_query[] = L"SELECT * from 数据 LIMIT 1;"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from 数据 LIMIT 1;"); - SQLWCHAR expected_column_name[] = L"资料"; + 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(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2656,12 +2572,13 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { SQLDescribeCol(stmt, column_index, column_name, buf_char_len, &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(name_length, wcslen(expected_column_name)); + EXPECT_EQ(name_length, expected_column_name_len); std::wstring returned(column_name, column_name + name_length); - EXPECT_EQ(returned, expected_column_name); - EXPECT_EQ(column_data_type, expected_column_data_type); - EXPECT_EQ(column_size, expected_column_size); + 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(0, decimal_digits); EXPECT_EQ(SQL_NULLABLE, nullable); @@ -2670,8 +2587,7 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2679,24 +2595,12 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { SQLSMALLINT nullable = 0; size_t column_index = 0; - 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")}; + const std::wstring column_names[] = { + L"TABLE_CAT", L"TABLE_SCHEM", L"TABLE_NAME", L"COLUMN_NAME", + L"DATA_TYPE", L"TYPE_NAME", L"COLUMN_SIZE", L"BUFFER_LENGTH", + L"DECIMAL_DIGITS", L"NUM_PREC_RADIX", L"NULLABLE", L"REMARKS", + L"COLUMN_DEF", L"SQL_DATA_TYPE", L"SQL_DATETIME_SUB", L"CHAR_OCTET_LENGTH", + L"ORDINAL_POSITION", 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, @@ -2714,7 +2618,7 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -2733,8 +2637,7 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBCVer2) { SQLWCHAR column_name[1024]; - SQLSMALLINT buf_char_len = - static_cast(sizeof(column_name) / GetSqlWCharSize()); + SQLSMALLINT buf_char_len = sizeof(column_name) / GetSqlWCharSize(); SQLSMALLINT name_length = 0; SQLSMALLINT column_data_type = 0; SQLULEN column_size = 0; @@ -2742,24 +2645,24 @@ TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBCVer2) { SQLSMALLINT nullable = 0; size_t column_index = 0; - 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")}; + const std::wstring column_names[] = {L"TABLE_QUALIFIER", + L"TABLE_OWNER", + L"TABLE_NAME", + L"COLUMN_NAME", + L"DATA_TYPE", + L"TYPE_NAME", + L"PRECISION", + L"LENGTH", + L"SCALE", + L"RADIX", + L"NULLABLE", + L"REMARKS", + L"COLUMN_DEF", + L"SQL_DATA_TYPE", + L"SQL_DATETIME_SUB", + L"CHAR_OCTET_LENGTH", + L"ORDINAL_POSITION", + 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, @@ -2777,7 +2680,7 @@ TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBCVer2) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); 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 e39433fa979f..cbd23e5647f8 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 @@ -64,8 +64,8 @@ void GetInfo(SQLHDBC connection, SQLUSMALLINT info_type, SQLULEN* value) { } // Get SQLWCHAR return value -void GetInfo(SQLHDBC connection, SQLUSMALLINT info_type, SQLWCHAR* value, - SQLSMALLINT buf_len = kOdbcBufferSize) { +void GetInfoSQLWCHAR(SQLHDBC connection, SQLUSMALLINT info_type, SQLWCHAR* value, + SQLSMALLINT buf_len = kOdbcBufferSize) { SQLSMALLINT message_length; ASSERT_EQ(SQL_SUCCESS, @@ -75,7 +75,7 @@ void GetInfo(SQLHDBC connection, SQLUSMALLINT info_type, SQLWCHAR* value, TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTruncation) { static constexpr int info_len = 1; - SQLWCHAR value[info_len] = L""; + SQLWCHAR value[info_len] = {}; SQLSMALLINT message_length; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, @@ -135,10 +135,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchSupport) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DATA_SOURCE_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DATA_SOURCE_NAME, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } #ifdef SQL_DRIVER_AWARE_POOLING_SUPPORTED @@ -205,24 +206,27 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHstmt) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DRIVER_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DRIVER_NAME, value); - EXPECT_STREQ(static_cast(L"Arrow Flight ODBC Driver"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"Arrow Flight ODBC Driver"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverOdbcVer) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DRIVER_ODBC_VER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DRIVER_ODBC_VER, value); - EXPECT_STREQ(static_cast(L"03.80"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"03.80"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverVer) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DRIVER_VER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DRIVER_VER, value); - EXPECT_STREQ(static_cast(L"00.09.0000.0"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"00.09.0000.0"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDynamicCursorAttributes1) { @@ -320,13 +324,15 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcInterfaceConformance) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcVer) { // This is implemented only in the Driver Manager. - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ODBC_VER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_ODBC_VER, value); + + std::wstring result = ConvertToWString(value); #ifdef __APPLE__ - EXPECT_STREQ(static_cast(L"03.52.0000"), value); + EXPECT_EQ(std::wstring(L"03.52.0000"), result); #else - EXPECT_STREQ(static_cast(L"03.80.0000"), value); + EXPECT_EQ(std::wstring(L"03.80.0000"), result); #endif // __APPLE__ } @@ -345,24 +351,26 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArraySelects) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoRowUpdates) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ROW_UPDATES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_ROW_UPDATES, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSearchPatternEscape) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_SEARCH_PATTERN_ESCAPE, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_SEARCH_PATTERN_ESCAPE, value); - EXPECT_STREQ(static_cast(L"\\"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"\\"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoServerName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_SERVER_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_SERVER_NAME, value); - EXPECT_GT(wcslen(value), 0); + EXPECT_GT(wcslen(reinterpret_cast(value)), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes1) { @@ -382,40 +390,43 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes2) { // DBMS Product Information TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDatabaseName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DATABASE_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DATABASE_NAME, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DBMS_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DBMS_NAME, value); - EXPECT_GT(wcslen(value), 0); + EXPECT_GT(wcslen(reinterpret_cast(value)), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DBMS_VER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DBMS_VER, value); - EXPECT_GT(wcslen(value), 0); + EXPECT_GT(wcslen(reinterpret_cast(value)), 0); } // Data Source Information TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleProcedures) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ACCESSIBLE_PROCEDURES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_ACCESSIBLE_PROCEDURES, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleTables) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ACCESSIBLE_TABLES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_ACCESSIBLE_TABLES, value); - EXPECT_STREQ(static_cast(L"Y"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"Y"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBookmarkPersistence) { @@ -426,17 +437,19 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBookmarkPersistence) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_CATALOG_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_CATALOG_TERM, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCollationSeq) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_COLLATION_SEQ, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_COLLATION_SEQ, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConcatNullBehavior) { @@ -468,10 +481,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorSensitivity) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceReadOnly) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DATA_SOURCE_READ_ONLY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DATA_SOURCE_READ_ONLY, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDefaultTxnIsolation) { @@ -482,31 +496,35 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDefaultTxnIsolation) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDescribeParameter) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DESCRIBE_PARAMETER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_DESCRIBE_PARAMETER, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultResultSets) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_MULT_RESULT_SETS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_MULT_RESULT_SETS, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultipleActiveTxn) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_MULTIPLE_ACTIVE_TXN, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_MULTIPLE_ACTIVE_TXN, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoNeedLongDataLen) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_NEED_LONG_DATA_LEN, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_NEED_LONG_DATA_LEN, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNullCollation) { @@ -516,17 +534,19 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNullCollation) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoProcedureTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_PROCEDURE_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_PROCEDURE_TERM, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_SCHEMA_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_SCHEMA_TERM, value); - EXPECT_STREQ(static_cast(L"schema"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"schema"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoScrollOptions) { @@ -537,10 +557,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoScrollOptions) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTableTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_TABLE_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_TABLE_TERM, value); - EXPECT_STREQ(static_cast(L"table"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"table"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnCapable) { @@ -558,10 +579,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnIsolationOption) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoUserName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_USER_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_USER_NAME, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } // Supported SQL @@ -604,17 +626,19 @@ TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoCatalogLocation) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_CATALOG_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_CATALOG_NAME, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogNameSeparator) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_CATALOG_NAME_SEPARATOR, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_CATALOG_NAME_SEPARATOR, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCatalogUsage) { @@ -625,10 +649,11 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCatalogUsage) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoColumnAlias) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_COLUMN_ALIAS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_COLUMN_ALIAS, value); - EXPECT_STREQ(static_cast(L"Y"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"Y"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCorrelationName) { @@ -765,10 +790,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropView) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoExpressionsInOrderby) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_EXPRESSIONS_IN_ORDERBY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_EXPRESSIONS_IN_ORDERBY, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoGroupBy) { @@ -786,10 +812,11 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierCase) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierQuoteChar) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_IDENTIFIER_QUOTE_CHAR, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_IDENTIFIER_QUOTE_CHAR, value); - EXPECT_STREQ(static_cast(L"\""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"\""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIndexKeywords) { @@ -808,26 +835,28 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoInsertStatement) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIntegrity) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_INTEGRITY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_INTEGRITY, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { // Keyword strings can require 10000 buffer length static constexpr int info_len = kOdbcBufferSize * 10; - SQLWCHAR value[info_len] = L""; - GetInfo(conn, SQL_KEYWORDS, value, info_len); + SQLWCHAR value[info_len] = {}; + GetInfoSQLWCHAR(conn, SQL_KEYWORDS, value, info_len); - EXPECT_GT(wcslen(value), 0); + EXPECT_GT(wcslen(reinterpret_cast(value)), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_LIKE_ESCAPE_CLAUSE, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_LIKE_ESCAPE_CLAUSE, value); - EXPECT_STREQ(static_cast(L"Y"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"Y"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNonNullableColumns) { @@ -845,24 +874,27 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOjCapabilities) { } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOrderByColumnsInSelect) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, value); - EXPECT_STREQ(static_cast(L"Y"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"Y"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOuterJoins) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_OUTER_JOINS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_OUTER_JOINS, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoProcedures) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_PROCEDURES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_PROCEDURES, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoQuotedIdentifierCase) { @@ -880,10 +912,11 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSchemaUsage) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSpecialCharacters) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_SPECIAL_CHARACTERS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_SPECIAL_CHARACTERS, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSqlConformance) { @@ -1003,17 +1036,19 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxProcedureNameLen) { } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxRowSize) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_MAX_ROW_SIZE, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_MAX_ROW_SIZE, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxRowSizeIncludesLong) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, value); - EXPECT_STREQ(static_cast(L"N"), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L"N"), result); } 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 78ca031e2e8f..5c816d5ca9d5 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc @@ -222,7 +222,7 @@ TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnect) { arrow::util::UTF8ToWideString(connect_str)); std::vector connect_str0(wconnect_str.begin(), wconnect_str.end()); - SQLWCHAR out_str[kOdbcBufferSize] = L""; + SQLWCHAR out_str[kOdbcBufferSize] = {}; SQLSMALLINT out_str_len; // Connecting to ODBC server. @@ -264,7 +264,7 @@ TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnectDsn) { arrow::util::UTF8ToWideString(connect_str)); std::vector connect_str0(wconnect_str.begin(), wconnect_str.end()); - SQLWCHAR out_str[kOdbcBufferSize] = L""; + SQLWCHAR out_str[kOdbcBufferSize] = {}; SQLSMALLINT out_str_len; // Connecting to ODBC server. @@ -482,7 +482,7 @@ TYPED_TEST(ConnectionHandleTest, TestCloseConnectionWithOpenStatement) { arrow::util::UTF8ToWideString(connect_str)); std::vector connect_str0(wconnect_str.begin(), wconnect_str.end()); - SQLWCHAR out_str[kOdbcBufferSize] = L""; + SQLWCHAR out_str[kOdbcBufferSize] = {}; SQLSMALLINT out_str_len; // Connecting to ODBC server. 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 c0d5f4919a55..273d737e8193 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -251,7 +251,8 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForDescriptorFailureFromDriverManager) { // API not implemented error from driver manager EXPECT_EQ(kErrorStateIM001, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); // Free descriptor handle EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DESC, descriptor)); @@ -288,7 +289,8 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagRecForConnectFailure) { EXPECT_EQ(kErrorState28000, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) { @@ -366,7 +368,8 @@ TYPED_TEST(ErrorsTest, TestSQLErrorEnvErrorFromDriverManager) { // Function sequence error state from driver manager EXPECT_EQ(kErrorStateHY010, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsTest, TestSQLErrorConnError) { @@ -392,7 +395,8 @@ TYPED_TEST(ErrorsTest, TestSQLErrorConnError) { // optional feature not supported error state EXPECT_EQ(kErrorStateHYC00, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsTest, TestSQLErrorStmtError) { @@ -401,8 +405,7 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtError) { // When application passes buffer length greater than SQL_MAX_MESSAGE_LENGTH (512), // DM passes 512 as buffer length to SQLError. - SQLWCHAR wsql[] = L"1"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"1"); ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); @@ -421,14 +424,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtError) { EXPECT_EQ(kErrorStateHY000, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsTest, TestSQLErrorStmtWarning) { // Test ODBC 2.0 API SQLError. - SQLWCHAR wsql[] = L"SELECT 'VERY LONG STRING here' AS string_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -456,7 +459,8 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtWarning) { // Verify string truncation warning is reported EXPECT_EQ(kErrorState01004, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) { @@ -489,7 +493,8 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) { EXPECT_EQ(kErrorStateHY010, SqlWcharToString(sql_state)); #endif // _WIN32 - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } #ifndef __APPLE__ @@ -521,7 +526,8 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorConnError) { // optional feature not supported error state. Driver Manager maps state to S1C00 EXPECT_EQ(kErrorStateS1C00, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } #endif // __APPLE__ @@ -531,8 +537,7 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtError) { // When application passes buffer length greater than SQL_MAX_MESSAGE_LENGTH (512), // DM passes 512 as buffer length to SQLError. - SQLWCHAR wsql[] = L"SELECT * from non_existent_table;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from non_existent_table;"); ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); @@ -549,14 +554,14 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtError) { // Driver Manager maps error state to S1000 EXPECT_EQ(kErrorStateS1000, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtWarning) { // Test ODBC 2.0 API SQLError. - SQLWCHAR wsql[] = L"SELECT 'VERY LONG STRING here' AS string_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -584,7 +589,8 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtWarning) { // Verify string truncation warning is reported EXPECT_EQ(kErrorState01004, SqlWcharToString(sql_state)); - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } } // namespace arrow::flight::sql::odbc 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 3fc48c263ec8..edbbd033c0c0 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 @@ -491,7 +491,7 @@ bool WriteDSN(Connection::ConnPropertyMap properties) { std::string driver = config.Get(FlightSqlConnection::DRIVER); std::wstring w_driver = arrow::util::UTF8ToWideString(driver).ValueOr(L""); - return RegisterDsn(config, w_driver.c_str()); + return RegisterDsn(config, reinterpret_cast(w_driver.c_str())); } std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id) { @@ -510,10 +510,27 @@ std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id) { return std::wstring(buf, buf + char_count); } +std::wstring ConvertToWString(const SQLWCHAR* str_val) { +#ifdef __linux__ + size_t str_len = std::wcslen(reinterpret_cast(str_val)); +#else + size_t str_len = std::wcslen(str_val); +#endif + std::wstring attr_str; + if (str_len == 0) { + attr_str = L""; + } else { + assert(str_val != nullptr); + assert(str_len > 0 && str_len <= static_cast(kOdbcBufferSize)); + attr_str.assign(str_val, str_val + str_len); + } + return attr_str; +} + std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len) { std::wstring attr_str; if (str_len == 0) { - attr_str = std::wstring(&str_val[0]); + attr_str = L""; } else { EXPECT_GT(str_len, 0); EXPECT_LE(str_len, static_cast(kOdbcBufferSize)); 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 a4e8665c9732..c02acf5cbff6 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 @@ -38,6 +38,20 @@ // For DSN registration #include "arrow/flight/sql/odbc/odbc_impl/system_dsn.h" +#ifdef __linux__ +# define ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ + auto name##_vec = ODBC::ToSqlWCharVector(std::wstring(wstring_var)); \ + SQLWCHAR* name = name##_vec.data(); +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ + size_t name##_len = std::wcslen(reinterpret_cast(name)); +#else +# define ASSIGN_SQLWCHAR_ARR(name, wstring_var) SQLWCHAR name[] = wstring_var; +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ + size_t name##_len = std::wcslen(name); +#endif + static constexpr std::string_view kTestConnectStr = "ARROW_FLIGHT_SQL_ODBC_CONN"; static constexpr std::string_view kTestDsn = "Apache Arrow Flight SQL Test DSN"; @@ -267,6 +281,11 @@ bool WriteDSN(Connection::ConnPropertyMap properties); /// \return wstring std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id); +/// \brief Check wide char array and convert into wstring +/// \param[in] str_val Array of SQLWCHAR. +/// \return wstring +std::wstring ConvertToWString(const SQLWCHAR* str_val); + /// \brief Check wide char vector and convert into wstring /// \param[in] str_val Vector of SQLWCHAR. /// \param[in] str_len length of string, in bytes. 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 1bbd3c1b74e0..0855f3c9751c 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 @@ -332,8 +332,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindType) { } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowNumber) { - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); 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 dd33ce9ae973..084809861657 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc @@ -38,8 +38,7 @@ using TestTypes = ::testing::Types; TYPED_TEST_SUITE(StatementTest, TestTypes); TYPED_TEST(StatementTest, TestSQLExecDirectSimpleQuery) { - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -65,8 +64,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectSimpleQuery) { } TYPED_TEST(StatementTest, TestSQLExecDirectInvalidQuery) { - SQLWCHAR wsql[] = L"SELECT;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT;"); ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors @@ -74,8 +72,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectInvalidQuery) { } TYPED_TEST(StatementTest, TestSQLExecuteSimpleQuery) { - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLPrepare(stmt, wsql, wsql_len)); @@ -104,8 +101,7 @@ TYPED_TEST(StatementTest, TestSQLExecuteSimpleQuery) { } TYPED_TEST(StatementTest, TestSQLPrepareInvalidQuery) { - SQLWCHAR wsql[] = L"SELECT;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT;"); ASSERT_EQ(SQL_ERROR, SQLPrepare(stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors @@ -346,12 +342,11 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectTimeQuery) { // Mock server test is skipped due to limitation on the mock server. // Time type from mock server does not include the fraction - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT CAST(TIME '00:00:00' AS TIME) AS time_min, CAST(TIME '23:59:59' AS TIME) AS time_max; - )"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -378,8 +373,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryQuery) { // Have binary test on mock test base as remote test servers tend to have different // formats for binary data - SQLWCHAR wsql[] = L"SELECT X'ABCDEF' AS c_varbinary;"; - SQLSMALLINT wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEF' AS c_varbinary;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -573,12 +567,11 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectTimeQueryDefaultType) { // Mock server test is skipped due to limitation on the mock server. // Time type from mock server does not include the fraction - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT CAST(TIME '00:00:00' AS TIME) AS time_min, CAST(TIME '23:59:59' AS TIME) AS time_max; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -606,8 +599,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectVarbinaryQueryDefaultType) { // Mock server has type `DENSE_UNION` for varbinary. // Note that not all remote servers support "from_hex" function - SQLWCHAR wsql[] = L"SELECT from_hex('ABCDEF') AS c_varbinary;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT from_hex('ABCDEF') AS c_varbinary;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -627,8 +619,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectVarbinaryQueryDefaultType) { // TODO(GH-48730): Enable this test when ARD/IRD descriptor support is fully implemented TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { // Verify that SQLGetData uses IRD precision/scale as defaults when ARD values are unset - SQLWCHAR wsql[] = L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -672,8 +663,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { // Verify that SQLGetData uses ARD precision/scale when set, for both SQL_ARD_TYPE and // SQL_C_DEFAULT - SQLWCHAR wsql[] = L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -717,8 +707,8 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { TYPED_TEST(StatementTest, TestSQLExecDirectGuidQueryUnsupported) { // Query GUID as string as SQLite does not support GUID - SQLWCHAR wsql[] = L"SELECT 'C77313CF-4E08-47CE-B6DF-94DD2FCF3541' AS guid;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + L"SELECT 'C77313CF-4E08-47CE-B6DF-94DD2FCF3541' AS guid;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -733,15 +723,14 @@ TYPED_TEST(StatementTest, TestSQLExecDirectGuidQueryUnsupported) { } TYPED_TEST(StatementTest, TestSQLExecDirectRowFetching) { - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1 AS small_table UNION ALL SELECT 2 UNION ALL SELECT 3; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -791,15 +780,14 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { SQLLEN rows_fetched; SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0); - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1 AS small_table UNION ALL SELECT 2 UNION ALL SELECT 3; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -853,8 +841,7 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { TYPED_TEST(StatementTest, TestSQLFetchScrollUnsupportedOrientation) { // SQL_FETCH_NEXT is the only supported fetch orientation. - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -890,8 +877,7 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollUnsupportedOrientation) { } TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { - SQLWCHAR wsql[] = L"SELECT 'VERY LONG STRING here' AS string_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -939,8 +925,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { } TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { - SQLWCHAR wsql[] = L"SELECT 'VERY LONG Unicode STRING 句子 here' AS wstring_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN( + wsql, L"SELECT 'VERY LONG Unicode STRING 句子 here' AS wstring_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -956,7 +942,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { // Verify string truncation is reported VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); - EXPECT_EQ(std::wstring(L"VERY LONG Unicode STRING 句子"), std::wstring(wchar_val)); + std::wstring wchar_result = ConvertToWString(wchar_val); + EXPECT_EQ(std::wstring(L"VERY LONG Unicode STRING 句子"), wchar_result); EXPECT_EQ(32 * wchar_size, ind); // Fetch same column 2nd time @@ -968,7 +955,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { // Verify string truncation is reported VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); - EXPECT_EQ(std::wstring(L" "), std::wstring(wchar_val2)); + wchar_result = ConvertToWString(wchar_val2); + EXPECT_EQ(std::wstring(L" "), wchar_result); EXPECT_EQ(5 * wchar_size, ind); // Fetch same column 3rd time @@ -979,7 +967,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { // Verify that there is no more truncation reports. The full string has been fetched. ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val3, buf_len, &ind)); - EXPECT_EQ(std::wstring(L"here"), std::wstring(wchar_val3)); + wchar_result = ConvertToWString(wchar_val3); + EXPECT_EQ(std::wstring(L"here"), wchar_result); EXPECT_EQ(4 * wchar_size, ind); // Attempt to fetch data 4th time @@ -992,8 +981,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { // Have binary test on mock test base as remote test servers tend to have different // formats for binary data - SQLWCHAR wsql[] = L"SELECT X'ABCDEFAB' AS c_varbinary;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEFAB' AS c_varbinary;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1061,8 +1049,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectNullQuery) { // Limitation on mock test server prevents null from working properly, so use remote // server instead. Mock server has type `DENSE_UNION` for null column data. - SQLWCHAR wsql[] = L"SELECT null as null_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1082,14 +1069,13 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { // Have binary test on mock test base as remote test servers tend to have different // formats for binary data - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1, 'VERY LONG STRING here' AS string_col, 'VERY LONG Unicode STRING 句子 here' AS wstring_col, X'ABCDEFAB' AS c_varbinary; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1132,8 +1118,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectNullQueryNullIndicator) { // Limitation on mock test server prevents null from working properly, so use remote // server instead. Mock server has type `DENSE_UNION` for null column data. - SQLWCHAR wsql[] = L"SELECT null as null_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1632,12 +1617,11 @@ TEST_F(StatementRemoteTest, TestSQLBindColTimeQuery) { ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 2, SQL_C_TYPE_TIME, &time_var_max, buf_len, &ind)); - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT CAST(TIME '00:00:00' AS TIME) AS time_min, CAST(TIME '23:59:59' AS TIME) AS time_max; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1665,8 +1649,7 @@ TEST_F(StatementMockTest, TestSQLBindColVarbinaryQuery) { ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); - SQLWCHAR wsql[] = L"SELECT X'ABCDEF' AS c_varbinary;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEF' AS c_varbinary;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1687,8 +1670,7 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQuery) { ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, &ind)); - SQLWCHAR wsql[] = L"SELECT null as null_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1706,8 +1688,7 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQueryNullIndicator) { ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, 0)); - SQLWCHAR wsql[] = L"SELECT null as null_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1725,15 +1706,14 @@ TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { // should be updated after every SQLFetch call. ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1 AS small_table UNION ALL SELECT 2 UNION ALL SELECT 3; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1775,15 +1755,14 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0)); - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1 AS small_table UNION ALL SELECT 2 UNION ALL SELECT 3; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1893,15 +1872,14 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ROWSET_SIZE, reinterpret_cast(rows), 0)); - SQLWCHAR wsql[] = - LR"( + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, + LR"( SELECT 1 AS small_table UNION ALL SELECT 2 UNION ALL SELECT 3; - )"; - SQLINTEGER wsql_len = std::wcslen(wsql); + )"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1913,7 +1891,7 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count, row_status)); EXPECT_EQ(3, row_count); - for (int i = 0; i < rows; i++) { + for (SQLULEN i = 0; i < rows; i++) { EXPECT_EQ(SQL_SUCCESS, row_status[i]); } @@ -1939,8 +1917,7 @@ TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); - SQLWCHAR wsql[] = L"SELECT null as null_col;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1956,8 +1933,7 @@ TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) { // Verify SQLMoreResults returns SQL_NO_DATA by default. - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -1974,80 +1950,75 @@ TYPED_TEST(StatementTest, TestSQLMoreResultsInvalidFunctionSequence) { TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputString) { SQLWCHAR buf[1024]; SQLINTEGER buf_char_len = sizeof(buf) / GetSqlWCharSize(); - SQLWCHAR input_str[] = L"SELECT * FROM mytable WHERE id == 1"; - SQLINTEGER input_char_len = static_cast(wcslen(input_str)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - std::wstring expected_string = std::wstring(input_str); - ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(conn, input_str, input_char_len, buf, buf_char_len, + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(conn, input_str, input_str_len, buf, buf_char_len, &output_char_len)); - EXPECT_EQ(input_char_len, output_char_len); + EXPECT_EQ(input_str_len, output_char_len); // returned length is in characters std::wstring returned_string(buf, buf + output_char_len); - EXPECT_EQ(expected_string, returned_string); + std::wstring input = ConvertToWString(input_str); + EXPECT_EQ(input, returned_string); } TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsNTSInputString) { SQLWCHAR buf[1024]; SQLINTEGER buf_char_len = sizeof(buf) / GetSqlWCharSize(); - SQLWCHAR input_str[] = L"SELECT * FROM mytable WHERE id == 1"; - SQLINTEGER input_char_len = static_cast(wcslen(input_str)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - std::wstring expected_string = std::wstring(input_str); ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(conn, input_str, SQL_NTS, buf, buf_char_len, &output_char_len)); - EXPECT_EQ(input_char_len, output_char_len); + EXPECT_EQ(input_str_len, output_char_len); // returned length is in characters std::wstring returned_string(buf, buf + output_char_len); + std::wstring expected_string = ConvertToWString(input_str); EXPECT_EQ(expected_string, returned_string); } TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputStringLength) { - SQLWCHAR input_str[] = L"SELECT * FROM mytable WHERE id == 1"; - SQLINTEGER input_char_len = static_cast(wcslen(input_str)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - std::wstring expected_string = std::wstring(input_str); ASSERT_EQ(SQL_SUCCESS, - SQLNativeSql(conn, input_str, input_char_len, nullptr, 0, &output_char_len)); + SQLNativeSql(conn, input_str, input_str_len, nullptr, 0, &output_char_len)); - EXPECT_EQ(input_char_len, output_char_len); + EXPECT_EQ(input_str_len, output_char_len); ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(conn, input_str, SQL_NTS, nullptr, 0, &output_char_len)); - EXPECT_EQ(input_char_len, output_char_len); + EXPECT_EQ(input_str_len, output_char_len); } TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsTruncatedString) { const SQLINTEGER small_buf_size_in_char = 11; SQLWCHAR small_buf[small_buf_size_in_char]; SQLINTEGER small_buf_char_len = sizeof(small_buf) / GetSqlWCharSize(); - SQLWCHAR input_str[] = L"SELECT * FROM mytable WHERE id == 1"; - SQLINTEGER input_char_len = static_cast(wcslen(input_str)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; // Create expected return string based on buf size SQLWCHAR expected_string_buf[small_buf_size_in_char]; - wcsncpy(expected_string_buf, input_str, 10); + wcsncpy(reinterpret_cast(expected_string_buf), + reinterpret_cast(input_str), 10); expected_string_buf[10] = L'\0'; std::wstring expected_string(expected_string_buf, expected_string_buf + small_buf_size_in_char); - ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLNativeSql(conn, input_str, input_char_len, small_buf, small_buf_char_len, - &output_char_len)); + ASSERT_EQ(SQL_SUCCESS_WITH_INFO, SQLNativeSql(conn, input_str, input_str_len, small_buf, + small_buf_char_len, &output_char_len)); VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01004); // Returned text length represents full string char length regardless of truncation - EXPECT_EQ(input_char_len, output_char_len); + EXPECT_EQ(input_str_len, output_char_len); std::wstring returned_string(small_buf, small_buf + small_buf_char_len); @@ -2057,11 +2028,10 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsTruncatedString) { TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsErrorOnBadInputs) { SQLWCHAR buf[1024]; SQLINTEGER buf_char_len = sizeof(buf) / GetSqlWCharSize(); - SQLWCHAR input_str[] = L"SELECT * FROM mytable WHERE id == 1"; - SQLINTEGER input_char_len = static_cast(wcslen(input_str)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - ASSERT_EQ(SQL_ERROR, SQLNativeSql(conn, nullptr, input_char_len, buf, buf_char_len, + ASSERT_EQ(SQL_ERROR, SQLNativeSql(conn, nullptr, input_str_len, buf, buf_char_len, &output_char_len)); VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY009); @@ -2081,10 +2051,9 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsErrorOnBadInputs) { TYPED_TEST(StatementTest, SQLNumResultColsReturnsColumnsOnSelect) { SQLSMALLINT column_count = 0; SQLSMALLINT expected_value = 3; - SQLWCHAR sql_query[] = L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2098,10 +2067,9 @@ TYPED_TEST(StatementTest, SQLNumResultColsReturnsColumnsOnSelect) { } TYPED_TEST(StatementTest, SQLNumResultColsReturnsSuccessOnNullptr) { - SQLWCHAR sql_query[] = L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2136,10 +2104,9 @@ TYPED_TEST(StatementTest, SQLNumResultColsFunctionSequenceErrorOnNoQuery) { TYPED_TEST(StatementTest, SQLRowCountReturnsNegativeOneOnSelect) { SQLLEN row_count = 0; SQLLEN expected_value = -1; - SQLWCHAR sql_query[] = L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2153,10 +2120,9 @@ TYPED_TEST(StatementTest, SQLRowCountReturnsNegativeOneOnSelect) { } TYPED_TEST(StatementTest, SQLRowCountReturnsSuccessOnNullptr) { - SQLWCHAR sql_query[] = L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"; - SQLINTEGER query_length = static_cast(wcslen(sql_query)); + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2182,8 +2148,7 @@ TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { } TYPED_TEST(StatementTest, TestSQLFreeStmtSQLClose) { - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); @@ -2191,8 +2156,7 @@ TYPED_TEST(StatementTest, TestSQLFreeStmtSQLClose) { } TYPED_TEST(StatementTest, TestSQLCloseCursor) { - SQLWCHAR wsql[] = L"SELECT 1;"; - SQLINTEGER wsql_len = std::wcslen(wsql); + ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); 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 60887d216cf2..4fa4d4334990 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -44,10 +44,10 @@ TYPED_TEST_SUITE(TablesOdbcV2Test, TestTypesOdbcV2); // Test Cases TYPED_TEST(TablesTest, SQLTablesTestInputData) { - SQLWCHAR catalog_name[] = L""; - SQLWCHAR schema_name[] = L""; - SQLWCHAR table_name[] = L""; - SQLWCHAR table_type[] = L""; + SQLWCHAR catalog_name[] = {0}; + SQLWCHAR schema_name[] = {0}; + SQLWCHAR table_name[] = {0}; + SQLWCHAR table_type[] = {0}; // All values populated EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, sizeof(catalog_name), schema_name, @@ -78,8 +78,8 @@ TYPED_TEST(TablesTest, SQLTablesTestInputData) { } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { - SQLWCHAR empty[] = L""; - SQLWCHAR SQL_ALL_CATALOGS_W[] = L"%"; + SQLWCHAR empty[] = {0}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_CATALOGS_W, L"%"); std::wstring expected_catalog_name = std::wstring(L"main"); // Get Catalog metadata @@ -100,12 +100,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { CreateTestTable(); - SQLWCHAR catalog_name[] = L"main"; - 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); + ASSIGN_SQLWCHAR_ARR(catalog_name, L"main"); + const std::wstring table_names[] = {L"TestTable", L"foreignTable", L"intTable", + L"sqlite_sequence"}; + std::wstring expected_catalog_name = std::wstring(L"main"); std::wstring expected_table_type = std::wstring(L"table"); // Get named Catalog metadata - Mock server returns the system table sqlite_sequence as @@ -130,7 +128,7 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { } TEST_F(TablesMockTest, SQLTablesTestGetSchemaHasNoData) { - SQLWCHAR SQL_ALL_SCHEMAS_W[] = L"%"; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_SCHEMAS_W, L"%"); // Validate that no schema data is available for Mock server ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, @@ -140,8 +138,8 @@ TEST_F(TablesMockTest, SQLTablesTestGetSchemaHasNoData) { } TEST_F(TablesRemoteTest, SQLTablesTestGetMetadataForAllSchemas) { - SQLWCHAR empty[] = L""; - SQLWCHAR SQL_ALL_SCHEMAS_W[] = L"%"; + SQLWCHAR empty[] = {0}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_SCHEMAS_W, L"%"); std::set actual_schemas; std::set expected_schemas = {L"$scratch", L"INFORMATION_SCHEMA", L"sys", L"sys.cache"}; @@ -173,39 +171,39 @@ 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"%"; - 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")}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_SCHEMAS_W, L"%"); + const std::wstring schema_names[] = {L"INFORMATION_SCHEMA", + L"INFORMATION_SCHEMA", + L"INFORMATION_SCHEMA", + L"INFORMATION_SCHEMA", + L"INFORMATION_SCHEMA", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys", + L"sys.cache", + L"sys.cache", + L"sys.cache", + L"sys.cache", + L"$scratch"}; std::wstring expected_system_table_type = std::wstring(L"SYSTEM_TABLE"); std::wstring expected_user_table_type = std::wstring(L"TABLE"); @@ -233,8 +231,8 @@ TEST_F(TablesRemoteTest, SQLTablesTestFilterByAllSchema) { TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { // Requires creation of user table named ODBCTest using schema $scratch in remote server - SQLWCHAR schema_name[] = L"$scratch"; - std::wstring expected_schema_name = std::wstring(schema_name); + ASSIGN_SQLWCHAR_ARR(schema_name, L"$scratch"); + 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"); @@ -255,11 +253,9 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { CreateTestTable(); - SQLWCHAR SQL_ALL_TABLES_W[] = L"%"; - const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), - static_cast(L"foreignTable"), - static_cast(L"intTable"), - static_cast(L"sqlite_sequence")}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_TABLES_W, L"%"); + const std::wstring table_names[] = {L"TestTable", L"foreignTable", L"intTable", + L"sqlite_sequence"}; std::wstring expected_catalog_name = std::wstring(L"main"); std::wstring expected_table_type = std::wstring(L"table"); @@ -287,11 +283,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { CreateTestTable(); - // 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"; + ASSIGN_SQLWCHAR_ARR(test_table, L"TestTable"); + ASSIGN_SQLWCHAR_ARR(foreign_table, L"foreignTable"); + ASSIGN_SQLWCHAR_ARR(int_table, L"intTable"); + ASSIGN_SQLWCHAR_ARR(sqlite_sequence, L"sqlite_sequence"); SQLWCHAR* table_names[] = {test_table, foreign_table, int_table, sqlite_sequence}; @@ -308,7 +303,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { CheckStringColumnW(stmt, 1, expected_catalog_name); // Mock server does not support table schema CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); + + std::wstring table_name = ConvertToWString(table_names[i]); + CheckStringColumnW(stmt, 3, table_name); + CheckStringColumnW(stmt, 4, expected_table_type); CheckNullColumnW(stmt, 5); @@ -321,9 +319,9 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { CreateUnicodeTable(); - SQLWCHAR unicodetable_name[] = L"数据"; + ASSIGN_SQLWCHAR_ARR(unicodetable_name, L"数据"); std::wstring expected_catalog_name = std::wstring(L"main"); - std::wstring expected_table_name = std::wstring(unicodetable_name); + std::wstring expected_table_name = std::wstring(L"数据"); std::wstring expected_table_type = std::wstring(L"table"); // Get specific Table metadata @@ -347,7 +345,7 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { TEST_F(TablesMockTest, SQLTablesTestGetMetadataForInvalidTableNameNoData) { CreateTestTable(); - SQLWCHAR invalid_table_name[] = L"NonExistenttable_name"; + ASSIGN_SQLWCHAR_ARR(invalid_table_name, L"NonExistenttable_name"); // Try to get metadata for a non-existent table name ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, @@ -362,17 +360,15 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { // Mock server only supports table type "table" in lowercase CreateTestTable(); - SQLWCHAR table_type_table_lowercase[] = L"table"; - SQLWCHAR table_type_table_uppercase[] = L"TABLE"; - SQLWCHAR table_type_view[] = L"VIEW"; - SQLWCHAR table_type_table_view[] = L"TABLE,VIEW"; - const SQLWCHAR* table_names[] = {static_cast(L"TestTable"), - static_cast(L"foreignTable"), - static_cast(L"intTable"), - static_cast(L"sqlite_sequence")}; + ASSIGN_SQLWCHAR_ARR(table_type_table_lowercase, L"table"); + ASSIGN_SQLWCHAR_ARR(table_type_table_uppercase, L"TABLE"); + ASSIGN_SQLWCHAR_ARR(table_type_view, L"VIEW"); + ASSIGN_SQLWCHAR_ARR(table_type_table_view, L"TABLE,VIEW"); + const std::wstring table_names[] = {L"TestTable", L"foreignTable", L"intTable", + 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); + std::wstring expected_table_type = std::wstring(L"table"); EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS, table_type_table_uppercase, SQL_NTS)); @@ -413,8 +409,8 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { // Requires creation of user table named ODBCTest using schema $scratch in remote server // Use mutable arrays to pass SQLWCHAR parameters to SQLTables - SQLWCHAR table[] = L"TABLE"; - SQLWCHAR table_view[] = L"TABLE,VIEW"; + ASSIGN_SQLWCHAR_ARR(table, L"TABLE"); + ASSIGN_SQLWCHAR_ARR(table_view, L"TABLE,VIEW"); SQLWCHAR* type_list[] = {table, table_view}; @@ -439,8 +435,8 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { } TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeViewHasNoData) { - SQLWCHAR empty[] = L""; - SQLWCHAR type_view[] = L"VIEW"; + SQLWCHAR empty[] = {0}; + ASSIGN_SQLWCHAR_ARR(type_view, L"VIEW"); EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, empty, SQL_NTS, type_view, SQL_NTS)); @@ -454,8 +450,8 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeViewHasNoData) { } TEST_F(TablesMockTest, SQLTablesGetSupportedTableTypes) { - SQLWCHAR empty[] = L""; - SQLWCHAR SQL_ALL_TABLE_TYPES_W[] = L"%"; + SQLWCHAR empty[] = {0}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_TABLE_TYPES_W, L"%"); std::wstring expected_table_type = std::wstring(L"table"); // Mock server returns lower case for supported type of "table" @@ -474,11 +470,9 @@ TEST_F(TablesMockTest, SQLTablesGetSupportedTableTypes) { } TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { - SQLWCHAR empty[] = L""; - SQLWCHAR SQL_ALL_TABLE_TYPES_W[] = L"%"; - const SQLWCHAR* type_lists[] = {static_cast(L"TABLE"), - static_cast(L"SYSTEM_TABLE"), - static_cast(L"VIEW")}; + SQLWCHAR empty[] = {0}; + ASSIGN_SQLWCHAR_ARR(SQL_ALL_TABLE_TYPES_W, L"%"); + const std::wstring type_lists[] = {L"TABLE", L"SYSTEM_TABLE", L"VIEW"}; ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); @@ -507,11 +501,8 @@ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { SQLSMALLINT nullable = 0; size_t column_index = 0; - 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")}; + const std::wstring column_names[] = {L"TABLE_CAT", L"TABLE_SCHEM", L"TABLE_NAME", + L"TABLE_TYPE", L"REMARKS"}; SQLSMALLINT column_data_types[] = {SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; @@ -526,7 +517,7 @@ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); @@ -554,11 +545,8 @@ TYPED_TEST(TablesOdbcV2Test, SQLTablesGetMetadataBySQLDescribeColODBCVer2) { SQLSMALLINT nullable = 0; size_t column_index = 0; - 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")}; + const std::wstring column_names[] = {L"TABLE_QUALIFIER", L"TABLE_OWNER", L"TABLE_NAME", + L"TABLE_TYPE", L"REMARKS"}; SQLSMALLINT column_data_types[] = {SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; @@ -573,7 +561,7 @@ TYPED_TEST(TablesOdbcV2Test, SQLTablesGetMetadataBySQLDescribeColODBCVer2) { &name_length, &column_data_type, &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(wcslen(column_names[i]), name_length); + EXPECT_EQ(column_names[i].length(), name_length); std::wstring returned(column_name, column_name + name_length); EXPECT_EQ(column_names[i], returned); 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 cb2fc57a92d3..702d9c8218d4 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 @@ -70,25 +70,25 @@ void CheckSQLDescribeCol(SQLHSTMT stmt, const SQLUSMALLINT column_index, } void CheckSQLDescribeColODBCVer2(SQLHSTMT stmt) { - 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")}; + const std::wstring column_names[] = {L"TYPE_NAME", + L"DATA_TYPE", + L"PRECISION", + L"LITERAL_PREFIX", + L"LITERAL_SUFFIX", + L"CREATE_PARAMS", + L"NULLABLE", + L"CASE_SENSITIVE", + L"SEARCHABLE", + L"UNSIGNED_ATTRIBUTE", + L"MONEY", + L"AUTO_INCREMENT", + L"LOCAL_TYPE_NAME", + L"MINIMUM_SCALE", + L"MAXIMUM_SCALE", + L"SQL_DATA_TYPE", + L"SQL_DATETIME_SUB", + L"NUM_PREC_RADIX", + 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,25 +112,14 @@ void CheckSQLDescribeColODBCVer2(SQLHSTMT stmt) { } void CheckSQLDescribeColODBCVer3(SQLHSTMT stmt) { - 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")}; + const std::wstring column_names[] = { + L"TYPE_NAME", L"DATA_TYPE", L"COLUMN_SIZE", + L"LITERAL_PREFIX", L"LITERAL_SUFFIX", L"CREATE_PARAMS", + L"NULLABLE", L"CASE_SENSITIVE", L"SEARCHABLE", + L"UNSIGNED_ATTRIBUTE", L"FIXED_PREC_SCALE", L"AUTO_UNIQUE_VALUE", + L"LOCAL_TYPE_NAME", L"MINIMUM_SCALE", L"MAXIMUM_SCALE", + L"SQL_DATA_TYPE", L"SQL_DATETIME_SUB", L"NUM_PREC_RADIX", + 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, @@ -221,16 +210,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bit"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -249,14 +238,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"tinyint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_TINYINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -275,14 +264,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bigint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIGINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -299,16 +288,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_LONGVARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -325,16 +314,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_VARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -352,16 +341,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"text"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -378,16 +367,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -405,16 +394,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"char"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -433,14 +422,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"integer"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_INTEGER, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -459,14 +448,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"smallint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_SMALLINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -485,14 +474,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"float"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_FLOAT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -511,14 +500,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"double"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -538,14 +527,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"numeric"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -565,14 +554,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -591,14 +580,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"date"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_DATE, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -617,14 +606,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"time"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIME, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -643,14 +632,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"timestamp"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIMESTAMP, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); } @@ -671,16 +660,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bit"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -699,14 +688,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"tinyint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_TINYINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -725,14 +714,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bigint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIGINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -749,16 +738,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_LONGVARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -775,16 +764,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_VARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -802,16 +791,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"text"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -828,16 +817,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -855,16 +844,16 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"char"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -883,14 +872,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"integer"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_INTEGER, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -909,14 +898,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"smallint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_SMALLINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -935,14 +924,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"float"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_FLOAT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -961,14 +950,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"double"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -988,14 +977,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"numeric"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1015,14 +1004,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1041,14 +1030,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"date"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // 0, driver + // returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1067,14 +1057,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"time"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // 0, driver + // returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1093,14 +1084,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoAllTypesODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"timestamp"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // 0, driver + // returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); } @@ -1121,16 +1113,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoBit) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bit"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1156,14 +1148,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoTinyInt) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"tinyint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_TINYINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1189,14 +1181,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoBigInt) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"bigint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_BIGINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1220,16 +1212,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoLongVarbinary) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_LONGVARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1253,16 +1245,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoVarbinary) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varbinary"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_VARBINARY, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec // No more data ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); @@ -1285,16 +1277,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoLongVarchar) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"text"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1311,16 +1303,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoLongVarchar) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"longvarchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WLONGVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1345,16 +1337,16 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoChar) { SQL_NULLABLE, // expected_nullable SQL_FALSE, // expected_case_sensitive SQL_SEARCHABLE, // expected_searchable - NULL, // expected_unsigned_attr + 0, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"char"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1380,14 +1372,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoInteger) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"integer"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_INTEGER, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1413,14 +1405,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSmallInt) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"smallint"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_SMALLINT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1446,14 +1438,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoFloat) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"float"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_FLOAT, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1479,14 +1471,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoDouble) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"double"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1506,14 +1498,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoDouble) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"numeric"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DOUBLE, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1540,14 +1532,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoVarchar) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"varchar"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_WVARCHAR, // expected_sql_data_type - NULL, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1573,14 +1565,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeDate) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"date"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_DATE, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1607,14 +1599,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLDate) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"date"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_DATE, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1640,14 +1632,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoDateODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"date"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // 0, driver + // returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1685,14 +1678,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTime) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"time"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIME, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1719,14 +1712,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTime) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"time"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIME, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1752,14 +1745,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoTimeODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"time"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // 0, driver + // returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); @@ -1797,14 +1791,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTimestamp) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"timestamp"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIMESTAMP, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1831,14 +1825,14 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTimestamp) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"timestamp"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type SQL_CODE_TIMESTAMP, // expected_sql_datetime_sub - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer3(stmt); @@ -1864,14 +1858,14 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTimestampODBCVer2) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE, // expected_unsigned_attr SQL_FALSE, // expected_fixed_prec_scale - NULL, // expected_auto_unique_value + 0, // expected_auto_unique_value std::wstring(L"timestamp"), // expected_local_type_name - NULL, // expected_min_scale - NULL, // expected_max_scale + 0, // expected_min_scale + 0, // expected_max_scale SQL_DATETIME, // expected_sql_data_type - NULL, // expected_sql_datetime_sub, driver returns NULL for Ver2 - NULL, // expected_num_prec_radix - NULL); // expected_interval_prec + 0, // expected_sql_datetime_sub, driver returns NULL for Ver2 + 0, // expected_num_prec_radix + 0); // expected_interval_prec CheckSQLDescribeColODBCVer2(stmt); From cebcabdbb8d6cc1390b2e6c89a9a732991ecafae Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Thu, 2 Apr 2026 12:58:18 -0700 Subject: [PATCH 03/17] Use SqlWCharArrLen() for wide char array length on Linux --- .../arrow/flight/sql/odbc/tests/odbc_test_suite.cc | 13 ++++++++++++- .../arrow/flight/sql/odbc/tests/odbc_test_suite.h | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) 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 edbbd033c0c0..bc83ed1f785e 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 @@ -510,9 +510,20 @@ std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id) { return std::wstring(buf, buf + char_count); } +size_t SqlWCharArrLen(const SQLWCHAR* str_val) { + if (!str_val) { + return 0; + } + const SQLWCHAR* p = str_val; + while (*p != 0) { + ++p; + } + return static_cast(p - str_val); +} + std::wstring ConvertToWString(const SQLWCHAR* str_val) { #ifdef __linux__ - size_t str_len = std::wcslen(reinterpret_cast(str_val)); + size_t str_len = SqlWCharArrLen(str_val); #else size_t str_len = std::wcslen(str_val); #endif 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 c02acf5cbff6..fb914ec19fd1 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 @@ -44,7 +44,7 @@ SQLWCHAR* name = name##_vec.data(); # define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ - size_t name##_len = std::wcslen(reinterpret_cast(name)); + size_t name##_len = SqlWCharArrLen(name); #else # define ASSIGN_SQLWCHAR_ARR(name, wstring_var) SQLWCHAR name[] = wstring_var; # define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ @@ -281,6 +281,11 @@ bool WriteDSN(Connection::ConnPropertyMap properties); /// \return wstring std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id); +/// \brief Get length of wide char array. +/// \param[in] str_val Array of SQLWCHAR. +/// \return number of wide characters in array +size_t SqlWCharArrLen(const SQLWCHAR* str_val); + /// \brief Check wide char array and convert into wstring /// \param[in] str_val Array of SQLWCHAR. /// \return wstring From 6d0d5b692749cdc4c90c2f9de7372bb768849f61 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:41:50 -0700 Subject: [PATCH 04/17] Fix ODBC Linux test segmentation fault * Resolve segfault issue on Linux and pass `ARROW_TEST_LINKAGE=static` Pass `ARROW_TEST_LINKAGE=static` * Clean up --- compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compose.yaml b/compose.yaml index 2fa4c5a9aa93..f0766bd30b65 100644 --- a/compose.yaml +++ b/compose.yaml @@ -565,6 +565,8 @@ services: ARROW_PARQUET: "OFF" ARROW_S3: "OFF" ARROW_SUBSTRAIT: "OFF" + # GH-49651 Link ODBC tests statically on Linux to fix segfault + ARROW_TEST_LINKAGE: "static" # Register ODBC before running tests command: > /bin/bash -c " From fa7d3d6cffe34650603f8f08e824d618678404ef Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 7 Apr 2026 14:04:33 -0700 Subject: [PATCH 05/17] Disable Large Memory Tests locally --- .github/workflows/cpp_extra.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 998b83a0b46e..2769ddf5c147 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -117,16 +117,17 @@ jobs: - image: alpine-linux-cpp runs-on: ubuntu-latest title: AMD64 Alpine Linux - - image: ubuntu-cpp - run-options: >- - -e ARROW_CTEST_TIMEOUT=2000 - -e ARROW_C_FLAGS_DEBUG="-O1" - -e ARROW_CXX_FLAGS_DEBUG="-O1" - -e ARROW_GANDIVA=OFF - -e ARROW_LARGE_MEMORY_TESTS=ON - -e BUILD_WARNING_LEVEL=PRODUCTION - runs-on: "runs-on=${{ github.run_id }}/family=x8i.2xlarge/volume=80gb/spot=capacity-optimized" - title: AMD64 Ubuntu Large Memory Tests + # Disable Large Memory Tests locally + # - image: ubuntu-cpp + # run-options: >- + # -e ARROW_CTEST_TIMEOUT=2000 + # -e ARROW_C_FLAGS_DEBUG="-O1" + # -e ARROW_CXX_FLAGS_DEBUG="-O1" + # -e ARROW_GANDIVA=OFF + # -e ARROW_LARGE_MEMORY_TESTS=ON + # -e BUILD_WARNING_LEVEL=PRODUCTION + # runs-on: "runs-on=${{ github.run_id }}/family=x8i.2xlarge/volume=80gb/spot=capacity-optimized" + # title: AMD64 Ubuntu Large Memory Tests - image: conda-cpp run-options: >- -e ARROW_USE_MESON=ON From 9a60cb4c5953adfa90dba4c301ce86e15a6a01c5 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Wed, 8 Apr 2026 11:39:21 -0700 Subject: [PATCH 06/17] Enable Remote Testing With Dremio Instance * Disable non-odbc workflows * Install `netcat` and set `ARROW_FLIGHT_SQL_ODBC_CONN` * Attempt to enable docker network Update compose.yaml Add executable bash script * add commands for testing Dremio instance value * Change to use `host.docker.internal` * Change test to run remote test Update cpp_extra.yml * Use `localhost` as hostname * Use `dremio_container` as host * Clean up PR * Test remote instance * CI can connect to remote instance, revert "Test remote instance" This reverts commit db975bfd30490e21e21b4667f8a004f49347e0ca. * Disable ODBC Debian build * Seeing segfault at ODBC test. Can probably be solved by passing test linkage = static like we did with Ubuntu. Since we don't have capacity to work on Debian now, we can close this. --- .github/workflows/cpp_extra.yml | 11 +++++++++-- compose.yaml | 8 ++++++++ .../flight/sql/odbc/tests/dremio/docker-compose.yml | 6 +++++- .../sql/odbc/tests/dremio/set_up_dremio_instance.sh | 0 4 files changed, 22 insertions(+), 3 deletions(-) mode change 100644 => 100755 cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 2769ddf5c147..687b9aade54a 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -379,8 +379,9 @@ jobs: include: - image: ubuntu-cpp-odbc title: AMD64 Ubuntu - - image: debian-cpp-odbc - title: AMD64 Debian + # GH-49582: TODO Enable Debian build for ODBC + # - image: debian-cpp-odbc + # title: AMD64 Debian env: ARCH: amd64 ARCHERY_DEBUG: 1 @@ -394,6 +395,12 @@ jobs: persist-credentials: false fetch-depth: 0 submodules: recursive + - name: Create Docker Test Network + run: docker network create odbc_net + - name: Set Up Dremio Instance + run: | + docker compose -f cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml up -d + cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh - name: Cache Docker Volumes uses: actions/cache@v5 with: diff --git a/compose.yaml b/compose.yaml index f0766bd30b65..24488e799a15 100644 --- a/compose.yaml +++ b/compose.yaml @@ -205,6 +205,11 @@ volumes: ubuntu-ccache: name: ${ARCH}-ubuntu-${UBUNTU}-ccache +networks: + # GH-48068 for Flight SQL ODBC Testing + odbc_net: + external: true + services: ################################# C++ ####################################### @@ -558,6 +563,7 @@ services: ARROW_DEPENDENCY_SOURCE: BUNDLED ARROW_DEPENDENCY_USE_SHARED: "OFF" ARROW_FLIGHT_SQL_ODBC: "ON" + ARROW_FLIGHT_SQL_ODBC_CONN: "driver={Apache Arrow Flight SQL ODBC Driver};HOST=dremio_container;port=32010;pwd=admin2025;uid=admin;useEncryption=false;UseWideChar=true;" ARROW_GANDIVA: "OFF" ARROW_GCS: "OFF" ARROW_HDFS: "OFF" @@ -568,6 +574,8 @@ services: # GH-49651 Link ODBC tests statically on Linux to fix segfault ARROW_TEST_LINKAGE: "static" # Register ODBC before running tests + networks: + - odbc_net command: > /bin/bash -c " /arrow/ci/scripts/cpp_build.sh /arrow /build && diff --git a/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml index eaab4d02b731..bf8f7f32ed4d 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml +++ b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml @@ -15,7 +15,9 @@ # specific language governing permissions and limitations # under the License. -# GH-48068 TODO: run remote ODBC tests on Linux +networks: + odbc_net: + external: true services: dremio: @@ -33,3 +35,5 @@ services: interval: 10s timeout: 5s retries: 30 + networks: + - odbc_net diff --git a/cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh b/cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh old mode 100644 new mode 100755 From 5ca9622faa367e09e2dc07d05de093bf9fff6221 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:47:31 -0700 Subject: [PATCH 07/17] macOS `.PKG` installer for Intel and ARM * Initial draft for macOS .pkg installer * in-progress for `install_odbc` * Remove `$HOME` from registration script * Generate .pkg installer and attempts to fix installer * Attempt to fix doc not seen * Attempt to fix ODBC registration script * Fix installer script and doc * Rename `install_odbc_ini.sh` to `postinstall` * Reuse `install_odbc.sh` script inside `postinstall` * Fix to generate macOS installer - Check $(pwd)/build/cpp * Clean up PR and todos * Update format to re-use code * Use `install_odbc_ini.sh` script to install DSN Keep a lightweight `postinstall` file for macOS * Update install_odbc_ini.sh execution access * Address Justin's comment --- .github/workflows/cpp_extra.yml | 14 ++++ .pre-commit-config.yaml | 2 + cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 75 ++++++++++++++++- .../flight/sql/odbc/Connection-Options.md | 20 +++++ cpp/src/arrow/flight/sql/odbc/README | 83 ------------------- .../flight/sql/odbc/install/mac/README.txt | 9 ++ .../flight/sql/odbc/install/mac/Welcome.txt | 1 + .../flight/sql/odbc/install/mac/postinstall | 30 +++++++ .../sql/odbc/install/unix/install_odbc.sh | 6 +- .../sql/odbc/install/unix/install_odbc_ini.sh | 39 +++------ dev/release/rat_exclude_files.txt | 2 + 11 files changed, 167 insertions(+), 114 deletions(-) create mode 100644 cpp/src/arrow/flight/sql/odbc/Connection-Options.md delete mode 100644 cpp/src/arrow/flight/sql/odbc/README create mode 100644 cpp/src/arrow/flight/sql/odbc/install/mac/README.txt create mode 100644 cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt create mode 100755 cpp/src/arrow/flight/sql/odbc/install/mac/postinstall diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 687b9aade54a..cd0c2c0b13b4 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -458,6 +458,7 @@ jobs: ARROW_DEPENDENCY_SOURCE: BUNDLED ARROW_DEPENDENCY_USE_SHARED: OFF ARROW_FLIGHT_SQL_ODBC: ON + ARROW_FLIGHT_SQL_ODBC_INSTALLER: ON ARROW_HOME: /tmp/local ARROW_MIMALLOC: OFF steps: @@ -533,6 +534,19 @@ jobs: --allow libresolv \ --allow libz \ "$(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib" + - name: Generate macOS Installer + if: matrix.build-type == 'release' + shell: bash + run: | + cd $(pwd)/build/cpp + cpack + - name: Upload ODBC PKG to the job + if: matrix.build-type == 'release' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} + path: build/cpp/ArrowFlightSqlOdbcODBC-*.pkg + if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0544ff11bf88..26d31ffecc1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -347,7 +347,9 @@ repos: ?^cpp/build-support/update-thrift\.sh$| ?^cpp/examples/minimal_build/run\.sh$| ?^cpp/examples/tutorial_examples/run\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$| ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$| ?^dev/release/05-binary-upload\.sh$| ?^dev/release/08-binary-verify\.sh$| ?^dev/release/binary-recover\.sh$| diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 48fab25a29b1..f0b30aa16301 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -129,7 +129,6 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache Arrow Flight SQL ODBC Driver") set(CPACK_PACKAGE_CONTACT "dev@arrow.apache.org") - # GH-47876 TODO: set up `arrow_flight_sql_odbc` component for macOS Installer # GH-47877 TODO: set up `arrow_flight_sql_odbc` component for Linux Installer if(WIN32) # Install ODBC and its Arrow dependencies @@ -156,6 +155,66 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp") + else() + if(APPLE) + set(CPACK_PACKAGE_FILE_NAME + "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + ) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + + set(CPACK_SET_DESTDIR ON) + set(CPACK_INSTALL_PREFIX "/Library/ODBC") + # Register ODBC after install + set(CPACK_POSTFLIGHT_ARROW_FLIGHT_SQL_ODBC_SCRIPT + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/postinstall") + set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/README.txt") + set(CPACK_RESOURCE_FILE_WELCOME + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/Welcome.txt") + + set(ODBC_INSTALL_DIR "arrow-odbc/lib") + set(DOC_INSTALL_DIR "arrow-odbc/doc") + else() + # Linux + # GH-49595: TODO implement DEB installer + # GH-47977: TODO implement RPM installer + message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595") + message(STATUS "ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977") + endif() + + # Install ODBC + install(TARGETS arrow_flight_sql_odbc_shared + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc) + + # Install temporary driver registration scripts, they will be removed after driver registration is complete + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc_ini.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + + # Install documentation files + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) endif() get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) @@ -170,8 +229,13 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Upgrade GUID is required to be unchanged for ODBC installer to upgrade set(CPACK_WIX_UPGRADE_GUID "DBF27A18-F8BF-423F-9E3A-957414D52C4B") set(CPACK_WIX_PRODUCT_GUID "279D087B-93B5-4DC3-BA69-BCF485022A26") + else() + # macOS and Linux + list(APPEND CPACK_COMPONENTS_ALL Docs) + if(APPLE) + set(CPACK_GENERATOR "productbuild") + endif() endif() - # GH-47876 TODO: create macOS Installer using cpack # GH-47877 TODO: create Linux Installer using cpack # Load CPack after all CPACK* variables are set @@ -180,4 +244,11 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) DISPLAY_NAME "ODBC library" DESCRIPTION "Apache Arrow Flight SQL ODBC library bin, required to install" REQUIRED) + if(UNIX) + # On macOS and Linux, provide connection string documentation since users need to manually enter DSN keys. + cpack_add_component(Docs + DISPLAY_NAME "Documentation" + DESCRIPTION "Documentation for Apache Arrow Flight SQL ODBC Driver" + ) + endif() endif() diff --git a/cpp/src/arrow/flight/sql/odbc/Connection-Options.md b/cpp/src/arrow/flight/sql/odbc/Connection-Options.md new file mode 100644 index 000000000000..61ca1eac6e4d --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/Connection-Options.md @@ -0,0 +1,20 @@ + + +GH-49723 TODO: enter ODBC connection options for unix DSN diff --git a/cpp/src/arrow/flight/sql/odbc/README b/cpp/src/arrow/flight/sql/odbc/README deleted file mode 100644 index f119efc82790..000000000000 --- a/cpp/src/arrow/flight/sql/odbc/README +++ /dev/null @@ -1,83 +0,0 @@ - - -## Steps to Register the 64-bit Apache Arrow ODBC driver on Windows - -After the build succeeds, the ODBC DLL will be located in -`build\debug\Debug` for a debug build and `build\release\Release` for a release build. - -1. Open Power Shell as administrator. - -2. Register your ODBC DLL: - Need to replace with actual path to repository in the commands. - - i. `cd to repo.` - ii. `cd ` - iii. Run script to register your ODBC DLL as Apache Arrow Flight SQL ODBC Driver - `.\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd \cpp\build\< release | debug >\< Release | Debug>\arrow_flight_sql_odbc.dll` - Example command for reference: - `.\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd C:\path\to\arrow\cpp\build\release\Release\arrow_flight_sql_odbc.dll` - -If the registration is successful, then Apache Arrow Flight SQL ODBC Driver -should show as an available ODBC driver in the x64 ODBC Driver Manager. - -## Steps to Generate Windows Installer -1. Build with `ARROW_FLIGHT_SQL_ODBC=ON` and `ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON`. -2. `cd` to `build` folder. -3. Run `cpack`. - -If the generation is successful, you will find `Apache Arrow Flight SQL ODBC--win64.msi` generated under the `build` folder. - -## Steps to Register the 64-bit Apache Arrow ODBC driver on macOS - -After the build succeeds, the ODBC DYLIB will be located in -`build\debug` for a debug build and `build\release` for a release build. - -1. Open terminal shell. - -2. Register your ODBC DYLIB: - Need to replace with actual path to repository in the commands. - - i. `cd to repo.` - ii. `cd ` - iii. Give script permission to execute - `chmod +x cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh` - iv. Run script with `sudo` to register your ODBC DYLIB as Apache Arrow Flight SQL ODBC Driver - `sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.dylib` - Example command for reference: - `sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /path/to/arrow/cpp/build/release/libarrow_flight_sql_odbc.dylib` - -If the registration is successful, then Apache Arrow Flight SQL ODBC Driver -should be shown at `~/Library/ODBC/odbcinst.ini` - -## Steps to Enable Logging -Arrow Flight SQL ODBC driver uses Arrow's internal logging framework. By default, the log messages are printed to the terminal. -1. Set environment variable `ARROW_ODBC_LOG_LEVEL` to any of the following valid values to enable logging. If `ARROW_ODBC_LOG_LEVEL` is set to a non-empty string that does not match any of the following values, `DEBUG` level is used by default. - -The characters are case-insensitive. -- TRACE -- DEBUG -- INFO -- WARNING -- ERROR -- FATAL - -The Windows ODBC driver currently does not support writing log files. `ARROW_USE_GLOG` is required to write log files, and `ARROW_USE_GLOG` is disabled on Windows platform since plasma using `glog` is not fully tested on windows. - -Note: GH-47670 running more than 1 tests with logging enabled is not fully supported. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt new file mode 100644 index 000000000000..8624470eb8bb --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt @@ -0,0 +1,9 @@ +Files are available in '/Library/ODBC/arrow-odbc' after installation. + +To setup a connection, you can use DSN to store your data source connection information. +1. Open 'iODBC Data Source Administrator'. +2. To create a user DSN, go to 'User DSN' tab and click 'Add'. +3. Select 'Apache Arrow Flight SQL ODBC Driver' and click 'Finish'. +4. Enter DSN name and connection string values. +For the list of all supported options, check '/Library/ODBC/arrow-odbc/doc/Connection-Options.md'. +5. Click 'Ok' to save the DSN. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt new file mode 100644 index 000000000000..5898db428f6f --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt @@ -0,0 +1 @@ +Apache Arrow Flight SQL ODBC Driver is a read-only ODBC driver for connecting to data sources that support Arrow Flight SQL. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall new file mode 100755 index 000000000000..9499c2fe0e92 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall @@ -0,0 +1,30 @@ +#!/bin/bash +# +# 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. + +# Use temporary driver registration script to register ODBC driver in system DSN +odbc_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc.sh" +"$odbc_install_script" /Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib + +# Use temporary DSN registration script to register sample system DSN +dsn_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc_ini.sh" +"$dsn_install_script" /Library/ODBC/odbc.ini + +# clean temporary script +rm -f "$odbc_install_script" +rm -f "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh index 5ddcc8a4cbda..b97fabfbadac 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -# Used by macOS ODBC installer script `install_odbc_ini.sh` and macOS ODBC testing +# Used by arrow/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall set -euo pipefail @@ -46,8 +46,8 @@ case "$(uname)" in ;; *) # macOS - USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini" - mkdir -p "$HOME"/Library/ODBC + USER_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + mkdir -p /Library/ODBC ;; esac diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh index 84de8e0e1464..b86d4047b12c 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh @@ -17,35 +17,23 @@ # specific language governing permissions and limitations # under the License. -# GH-47876 TODO: create macOS ODBC Installer. -# Script for installing macOS ODBC driver, to be used for macOS installer. -# This script assumes ODBC driver is at -# /Library/ODBC/arrow-odbc/libarrow_flight_sql_odbc.dylib +SYSTEM_ODBC_FILE="$1" -set -euo pipefail - -if [ $EUID -ne 0 ]; then - echo "Please run this script with sudo" - exit 1 +if [[ -z "$SYSTEM_ODBC_FILE" ]]; then + echo "error: path to system ODBC DSN is not specified. Call format: install_odbc_ini abs_path_to_odbc_dsn_ini" + exit 1 fi -source_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -odbc_install_script="${source_dir}/../unix/install_odbc.sh" - -"$odbc_install_script" /Library/ODBC/arrow-odbc/libarrow_flight_sql_odbc.dylib - -USER_ODBC_FILE="$HOME/Library/ODBC/odbc.ini" DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" DSN_NAME="Apache Arrow Flight SQL ODBC DSN" -touch "$USER_ODBC_FILE" +touch "$SYSTEM_ODBC_FILE" -if grep -q "^\[$DSN_NAME\]" "$USER_ODBC_FILE"; then - echo "DSN [$DSN_NAME] already exists in $USER_ODBC_FILE" +if grep -q "^\[$DSN_NAME\]" "$SYSTEM_ODBC_FILE"; then + echo "DSN [$DSN_NAME] already exists in $SYSTEM_ODBC_FILE" else - echo "Adding [$DSN_NAME] to $USER_ODBC_FILE..." - cat >> "$USER_ODBC_FILE" <> "$SYSTEM_ODBC_FILE" < "${USER_ODBC_FILE}.tmp" && mv "${USER_ODBC_FILE}.tmp" "$USER_ODBC_FILE" + ' "$SYSTEM_ODBC_FILE" > "${SYSTEM_ODBC_FILE}.tmp" && mv "${SYSTEM_ODBC_FILE}.tmp" "$SYSTEM_ODBC_FILE" fi else # Section doesn't exist, append section and DSN entry at end @@ -80,6 +68,5 @@ else echo "" echo "[ODBC Data Sources]" echo "${DSN_NAME}=${DRIVER_NAME}" - } >> "$USER_ODBC_FILE" + } >> "$SYSTEM_ODBC_FILE" fi - diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt index bd685845bc7c..6dea092feacf 100644 --- a/dev/release/rat_exclude_files.txt +++ b/dev/release/rat_exclude_files.txt @@ -13,6 +13,8 @@ ci/vcpkg/*.patch CHANGELOG.md cpp/CHANGELOG_PARQUET.md cpp/src/arrow/c/dlpack_abi.h +cpp/src/arrow/flight/sql/odbc/install/mac/README.txt +cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt cpp/src/arrow/io/mman.h cpp/src/arrow/util/random.h cpp/src/arrow/status.cc From c2c2aa197742b06e4e06704af49685226a9b193e Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:18:34 -0700 Subject: [PATCH 08/17] Add debug workflow for ODBC Linux * Add debug workflow for ODBC Linux Update cpp_extra.yml * apply static test linkage to ODBC only --- .github/workflows/cpp_extra.yml | 14 ++++++++++---- compose.yaml | 2 -- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index cd0c2c0b13b4..ca1300c9eb54 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -378,10 +378,16 @@ jobs: matrix: include: - image: ubuntu-cpp-odbc - title: AMD64 Ubuntu + title: AMD64 Ubuntu Release + build-type: release # GH-49582: TODO Enable Debian build for ODBC # - image: debian-cpp-odbc # title: AMD64 Debian + - image: ubuntu-cpp-odbc + title: AMD64 Ubuntu Debug + build-type: debug + run-options: >- + -e ARROW_BUILD_TYPE=DEBUG env: ARCH: amd64 ARCHERY_DEBUG: 1 @@ -405,8 +411,8 @@ jobs: uses: actions/cache@v5 with: path: .docker - key: ${{ matrix.image }}-${{ hashFiles('cpp/**') }} - restore-keys: ${{ matrix.image }}- + key: ${{ matrix.image }}-${{ matrix.build-type }}-${{ hashFiles('cpp/**') }} + restore-keys: ${{ matrix.image }}-${{ matrix.build-type }}- - name: Setup Python on hosted runner uses: actions/setup-python@v6 with: @@ -421,7 +427,7 @@ jobs: # GH-40558: reduce ASLR to avoid ASAN/LSAN crashes sudo sysctl -w vm.mmap_rnd_bits=28 source ci/scripts/util_enable_core_dumps.sh - archery docker run ${{ matrix.image }} + archery docker run ${{ matrix.run-options || '' }} ${{ matrix.image }} - name: Docker Push if: >- success() && diff --git a/compose.yaml b/compose.yaml index 24488e799a15..d38219d4d4db 100644 --- a/compose.yaml +++ b/compose.yaml @@ -571,8 +571,6 @@ services: ARROW_PARQUET: "OFF" ARROW_S3: "OFF" ARROW_SUBSTRAIT: "OFF" - # GH-49651 Link ODBC tests statically on Linux to fix segfault - ARROW_TEST_LINKAGE: "static" # Register ODBC before running tests networks: - odbc_net From 015b96287d52647dfc9d16e7c274f03820307e13 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:44:17 -0700 Subject: [PATCH 09/17] Reuse connections across test suite Co-Authored-By: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> --- .../flight/sql/odbc/tests/CMakeLists.txt | 5 + .../sql/odbc/tests/connection_attr_test.cc | 9 +- .../sql/odbc/tests/connection_info_test.cc | 6 +- .../flight/sql/odbc/tests/odbc_test_suite.cc | 165 +++++++++++------- .../flight/sql/odbc/tests/odbc_test_suite.h | 44 +++-- 5 files changed, 147 insertions(+), 82 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt index 0f45bfd0c811..79cd45ed0bc8 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt @@ -42,6 +42,11 @@ set(ARROW_FLIGHT_SQL_ODBC_TEST_SRCS # GH-46889: move protobuf_test_util to a more common location ../../../../engine/substrait/protobuf_test_util.cc) +# Resolve segmentation fault error on Windows platform due to Arrow Compute Library Initialization +if(WIN32) + list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_SRCS ../../../../compute/test_env.cc) +endif() + # GH-49651 Link ODBC tests statically on Linux and dynamically on macOS/Windows if(WIN32 OR APPLE) set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_shared 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 dbf2fbb74f8f..467447bdc9c5 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 @@ -87,15 +87,18 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported) } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { - this->AllocEnvConnHandles(); + SQLHENV test_env = SQL_NULL_HENV; + SQLHDBC test_conn = SQL_NULL_HDBC; + this->AllocEnvConnHandles(test_env, test_conn); // Verify DM-only attribute is settable via Driver Manager ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_ODBC_CURSORS, + SQLSetConnectAttr(test_conn, SQL_ATTR_ODBC_CURSORS, reinterpret_cast(SQL_CUR_USE_DRIVER), 0)); std::string connect_str = this->GetConnectionString(); - this->ConnectWithString(connect_str); + this->ConnectWithString(connect_str, test_conn); + this->Disconnect(test_env, test_conn); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { 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 cbd23e5647f8..cd39abd2928a 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 @@ -614,7 +614,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoCatalogLocation) { // GH-49482 TODO: resolve inconsitent return value for SQL_CATALOG_LOCATION and change // test type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), conn); SQLUSMALLINT value; GetInfo(conn, SQL_CATALOG_LOCATION, &value); @@ -750,7 +750,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_SCHEMA and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), conn); SQLUINTEGER value; GetInfo(conn, SQL_DROP_SCHEMA, &value); @@ -764,7 +764,7 @@ TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropTable) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_TABLE and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), conn); SQLUINTEGER value; GetInfo(conn, SQL_DROP_TABLE, &value); 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 bc83ed1f785e..ad3eb43abe2a 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 @@ -51,28 +51,64 @@ class MockServerEnvironment : public ::testing::Environment { } }; -::testing::Environment* mock_env = +bool RunningRemoteTests() { return !remote_test_connect_str.empty(); } + +class OdbcTestEnvironment : public ::testing::Environment { + public: + void SetUp() override { + remote_test_connect_str = ODBCTestBase::GetConnectionString(); + if (RunningRemoteTests()) { + ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv3_handles.env, + remote_odbcv3_handles.conn, SQL_OV_ODBC3); + ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv2_handles.env, + remote_odbcv2_handles.conn, SQL_OV_ODBC2); + } + + std::string mock_test_connect_str = ODBCMockTestBase::GetConnectionString(); + ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv3_handles.env, + mock_odbcv3_handles.conn, SQL_OV_ODBC3); + ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv2_handles.env, + mock_odbcv2_handles.conn, SQL_OV_ODBC2); + } + + void TearDown() override { + if (RunningRemoteTests()) { + ODBCTestBase::Disconnect(remote_odbcv3_handles.env, remote_odbcv3_handles.conn); + ODBCTestBase::Disconnect(remote_odbcv2_handles.env, remote_odbcv2_handles.conn); + } + + ODBCTestBase::Disconnect(mock_odbcv3_handles.env, mock_odbcv3_handles.conn); + ODBCTestBase::Disconnect(mock_odbcv2_handles.env, mock_odbcv2_handles.conn); + } +}; + +::testing::Environment* mock_server_env = ::testing::AddGlobalTestEnvironment(new MockServerEnvironment); -void ODBCTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { +::testing::Environment* odbc_test_env = + ::testing::AddGlobalTestEnvironment(new OdbcTestEnvironment); + +void ODBCTestBase::AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver) { // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env_handle)); ASSERT_EQ( SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + SQLSetEnvAttr(env_handle, SQL_ATTR_ODBC_VERSION, reinterpret_cast(static_cast(odbc_ver)), 0)); // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env_handle, &conn_handle)); } -void ODBCTestBase::Connect(std::string connect_str, SQLINTEGER odbc_ver) { - ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(odbc_ver)); - ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str)); +void ODBCTestBase::Connect(std::string connect_str, SQLHENV& env_handle, + SQLHDBC& conn_handle, SQLINTEGER odbc_ver) { + ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(env_handle, conn_handle, odbc_ver)); + ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str, conn_handle)); } -void ODBCTestBase::ConnectWithString(std::string connect_str) { +void ODBCTestBase::ConnectWithString(std::string connect_str, SQLHDBC& conn_handle) { // Connect string std::vector connect_str0(connect_str.begin(), connect_str.end()); @@ -81,31 +117,39 @@ void ODBCTestBase::ConnectWithString(std::string connect_str) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(conn_handle, 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, conn_handle); } -void ODBCTestBase::Disconnect() { +void ODBCTestBase::Disconnect(SQLHENV& env_handle, SQLHDBC& conn_handle) { // Disconnect from ODBC - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + if (conn_handle != SQL_NULL_HDBC) { + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn_handle)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn_handle); + } - FreeEnvConnHandles(); + FreeEnvConnHandles(env_handle, conn_handle); } -void ODBCTestBase::FreeEnvConnHandles() { +void ODBCTestBase::FreeEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle) { // Free connection handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); + if (conn_handle != SQL_NULL_HDBC) { + EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn_handle)); + conn_handle = SQL_NULL_HDBC; + } // Free environment handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + if (env_handle != SQL_NULL_HENV) { + EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env_handle)); + env_handle = SQL_NULL_HENV; + } } std::string ODBCTestBase::GetConnectionString() { std::string connect_str = - arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOrDie(); + arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr(""); return connect_str; } @@ -168,68 +212,58 @@ std::wstring ODBCTestBase::GetQueryAllDataTypes() { } void ODBCTestBase::SetUp() { - if (connected) { - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); - } + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); } void ODBCTestBase::TearDown() { - if (connected) { - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt)); - } -} - -void ODBCTestBase::TearDownTestSuite() { - if (connected) { - Disconnect(); - connected = false; - } -} - -void FlightSQLODBCRemoteTestBase::CheckForRemoteTest() { - if (arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("").empty()) { - skipping_test = true; - GTEST_SKIP() << "Skipping test: kTestConnectStr not set"; - } + ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt)); } void FlightSQLODBCRemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC3); - connected = true; + env = remote_odbcv3_handles.env; + conn = remote_odbcv3_handles.conn; + stmt = remote_odbcv3_handles.stmt; } void FlightSQLOdbcV2RemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC2); - connected = true; + env = remote_odbcv2_handles.env; + conn = remote_odbcv2_handles.conn; + stmt = remote_odbcv2_handles.stmt; } void FlightSQLOdbcEnvConnHandleRemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - AllocEnvConnHandles(); + AllocEnvConnHandles(remote_non_connection_handles.env, + remote_non_connection_handles.conn); + env = remote_non_connection_handles.env; + conn = remote_non_connection_handles.conn; + stmt = remote_non_connection_handles.stmt; } void FlightSQLOdbcEnvConnHandleRemoteTestBase::TearDownTestSuite() { - if (skipping_test) { + if (!RunningRemoteTests()) { return; } - FreeEnvConnHandles(); + FreeEnvConnHandles(remote_non_connection_handles.env, + remote_non_connection_handles.conn); } std::string FindTokenInCallHeaders(const CallHeaders& incoming_headers) { @@ -400,20 +434,27 @@ void ODBCMockTestBase::DropUnicodeTable() { } void FlightSQLODBCMockTestBase::SetUpTestSuite() { - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC3); - connected = true; + env = mock_odbcv3_handles.env; + conn = mock_odbcv3_handles.conn; + stmt = mock_odbcv3_handles.stmt; } void FlightSQLOdbcV2MockTestBase::SetUpTestSuite() { - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC2); - connected = true; + env = mock_odbcv2_handles.env; + conn = mock_odbcv2_handles.conn; + stmt = mock_odbcv2_handles.stmt; } -void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { AllocEnvConnHandles(); } +void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { + AllocEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn); + env = mock_non_connection_handles.env; + conn = mock_non_connection_handles.conn; + stmt = mock_non_connection_handles.stmt; +} -void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { FreeEnvConnHandles(); } +void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { + FreeEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn); +} bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, Connection::ConnPropertyMap map2) { 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 fb914ec19fd1..f196c4535da7 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 @@ -55,12 +55,26 @@ static constexpr std::string_view kTestConnectStr = "ARROW_FLIGHT_SQL_ODBC_CONN"; static constexpr std::string_view kTestDsn = "Apache Arrow Flight SQL Test DSN"; -inline SQLHENV env = 0; -inline SQLHDBC conn = 0; -inline SQLHSTMT stmt = 0; +inline std::string remote_test_connect_str = ""; -inline bool skipping_test = false; -inline bool connected = false; +struct OdbcHandles { + SQLHENV env = SQL_NULL_HENV; + SQLHDBC conn = SQL_NULL_HDBC; + SQLHSTMT stmt = SQL_NULL_HSTMT; +}; + +inline OdbcHandles remote_odbcv3_handles; +inline OdbcHandles remote_odbcv2_handles; +inline OdbcHandles remote_non_connection_handles; +inline OdbcHandles mock_odbcv3_handles; +inline OdbcHandles mock_odbcv2_handles; +inline OdbcHandles mock_non_connection_handles; + +// These handles are meant to point to to the relevant handle above +// depending on the test fixture. +inline SQLHENV env = SQL_NULL_HENV; +inline SQLHDBC conn = SQL_NULL_HDBC; +inline SQLHSTMT stmt = SQL_NULL_HSTMT; inline std::shared_ptr mock_server; inline int mock_server_port = 0; @@ -75,17 +89,19 @@ namespace arrow::flight::sql::odbc { class ODBCTestBase : public ::testing::Test { public: /// \brief Allocate environment and connection handles - static void AllocEnvConnHandles(SQLINTEGER odbc_ver = SQL_OV_ODBC3); + static void AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver = SQL_OV_ODBC3); /// \brief Free environment and connection handles - static void FreeEnvConnHandles(); + static void FreeEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle); /// \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 - static void Connect(std::string connect_str, SQLINTEGER odbc_ver = SQL_OV_ODBC3); + static void Connect(std::string connect_str, SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver = SQL_OV_ODBC3); /// \brief Connect to Arrow Flight SQL server using connection string - static void ConnectWithString(std::string connection_str); + static void ConnectWithString(std::string connect_str, SQLHDBC& conn_handle); /// \brief Disconnect from server - static void Disconnect(); + static void Disconnect(SQLHENV& env_handle, SQLHDBC& conn_handle); /// \brief Get connection string from environment variable "ARROW_FLIGHT_SQL_ODBC_CONN" static std::string GetConnectionString(); /// \brief Get invalid connection string based on connection string defined in @@ -97,7 +113,6 @@ class ODBCTestBase : public ::testing::Test { protected: void SetUp() override; void TearDown() override; - static void TearDownTestSuite(); }; /// \brief Base test fixture for running tests against a remote server. @@ -106,9 +121,6 @@ class ODBCTestBase : public ::testing::Test { /// The connection string for connecting to this server is defined /// in the ARROW_FLIGHT_SQL_ODBC_CONN environment variable. class FlightSQLODBCRemoteTestBase : public ODBCTestBase { - public: - static void CheckForRemoteTest(); - protected: static void SetUpTestSuite(); }; @@ -125,6 +137,8 @@ class FlightSQLOdbcEnvConnHandleRemoteTestBase : public FlightSQLODBCRemoteTestB protected: static void SetUpTestSuite(); static void TearDownTestSuite(); + void SetUp() override {} + void TearDown() override {} }; static constexpr std::string_view kAuthorizationHeader = "authorization"; @@ -214,6 +228,8 @@ class FlightSQLOdbcEnvConnHandleMockTestBase : public FlightSQLODBCMockTestBase protected: static void SetUpTestSuite(); static void TearDownTestSuite(); + void SetUp() override {} + void TearDown() override {} }; /** ODBC read buffer size. */ From 7a6b3297ff2c0cd706d002d24d26b5fb7682561a Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:43:54 -0700 Subject: [PATCH 10/17] Fix tests on Linux --- ci/scripts/cpp_test.sh | 1 - .../flight/sql/odbc/tests/columns_test.cc | 25 ++++---- .../sql/odbc/tests/connection_attr_test.cc | 63 +++++++++++++------ .../sql/odbc/tests/connection_info_test.cc | 24 ++++--- .../flight/sql/odbc/tests/errors_test.cc | 23 ++++--- .../sql/odbc/tests/get_functions_test.cc | 7 ++- .../flight/sql/odbc/tests/odbc_test_suite.cc | 20 +++--- .../flight/sql/odbc/tests/odbc_test_suite.h | 33 ++++++---- .../sql/odbc/tests/statement_attr_test.cc | 4 ++ .../flight/sql/odbc/tests/statement_test.cc | 50 ++++++++------- .../flight/sql/odbc/tests/tables_test.cc | 14 ++++- .../flight/sql/odbc/tests/type_info_test.cc | 24 +++---- 12 files changed, 185 insertions(+), 103 deletions(-) diff --git a/ci/scripts/cpp_test.sh b/ci/scripts/cpp_test.sh index 2f88cdc819b2..241addbfebd2 100755 --- a/ci/scripts/cpp_test.sh +++ b/ci/scripts/cpp_test.sh @@ -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) 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 e4468d277ff4..571f52c76e13 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -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, @@ -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, @@ -415,6 +419,8 @@ TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) { ValidateFetch(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 @@ -1209,6 +1215,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { // There is no more column EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); } +#endif // __linux__ TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"non-existent-table"); @@ -1224,8 +1231,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2560,10 +2566,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(stmt, sql_query, sql_query_len)); ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); @@ -2572,13 +2574,14 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { SQLDescribeCol(stmt, column_index, column_name, 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); 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 467447bdc9c5..9db2ff74a109 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 @@ -33,6 +33,13 @@ using TestTypes = ::testing::Types; TYPED_TEST_SUITE(ConnectionAttributeTest, TestTypes); +template +class ConnectionAttributePreConnectTest : public T {}; + +using TestTypesHandle = ::testing::Types; +TYPED_TEST_SUITE(ConnectionAttributePreConnectTest, TestTypesHandle); + #ifdef SQL_ATTR_ASYNC_DBC_EVENT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); @@ -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. std::wstring trace_file = L"invalid/file/path"; std::vector trace_file0(trace_file.begin(), trace_file.end()); + +#ifdef _WIN32 ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRACEFILE, &trace_file0[0], static_cast(trace_file0.size()))); -#ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); -#else VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY000); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + static_cast(trace_file0.size()))); +#endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateLabDMOnly) { // Verify DM-only attribute is handled by Driver Manager ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); // Checks for invalid argument return error -#ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); -#else +#ifdef _WIN32 VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY024); -#endif // __APPLE__ +#else // Mac & Linux + VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); +#endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) { @@ -165,8 +174,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; @@ -175,7 +184,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; @@ -183,7 +191,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]; @@ -197,7 +204,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { ODBC::SqlWcharToString(out_str, static_cast(out_str_len)); EXPECT_FALSE(out_connection_string.empty()); } -#endif // __APPLE__ +#endif // _WIN32 TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) { SQLWCHAR out_str[kOdbcBufferSize]; @@ -224,11 +231,16 @@ 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(conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY114); +# else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); +# endif } #endif @@ -353,14 +365,23 @@ 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(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState08003); +#else // Windows & Mac ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); EXPECT_EQ(0, size); +#endif ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(0), 0)); @@ -370,12 +391,18 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) { SQLGetConnectAttr(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(conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(2), 0)); +#else // Windows & Mac + // driver should return warning and not error EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(2), 0)); // Verify warning status VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01S02); +#endif } } // namespace arrow::flight::sql::odbc 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 cd39abd2928a..737c5b0ce1d3 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 @@ -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 @@ -153,7 +156,8 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) { EXPECT_EQ(static_cast(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) { @@ -329,9 +333,11 @@ 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__ } @@ -370,7 +376,8 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoServerName) { SQLWCHAR value[kOdbcBufferSize] = {}; GetInfoSQLWCHAR(conn, SQL_SERVER_NAME, value); - EXPECT_GT(wcslen(reinterpret_cast(value)), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes1) { @@ -401,14 +408,16 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsName) { SQLWCHAR value[kOdbcBufferSize] = {}; GetInfoSQLWCHAR(conn, SQL_DBMS_NAME, value); - EXPECT_GT(wcslen(reinterpret_cast(value)), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { SQLWCHAR value[kOdbcBufferSize] = {}; GetInfoSQLWCHAR(conn, SQL_DBMS_VER, value); - EXPECT_GT(wcslen(reinterpret_cast(value)), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } // Data Source Information @@ -848,7 +857,8 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { SQLWCHAR value[info_len] = {}; GetInfoSQLWCHAR(conn, SQL_KEYWORDS, value, info_len); - EXPECT_GT(wcslen(reinterpret_cast(value)), 0); + std::wstring result = ConvertToWString(value, -1, info_len); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { 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 273d737e8193..d12d8669ee9e 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -309,15 +309,20 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) { EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, 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, 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) { @@ -485,13 +490,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()); 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 6ae1178e5d28..cf94c20aa12b 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 @@ -40,8 +40,9 @@ using TestTypesOdbcV2 = ::testing::Types; 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 @@ -217,6 +218,6 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsUnsupportedSingleAPI) { api_exists = -1; } } -#endif // __APPLE__ +#endif // _WIN32 } // namespace arrow::flight::sql::odbc 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 ad3eb43abe2a..406483a1ce87 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 @@ -531,7 +531,7 @@ bool WriteDSN(Connection::ConnPropertyMap properties) { } std::string driver = config.Get(FlightSqlConnection::DRIVER); - std::wstring w_driver = arrow::util::UTF8ToWideString(driver).ValueOr(L""); + CONVERT_SQLWCHAR_STR(w_driver, driver); return RegisterDsn(config, reinterpret_cast(w_driver.c_str())); } @@ -562,30 +562,34 @@ size_t SqlWCharArrLen(const SQLWCHAR* str_val) { return static_cast(p - str_val); } -std::wstring ConvertToWString(const SQLWCHAR* str_val) { +std::wstring ConvertToWString(const SQLWCHAR* str_val, SQLSMALLINT str_len, + SQLSMALLINT buffer_size) { + if (str_len == -1) { #ifdef __linux__ - size_t str_len = SqlWCharArrLen(str_val); -#else - size_t str_len = std::wcslen(str_val); + str_len = SqlWCharArrLen(str_val); +#else // Windows & Mac + str_len = std::wcslen(str_val); #endif + } std::wstring attr_str; if (str_len == 0) { attr_str = L""; } else { assert(str_val != nullptr); - assert(str_len > 0 && str_len <= static_cast(kOdbcBufferSize)); + assert(str_len > 0 && str_len <= buffer_size); attr_str.assign(str_val, str_val + str_len); } return attr_str; } -std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len) { +std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len, + SQLSMALLINT buffer_size) { std::wstring attr_str; if (str_len == 0) { attr_str = L""; } else { EXPECT_GT(str_len, 0); - EXPECT_LE(str_len, static_cast(kOdbcBufferSize)); + EXPECT_LE(str_len, buffer_size); attr_str = std::wstring(str_val.begin(), str_val.begin() + str_len / GetSqlWCharSize()); } 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 f196c4535da7..5271d2171c90 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 @@ -39,17 +39,20 @@ #include "arrow/flight/sql/odbc/odbc_impl/system_dsn.h" #ifdef __linux__ -# define ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ - auto name##_vec = ODBC::ToSqlWCharVector(std::wstring(wstring_var)); \ +# define ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + auto name##_vec = ODBC::ToSqlWCharVector(std::wstring(wstring_literal)); \ + if (name##_vec.empty() || name##_vec.back() != static_cast(0)) { \ + name##_vec.push_back(static_cast(0)); \ + } \ SQLWCHAR* name = name##_vec.data(); -# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ - ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ - size_t name##_len = SqlWCharArrLen(name); -#else -# define ASSIGN_SQLWCHAR_ARR(name, wstring_var) SQLWCHAR name[] = wstring_var; -# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_var) \ - ASSIGN_SQLWCHAR_ARR(name, wstring_var) \ - size_t name##_len = std::wcslen(name); +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_literal) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + SQLSMALLINT name##_len = static_cast(name##_vec.size() - 1); +#else // Windows & Mac +# define ASSIGN_SQLWCHAR_ARR(name, wstring_literal) SQLWCHAR name[] = wstring_literal; +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_literal) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + SQLSMALLINT name##_len = static_cast(std::wcslen(name)); #endif static constexpr std::string_view kTestConnectStr = "ARROW_FLIGHT_SQL_ODBC_CONN"; @@ -248,6 +251,7 @@ bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, /// Get error message from ODBC driver using SQLGetDiagRec std::string GetOdbcErrorMessage(SQLSMALLINT handle_type, SQLHANDLE handle); +static constexpr std::string_view kErrorState00000 = "00000"; static constexpr std::string_view kErrorState01004 = "01004"; static constexpr std::string_view kErrorState01S02 = "01S02"; static constexpr std::string_view kErrorState01S07 = "01S07"; @@ -304,14 +308,19 @@ size_t SqlWCharArrLen(const SQLWCHAR* str_val); /// \brief Check wide char array and convert into wstring /// \param[in] str_val Array of SQLWCHAR. +/// \param[in] str_len length of string, in number of characters. +/// \param[in] buffer_size size of underlying buffer, in number of characters. /// \return wstring -std::wstring ConvertToWString(const SQLWCHAR* str_val); +std::wstring ConvertToWString(const SQLWCHAR* str_val, SQLSMALLINT str_len = -1, + SQLSMALLINT buffer_size = kOdbcBufferSize); /// \brief Check wide char vector and convert into wstring /// \param[in] str_val Vector of SQLWCHAR. /// \param[in] str_len length of string, in bytes. +/// \param[in] buffer_size size of underlying buffer, in number of characters. /// \return wstring -std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len); +std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len, + SQLSMALLINT buffer_size = kOdbcBufferSize); /// \brief Check wide string column. /// \param[in] stmt Statement. 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 0855f3c9751c..d1d97fc3e115 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 @@ -424,7 +424,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtEventUnsupported) { // Driver does not support asynchronous notification ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR, +# ifdef __linux__ + kErrorStateHYC00); +# else // Windows & Mac kErrorStateHY118); +# endif } #endif 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 084809861657..9f7c408bef64 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc @@ -385,9 +385,9 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } // Tests with SQL_C_DEFAULT as the target type @@ -611,9 +611,9 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectVarbinaryQueryDefaultType) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &varbinary_val[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } // TODO(GH-48730): Enable this test when ARD/IRD descriptor support is fully implemented @@ -995,9 +995,9 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); // Verify binary truncation is reported VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); EXPECT_EQ(4, ind); // Fetch same column 2nd time @@ -1008,7 +1008,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val2[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(1, ind); // Attempt to fetch data 3rd time @@ -1131,9 +1131,9 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectNullQueryNullIndicator) { VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); } -// MacOS Driver Manager iODBC returns SQL_ERROR when invalid buffer length is provided to -// SQLGetData -#ifndef __APPLE__ +// The MacOS and Linux Driver Managers return SQL_ERROR when invalid buffer length is +// provided to SQLGetData +#ifdef _WIN32 TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { // Verify the driver ignores invalid buffer length for fixed data types @@ -1331,7 +1331,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { EXPECT_EQ(59, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); } -#endif // __APPLE__ +#endif // _WIN32 TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { // Numeric Types @@ -1656,9 +1656,9 @@ TEST_F(StatementMockTest, TestSQLBindColVarbinaryQuery) { ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); // Check varbinary values - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } TEST_F(StatementRemoteTest, TestSQLBindColNullQuery) { @@ -1943,8 +1943,13 @@ TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) { TYPED_TEST(StatementTest, TestSQLMoreResultsInvalidFunctionSequence) { // Verify function sequence error state is reported when SQLMoreResults is called // without executing any queries +#ifdef __linux__ + ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(stmt)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState00000); +#else // Windows & Mac ASSERT_EQ(SQL_ERROR, SQLMoreResults(stmt)); VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); +#endif } TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputString) { @@ -1961,7 +1966,7 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputString) { // returned length is in characters std::wstring returned_string(buf, buf + output_char_len); - std::wstring input = ConvertToWString(input_str); + std::wstring input = ConvertToWString(input_str, input_str_len); EXPECT_EQ(input, returned_string); } @@ -1979,7 +1984,7 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsNTSInputString) { // returned length is in characters std::wstring returned_string(buf, buf + output_char_len); - std::wstring expected_string = ConvertToWString(input_str); + std::wstring expected_string = ConvertToWString(input_str, input_str_len); EXPECT_EQ(expected_string, returned_string); } @@ -2007,8 +2012,7 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsTruncatedString) { // Create expected return string based on buf size SQLWCHAR expected_string_buf[small_buf_size_in_char]; - wcsncpy(reinterpret_cast(expected_string_buf), - reinterpret_cast(input_str), 10); + std::copy(input_str, input_str + 10, expected_string_buf); expected_string_buf[10] = L'\0'; std::wstring expected_string(expected_string_buf, expected_string_buf + small_buf_size_in_char); @@ -2135,7 +2139,11 @@ TYPED_TEST(StatementTest, SQLRowCountReturnsSuccessOnNullptr) { TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { SQLLEN row_count = 0; +#ifdef __linux__ + SQLLEN expected_value = -1; +#else // Windows & Mac SQLLEN expected_value = 0; +#endif ASSERT_EQ(SQL_ERROR, SQLRowCount(stmt, &row_count)); #ifdef __APPLE__ 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 4fa4d4334990..ca3972a91d04 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -31,7 +31,7 @@ class TablesTest : public T {}; class TablesMockTest : public FlightSQLODBCMockTestBase {}; class TablesRemoteTest : public FlightSQLODBCRemoteTestBase {}; -using TestTypes = ::testing::Types; +using TestTypes = ::testing::Types; TYPED_TEST_SUITE(TablesTest, TestTypes); template @@ -77,6 +77,8 @@ TYPED_TEST(TablesTest, SQLTablesTestInputData) { ValidateFetch(stmt, SQL_SUCCESS); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { SQLWCHAR empty[] = {0}; ASSIGN_SQLWCHAR_ARR(SQL_ALL_CATALOGS_W, L"%"); @@ -96,6 +98,7 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { ValidateFetch(stmt, SQL_NO_DATA); } +#endif // __linux__ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { CreateTestTable(); @@ -137,6 +140,8 @@ TEST_F(TablesMockTest, SQLTablesTestGetSchemaHasNoData) { ValidateFetch(stmt, SQL_NO_DATA); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ TEST_F(TablesRemoteTest, SQLTablesTestGetMetadataForAllSchemas) { SQLWCHAR empty[] = {0}; ASSIGN_SQLWCHAR_ARR(SQL_ALL_SCHEMAS_W, L"%"); @@ -341,6 +346,7 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { DropUnicodeTable(); } +#endif // __linux__ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForInvalidTableNameNoData) { CreateTestTable(); @@ -405,6 +411,8 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { DropTestTable(); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { // Requires creation of user table named ODBCTest using schema $scratch in remote server @@ -433,6 +441,7 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { ValidateFetch(stmt, SQL_NO_DATA); } } +#endif // __linux__ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeViewHasNoData) { SQLWCHAR empty[] = {0}; @@ -449,6 +458,8 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeViewHasNoData) { ValidateFetch(stmt, SQL_NO_DATA); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ TEST_F(TablesMockTest, SQLTablesGetSupportedTableTypes) { SQLWCHAR empty[] = {0}; ASSIGN_SQLWCHAR_ARR(SQL_ALL_TABLE_TYPES_W, L"%"); @@ -489,6 +500,7 @@ TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { ValidateFetch(stmt, SQL_NO_DATA); } +#endif // __linux__ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { SQLWCHAR column_name[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 702d9c8218d4..623f4aa3f500 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 @@ -1649,15 +1649,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoDateODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeDate) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTime) { @@ -1762,15 +1762,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoTimeODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeTime) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTimestamp) { @@ -1874,15 +1874,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTimestampODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeTimestamp) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoInvalidDataType) { From 14537938cb29de4591cfc2939ce46354624808df Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:48:09 -0700 Subject: [PATCH 11/17] ODBC Linux rpm installer support * Implement RPM installer Revert "TEMP - Disable non-ODBC items" This reverts commit efa8d84c696688432ff43689e84123e22a0e47f7. fix formatting Remove todos ODBC rpm Installer wrap up * installing `rpm` package fixed the `cpack` command issue * Fix cpack command on CI (merge into last commit when ready) Change to use `awk` so script works on both platforms Comment out `find` and `tree` steps Change build path to be under /arrow Since docker is mounted, changing build path to be in `/arrow` will allow host machine to access docker build contents TEMP - Disable non-ODBC items Add commands to find build folder Attempt to build RPM installer * not sure if `/build/cpp` can be accessed outside of docker. Hopefully it should. * add `rpm` dependency install Indicate RPM in workflow run Add rpm `postinstall` (not tested) Remove merge conflict code * Enable ODBC installer build in CI instead of `compose.yaml` --- .github/workflows/cpp_extra.yml | 15 ++++++++- .pre-commit-config.yaml | 1 + ci/docker/ubuntu-24.04-cpp.dockerfile | 1 + ci/scripts/cpp_build.sh | 1 + compose.yaml | 9 +++-- cpp/cmake_modules/DefineOptions.cmake | 6 ++++ cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 33 +++++++++++++++---- cpp/src/arrow/flight/sql/odbc/README.md | 16 +++++++++ .../sql/odbc/install/linux/rpm/postinstall | 30 +++++++++++++++++ .../sql/odbc/install/unix/install_odbc.sh | 29 +++++++++------- 10 files changed, 119 insertions(+), 22 deletions(-) create mode 100755 cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index ca1300c9eb54..1d2cb99959c9 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -378,8 +378,12 @@ jobs: matrix: include: - image: ubuntu-cpp-odbc - title: AMD64 Ubuntu Release + title: AMD64 Ubuntu RPM Release build-type: release + format: rpm + run-options: >- + -e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON + -e ODBC_PACKAGE_FORMAT=RPM # GH-49582: TODO Enable Debian build for ODBC # - image: debian-cpp-odbc # title: AMD64 Debian @@ -428,6 +432,15 @@ jobs: sudo sysctl -w vm.mmap_rnd_bits=28 source ci/scripts/util_enable_core_dumps.sh archery docker run ${{ matrix.run-options || '' }} ${{ matrix.image }} + + - name: Upload ODBC ${{ matrix.format }} to the job + if: matrix.build-type == 'release' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-pkg-installer-${{ matrix.format }} + path: build/cpp/ArrowFlightSqlOdbcODBC-*.${{ matrix.format }} + if-no-files-found: error + - name: Docker Push if: >- success() && diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26d31ffecc1c..6d22c1fb0a0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -348,6 +348,7 @@ repos: ?^cpp/examples/minimal_build/run\.sh$| ?^cpp/examples/tutorial_examples/run\.sh$| ?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$| + ?^cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall$| ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$| ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$| ?^dev/release/05-binary-upload\.sh$| diff --git a/ci/docker/ubuntu-24.04-cpp.dockerfile b/ci/docker/ubuntu-24.04-cpp.dockerfile index 074301b472dc..eca5495b12f0 100644 --- a/ci/docker/ubuntu-24.04-cpp.dockerfile +++ b/ci/docker/ubuntu-24.04-cpp.dockerfile @@ -118,6 +118,7 @@ RUN apt-get update -y -q && \ python3-venv \ rados-objclass-dev \ rapidjson-dev \ + rpm \ rsync \ tzdata \ tzdata-legacy \ diff --git a/ci/scripts/cpp_build.sh b/ci/scripts/cpp_build.sh index 1e2f3e8f8f1a..5023c30a5df4 100755 --- a/ci/scripts/cpp_build.sh +++ b/ci/scripts/cpp_build.sh @@ -274,6 +274,7 @@ else -Dlz4_SOURCE=${lz4_SOURCE:-} \ -Dnlohmann_json_SOURCE=${nlohmann_json_SOURCE:-} \ -Dopentelemetry-cpp_SOURCE=${opentelemetry_cpp_SOURCE:-} \ + -DODBC_PACKAGE_FORMAT=${ODBC_PACKAGE_FORMAT:-} \ -DORC_SOURCE=${ORC_SOURCE:-} \ -DPARQUET_BUILD_EXAMPLES=${PARQUET_BUILD_EXAMPLES:-OFF} \ -DPARQUET_BUILD_EXECUTABLES=${PARQUET_BUILD_EXECUTABLES:-OFF} \ diff --git a/compose.yaml b/compose.yaml index d38219d4d4db..f797dbb7246c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -571,14 +571,17 @@ services: ARROW_PARQUET: "OFF" ARROW_S3: "OFF" ARROW_SUBSTRAIT: "OFF" - # Register ODBC before running tests networks: - odbc_net + # Use `/arrow/build` so build artifacts are visible on the CI host + # Generate ODBC installer before testing + # Register ODBC before running tests command: > /bin/bash -c " - /arrow/ci/scripts/cpp_build.sh /arrow /build && + /arrow/ci/scripts/cpp_build.sh /arrow /arrow/build && + (cd /arrow/build/cpp && cpack) && sudo /arrow/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /usr/local/lib/libarrow_flight_sql_odbc.so && - /arrow/ci/scripts/cpp_test.sh /arrow /build" + /arrow/ci/scripts/cpp_test.sh /arrow /arrow/build" ubuntu-cpp-minimal: # Arrow build with minimal components/dependencies diff --git a/cpp/cmake_modules/DefineOptions.cmake b/cpp/cmake_modules/DefineOptions.cmake index 017a5a6efb26..260dc4e9da65 100644 --- a/cpp/cmake_modules/DefineOptions.cmake +++ b/cpp/cmake_modules/DefineOptions.cmake @@ -343,6 +343,12 @@ takes precedence over ccache if a storage backend is configured" ON) ARROW_FLIGHT_SQL ARROW_COMPUTE) + define_option(ARROW_FLIGHT_SQL_ODBC_INSTALLER + "Build the installer Arrow Flight SQL ODBC extension" + OFF + DEPENDS + ARROW_FLIGHT_SQL_ODBC) + define_option(ARROW_GANDIVA "Build the Gandiva libraries" OFF diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index f0b30aa16301..fa6c0938d871 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -156,10 +156,11 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp") else() + set(ODBC_UNIX_FILE_NAME + "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + ) if(APPLE) - set(CPACK_PACKAGE_FILE_NAME - "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" - ) + set(CPACK_PACKAGE_FILE_NAME "${ODBC_UNIX_FILE_NAME}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") set(CPACK_SET_DESTDIR ON) @@ -175,10 +176,28 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(DOC_INSTALL_DIR "arrow-odbc/doc") else() # Linux - # GH-49595: TODO implement DEB installer - # GH-47977: TODO implement RPM installer - message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595") - message(STATUS "ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + if(${ODBC_PACKAGE_FORMAT} STREQUAL "DEB") + # GH-49595 TODO: implement DEB installer + message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595") + elseif(${ODBC_PACKAGE_FORMAT} STREQUAL "RPM") + set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) + set(CPACK_GENERATOR RPM) + set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/rpm/postinstall") + set(CPACK_RPM_FILE_NAME "${ODBC_UNIX_FILE_NAME}.rpm") + # Disable dependency check as ODBC embeds all third party dependencies + set(CPACK_RPM_PACKAGE_AUTOREQPROV "no") + set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1) + set(CPACK_RPM_COMPONENT_INSTALL ON) + else() + message(FATAL_ERROR "ODBC_PACKAGE_FORMAT '${ODBC_PACKAGE_FORMAT}' must be DEB or RPM for Linux installer." + ) + endif() + + # By default, Linux installs under /usr + set(ODBC_INSTALL_DIR "lib64/arrow-odbc/lib") + set(DOC_INSTALL_DIR "lib64/arrow-odbc/doc") endif() # Install ODBC diff --git a/cpp/src/arrow/flight/sql/odbc/README.md b/cpp/src/arrow/flight/sql/odbc/README.md index a2a3fd79041a..9261fbd3bb1b 100644 --- a/cpp/src/arrow/flight/sql/odbc/README.md +++ b/cpp/src/arrow/flight/sql/odbc/README.md @@ -125,6 +125,22 @@ After ODBC has been registered, you can run the ODBC tests. It is recommended to .\cpp\build\< release | debug >\< Release | Debug>\arrow-flight-sql-odbc-test.exe ``` +## Installers + +ODBC installers are uploaded to the CI artifacts. + +| Operating System | Package Format | +|------------------|----------------| +| Windows | MSI | +| macOS | PKG | +| Linux | DEB / RPM | + +### Install `.RPM` on Ubuntu +While installing via `.DEB` installer on Ubuntu is the recommended approach, users may install `.RPM` on Ubuntu using below command +``` +alien -i --scripts ArrowFlightSqlOdbcODBC-.rpm +``` + ## Known Limitations - Conversion from timestamp data type with specified time zone value to strings is not supported at the moment. This doesn't impact driver's usage of retrieving timestamp data from Power BI on Windows, and Excel on macOS and Windows. See GH-47504 for more context. diff --git a/cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall b/cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall new file mode 100755 index 000000000000..df20fab84a97 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall @@ -0,0 +1,30 @@ +#!/bin/bash +# +# 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. + +# Use temporary driver registration script to register ODBC driver in system DSN +odbc_install_script="/usr/lib64/arrow-odbc/lib/install_odbc.sh" +"$odbc_install_script" /usr/lib64/arrow-odbc/lib/libarrow_flight_sql_odbc.so + +# Use temporary DSN registration script to register sample system DSN +dsn_install_script="/usr/lib64/arrow-odbc/lib/install_odbc_ini.sh" +"$dsn_install_script" /etc/odbc.ini + +# clean temporary script +rm -f "$odbc_install_script" +rm -f "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh index b97fabfbadac..8c9423f1218e 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -42,20 +42,20 @@ fi case "$(uname)" in Linux) - USER_ODBCINST_FILE="/etc/odbcinst.ini" + SYSTEM_ODBCINST_FILE="/etc/odbcinst.ini" ;; *) # macOS - USER_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + SYSTEM_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" mkdir -p /Library/ODBC ;; esac DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" -touch "$USER_ODBCINST_FILE" +touch "$SYSTEM_ODBCINST_FILE" -if grep -q "^\[$DRIVER_NAME\]" "$USER_ODBCINST_FILE"; then +if grep -q "^\[$DRIVER_NAME\]" "$SYSTEM_ODBCINST_FILE"; then echo "Driver [$DRIVER_NAME] already exists in odbcinst.ini" else echo "Adding [$DRIVER_NAME] to odbcinst.ini..." @@ -63,17 +63,24 @@ else [$DRIVER_NAME] Description=An ODBC Driver for Apache Arrow Flight SQL Driver=$ODBC_64BIT -" >>"$USER_ODBCINST_FILE" +" >>"$SYSTEM_ODBCINST_FILE" fi # Check if [ODBC Drivers] section exists -if grep -q '^\[ODBC Drivers\]' "$USER_ODBCINST_FILE"; then +if grep -q '^\[ODBC Drivers\]' "$SYSTEM_ODBCINST_FILE"; then # Section exists: check if driver entry exists - if ! grep -q "^${DRIVER_NAME}=" "$USER_ODBCINST_FILE"; then + if ! grep -q "^${DRIVER_NAME}=" "$SYSTEM_ODBCINST_FILE"; then # Driver entry does not exist, add under [ODBC Drivers] - sed -i '' "/^\[ODBC Drivers\]/a\\ -${DRIVER_NAME}=Installed -" "$USER_ODBCINST_FILE" + + awk -v driver="$DRIVER_NAME" ' + $0 ~ /^\[ODBC Drivers\]/ && !inserted { + print + print driver "=Installed" + inserted=1 + next + } + { print } + ' "$SYSTEM_ODBCINST_FILE" > "${SYSTEM_ODBCINST_FILE}.tmp" && mv "${SYSTEM_ODBCINST_FILE}.tmp" "$SYSTEM_ODBCINST_FILE" fi else # Section doesn't exist, append both section and driver entry at end @@ -81,5 +88,5 @@ else echo "" echo "[ODBC Drivers]" echo "${DRIVER_NAME}=Installed" - } >>"$USER_ODBCINST_FILE" + } >>"$SYSTEM_ODBCINST_FILE" fi From d13a98ab48c2eda501abee319f4df02028fdcbe6 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:37:41 -0700 Subject: [PATCH 12/17] Only Run ODBC-related tests on CI * Only Run ODBC-related tests on CI * Increase timeout for macOS * Work on Justin's comment --- ci/scripts/cpp_test.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/scripts/cpp_test.sh b/ci/scripts/cpp_test.sh index 241addbfebd2..17c604680d18 100755 --- a/ci/scripts/cpp_test.sh +++ b/ci/scripts/cpp_test.sh @@ -87,7 +87,11 @@ case "$(uname)" in n_jobs=${NPROC:-1} ;; esac -if [ "${#exclude_tests[@]}" -gt 0 ]; then + +if [ "$ARROW_FLIGHT_SQL_ODBC" = "ON" ]; then + # GH-49816: Only run ODBC tests on ODBC CI pipelines + ctest_options+=(--tests-regex "arrow-flight-sql-odbc-test|arrow-odbc-spi-impl-test") +elif [ "${#exclude_tests[@]}" -gt 0 ]; then IFS="|" ctest_options+=(--exclude-regex "${exclude_tests[*]}") unset IFS From 0cf1afb33d0712c415dc362c7454623283412219 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 21 Apr 2026 10:28:01 -0700 Subject: [PATCH 13/17] Initialize Arrow Compute in global test environment --- cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt | 5 ----- .../arrow/flight/sql/odbc/tests/odbc_test_suite.cc | 12 ++++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt index 79cd45ed0bc8..0f45bfd0c811 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt @@ -42,11 +42,6 @@ set(ARROW_FLIGHT_SQL_ODBC_TEST_SRCS # GH-46889: move protobuf_test_util to a more common location ../../../../engine/substrait/protobuf_test_util.cc) -# Resolve segmentation fault error on Windows platform due to Arrow Compute Library Initialization -if(WIN32) - list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_SRCS ../../../../compute/test_env.cc) -endif() - # GH-49651 Link ODBC tests statically on Linux and dynamically on macOS/Windows if(WIN32 OR APPLE) set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_shared 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 406483a1ce87..47ef32da997a 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 @@ -19,6 +19,7 @@ // with windows.h #include "arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h" +#include "arrow/compute/api.h" #include "arrow/flight/sql/odbc/tests/odbc_test_suite.h" // For DSN registration @@ -82,6 +83,17 @@ class OdbcTestEnvironment : public ::testing::Environment { } }; +#ifdef _WIN32 +// A global test "environment", to ensure Arrow compute kernel functions are registered +class ComputeKernelEnvironment : public ::testing::Environment { + public: + void SetUp() override { ASSERT_OK(arrow::compute::Initialize()); } +}; + +::testing::Environment* compute_kernel_env = + ::testing::AddGlobalTestEnvironment(new ComputeKernelEnvironment); +#endif // _WIN32 + ::testing::Environment* mock_server_env = ::testing::AddGlobalTestEnvironment(new MockServerEnvironment); From d25cddfbb101e1e6cbb5a5ca750e90ede749832c Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 21 Apr 2026 13:15:45 -0700 Subject: [PATCH 14/17] Set ODBC handles as test fixture fields --- .../flight/sql/odbc/tests/columns_test.cc | 527 ++++++------ .../sql/odbc/tests/connection_attr_test.cc | 165 ++-- .../sql/odbc/tests/connection_info_test.cc | 340 ++++---- .../flight/sql/odbc/tests/connection_test.cc | 98 +-- .../flight/sql/odbc/tests/errors_test.cc | 115 +-- .../sql/odbc/tests/get_functions_test.cc | 13 +- .../flight/sql/odbc/tests/odbc_test_suite.cc | 20 +- .../flight/sql/odbc/tests/odbc_test_suite.h | 12 +- .../sql/odbc/tests/statement_attr_test.cc | 189 ++-- .../flight/sql/odbc/tests/statement_test.cc | 804 +++++++++--------- .../flight/sql/odbc/tests/tables_test.cc | 291 +++---- .../flight/sql/odbc/tests/type_info_test.cc | 4 +- 12 files changed, 1323 insertions(+), 1255 deletions(-) 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 571f52c76e13..abe6d8e6994a 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -395,28 +395,29 @@ TYPED_TEST(ColumnsTest, SQLColumnsTestInputData) { SQLWCHAR column_name[] = {0}; // All values populated - EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, catalog_name, sizeof(catalog_name), schema_name, - sizeof(schema_name), table_name, sizeof(table_name), - column_name, sizeof(column_name))); - ValidateFetch(stmt, SQL_NO_DATA); + EXPECT_EQ(SQL_SUCCESS, + SQLColumns(this->stmt, catalog_name, sizeof(catalog_name), schema_name, + sizeof(schema_name), table_name, sizeof(table_name), column_name, + sizeof(column_name))); + ValidateFetch(this->stmt, SQL_NO_DATA); // Sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, catalog_name, 0, schema_name, 0, table_name, 0, - column_name, 0)); - ValidateFetch(stmt, SQL_NO_DATA); + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, catalog_name, 0, schema_name, 0, + table_name, 0, column_name, 0)); + ValidateFetch(this->stmt, SQL_NO_DATA); // Names are nulls - EXPECT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, sizeof(catalog_name), nullptr, sizeof(schema_name), - nullptr, sizeof(table_name), nullptr, sizeof(column_name))); - ValidateFetch(stmt, SQL_SUCCESS); + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, sizeof(catalog_name), nullptr, + sizeof(schema_name), nullptr, sizeof(table_name), + nullptr, sizeof(column_name))); + ValidateFetch(this->stmt, SQL_SUCCESS); // Close statement cursor to avoid leaving in an invalid state - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Names are nulls and sizes are zeros EXPECT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); - ValidateFetch(stmt, SQL_SUCCESS); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + ValidateFetch(this->stmt, SQL_SUCCESS); } // GH-49702: TODO Disabled on Linux due to BlockingQueue issue @@ -428,17 +429,17 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"%"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // mock limitation: SQLite mock server returns 10 for bigint size when spec indicates // should be 19 // DECIMAL_DIGITS should be 0 for bigint type since it is exact // mock limitation: SQLite mock server returns 10 for bigint decimal digits when spec // indicates should be 0 - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -456,9 +457,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"foreignName"), // expected_column @@ -477,9 +478,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"value"), // expected_column @@ -497,9 +498,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"id"), // expected_column @@ -517,9 +518,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"keyName"), // expected_column @@ -538,9 +539,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"value"), // expected_column @@ -558,9 +559,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllColumns) { std::wstring(L"YES")); // expected_is_nullable // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"foreignId"), // expected_column @@ -590,13 +591,13 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"AllTypesTable"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Fetch SQLColumn data for 1st column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"bigint_col"), // expected_column @@ -616,9 +617,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check SQLColumn data for 2nd column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"char_col"), // expected_column @@ -637,9 +638,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check SQLColumn data for 3rd column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"varbinary_col"), // expected_column @@ -658,9 +659,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check SQLColumn data for 4th column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"double_col"), // expected_column @@ -678,7 +679,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // There should be no more column data - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); DropAllDataTypeTable(); } @@ -693,13 +694,13 @@ TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"数据"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check SQLColumn data for 1st column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"数据"), // expected_table std::wstring(L"资料"), // expected_column @@ -718,7 +719,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsUnicode) { std::wstring(L"YES")); // expected_is_nullable // There should be no more column data - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); DropUnicodeTable(); } @@ -730,14 +731,14 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"ODBCTest"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sinteger_max"), // expected_column @@ -755,10 +756,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sbigint_max"), // expected_column @@ -776,9 +777,9 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"decimal_positive"), // expected_column @@ -796,9 +797,9 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"float_max"), // expected_column @@ -816,9 +817,9 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"double_max"), // expected_column @@ -836,9 +837,9 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"bit_true"), // expected_column @@ -860,10 +861,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { // DATA_TYPE field // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"date_max"), // expected_column @@ -881,10 +882,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 8th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"time_max"), // expected_column @@ -902,10 +903,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 9th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"timestamp_max"), // expected_column @@ -923,7 +924,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { @@ -933,14 +934,14 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"ODBCTest"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sinteger_max"), // expected_column @@ -958,10 +959,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sbigint_max"), // expected_column @@ -979,9 +980,9 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"decimal_positive"), // expected_column @@ -999,9 +1000,9 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"float_max"), // expected_column @@ -1019,9 +1020,9 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"double_max"), // expected_column @@ -1039,9 +1040,9 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"bit_true"), // expected_column @@ -1062,10 +1063,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { // ODBC ver 2 returns SQL_DATE, SQL_TIME, and SQL_TIMESTAMP in the DATA_TYPE field // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"date_max"), // expected_column @@ -1083,10 +1084,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 8th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"time_max"), // expected_column @@ -1104,10 +1105,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 9th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"timestamp_max"), // expected_column @@ -1125,7 +1126,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { @@ -1135,13 +1136,13 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"%"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"id"); - EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1159,9 +1160,9 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { std::wstring(L"YES")); // expected_is_nullable // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1179,7 +1180,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { @@ -1189,13 +1190,13 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"foreignTable"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"id"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1213,7 +1214,7 @@ TEST_F(ColumnsMockTest, TestSQLColumnsTableColumnPattern) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } #endif // __linux__ @@ -1221,19 +1222,19 @@ TEST_F(ColumnsMockTest, TestSQLColumnsInvalidTablePattern) { ASSIGN_SQLWCHAR_ARR(table_pattern, L"non-existent-table"); ASSIGN_SQLWCHAR_ARR(column_pattern, L"%"); - ASSERT_EQ(SQL_SUCCESS, SQLColumns(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // There is no column from filter - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT idx = 1; SQLWCHAR character_attr[kOdbcBufferSize]; @@ -1241,32 +1242,32 @@ TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { SQLLEN numeric_attr = 0; // All character values populated - EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, idx, SQL_DESC_NAME, character_attr, + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_DESC_NAME, character_attr, kOdbcBufferSize, &character_attr_len, nullptr)); // All numeric values populated - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, &numeric_attr)); + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, + &numeric_attr)); // Pass null values, driver should not throw error - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_COLUMN_TABLE_NAME, 0, 0, nullptr, nullptr)); + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_COLUMN_TABLE_NAME, 0, 0, + nullptr, nullptr)); EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, nullptr)); + SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, nullptr)); } TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLSMALLINT character_attr_len = 0; // Check length of character attribute - ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, 1, SQL_DESC_BASE_COLUMN_NAME, 0, 0, + ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, 1, SQL_DESC_BASE_COLUMN_NAME, 0, 0, &character_attr_len, nullptr)); EXPECT_EQ(4 * GetSqlWCharSize(), character_attr_len); } @@ -1274,37 +1275,37 @@ TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { TYPED_TEST(ColumnsTest, SQLColAttributeInvalidFieldId) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT invalid_field_id = -100; SQLUSMALLINT idx = 1; SQLWCHAR character_attr[kOdbcBufferSize]; SQLSMALLINT character_attr_len = 0; - ASSERT_EQ(SQL_ERROR, SQLColAttribute(stmt, idx, invalid_field_id, character_attr, + ASSERT_EQ(SQL_ERROR, SQLColAttribute(this->stmt, idx, invalid_field_id, character_attr, kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor field identifier error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY091); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY091); } TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1 as col1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT invalid_col_id = 2; SQLWCHAR character_attr[kOdbcBufferSize]; SQLSMALLINT character_attr_len = 0; - ASSERT_EQ(SQL_ERROR, SQLColAttribute(stmt, invalid_col_id, SQL_DESC_BASE_COLUMN_NAME, - character_attr, kOdbcBufferSize, - &character_attr_len, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLColAttribute(this->stmt, invalid_col_id, + SQL_DESC_BASE_COLUMN_NAME, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor index error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); } TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { @@ -1312,11 +1313,11 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from AllTypesTable;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "bigint_col", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1333,7 +1334,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "char_col", // expected_column_name SQL_WVARCHAR, // expected_data_type SQL_WVARCHAR, // expected_concise_type @@ -1350,7 +1351,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "varbinary_col", // expected_column_name SQL_BINARY, // expected_data_type SQL_BINARY, // expected_concise_type @@ -1367,7 +1368,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "double_col", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1395,10 +1396,10 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from AllTypesTable;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - CheckSQLColAttributes(stmt, 1, + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); + CheckSQLColAttributes(this->stmt, 1, "bigint_col", // expected_column_name SQL_BIGINT, // expected_data_type 20, // expected_display_size @@ -1410,7 +1411,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 2, + CheckSQLColAttributes(this->stmt, 2, "char_col", // expected_column_name SQL_WVARCHAR, // expected_data_type 0, // expected_display_size @@ -1422,7 +1423,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 3, + CheckSQLColAttributes(this->stmt, 3, "varbinary_col", // expected_column_name SQL_BINARY, // expected_data_type 0, // expected_display_size @@ -1434,7 +1435,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 4, + CheckSQLColAttributes(this->stmt, 4, "double_col", // expected_column_name SQL_DOUBLE, // expected_data_type 24, // expected_display_size @@ -1455,11 +1456,11 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type SQL_INTEGER, // expected_concise_type @@ -1476,7 +1477,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1493,7 +1494,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type SQL_DECIMAL, // expected_concise_type @@ -1510,7 +1511,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type SQL_FLOAT, // expected_concise_type @@ -1527,7 +1528,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 5, + CheckSQLColAttribute(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1544,7 +1545,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 6, + CheckSQLColAttribute(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type SQL_BIT, // expected_concise_type @@ -1561,7 +1562,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 7, + CheckSQLColAttribute(this->stmt, 7, "date_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_DATE, // expected_concise_type @@ -1578,7 +1579,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 8, + CheckSQLColAttribute(this->stmt, 8, "time_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_TIME, // expected_concise_type @@ -1595,7 +1596,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 9, + CheckSQLColAttribute(this->stmt, 9, "timestamp_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_TIMESTAMP, // expected_concise_type @@ -1619,11 +1620,11 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { // Test assumes there is a table $scratch.ODBCTest in remote server ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type SQL_INTEGER, // expected_concise_type @@ -1640,7 +1641,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1657,7 +1658,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type SQL_DECIMAL, // expected_concise_type @@ -1674,7 +1675,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type SQL_FLOAT, // expected_concise_type @@ -1691,7 +1692,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 5, + CheckSQLColAttribute(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1708,7 +1709,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 6, + CheckSQLColAttribute(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type SQL_BIT, // expected_concise_type @@ -1725,7 +1726,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 7, + CheckSQLColAttribute(this->stmt, 7, "date_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_DATE, // expected_concise_type @@ -1742,7 +1743,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 8, + CheckSQLColAttribute(this->stmt, 8, "time_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TIME, // expected_concise_type @@ -1759,7 +1760,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 9, + CheckSQLColAttribute(this->stmt, 9, "timestamp_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TIMESTAMP, // expected_concise_type @@ -1783,11 +1784,11 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { // Test assumes there is a table $scratch.ODBCTest in remote server ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from $scratch.ODBCTest;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttributes(stmt, 1, + CheckSQLColAttributes(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type 11, // expected_display_size @@ -1799,7 +1800,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 2, + CheckSQLColAttributes(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type 20, // expected_display_size @@ -1811,7 +1812,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 3, + CheckSQLColAttributes(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type 40, // expected_display_size @@ -1823,7 +1824,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 4, + CheckSQLColAttributes(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type 24, // expected_display_size @@ -1835,7 +1836,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 5, + CheckSQLColAttributes(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type 24, // expected_display_size @@ -1847,7 +1848,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 6, + CheckSQLColAttributes(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type 1, // expected_display_size @@ -1859,7 +1860,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 7, + CheckSQLColAttributes(this->stmt, 7, "date_max", // expected_column_name SQL_DATE, // expected_data_type 10, // expected_display_size @@ -1871,7 +1872,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 8, + CheckSQLColAttributes(this->stmt, 8, "time_max", // expected_column_name SQL_TIME, // expected_data_type 12, // expected_display_size @@ -1883,7 +1884,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 9, + CheckSQLColAttributes(this->stmt, 9, "timestamp_max", // expected_column_name SQL_TIMESTAMP, // expected_data_type 23, // expected_display_size @@ -1903,11 +1904,11 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeCaseSensitive) { std::wstring wsql = this->GetQueryAllDataTypes(); // Int column SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_CASE_SENSITIVE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Varchar column - GetSQLColAttributeNumeric(stmt, wsql, 28, SQL_DESC_CASE_SENSITIVE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 28, SQL_DESC_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); } @@ -1920,11 +1921,11 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesCaseSensitive) { std::wstring wsql = this->GetQueryAllDataTypes(); // Int column SQLLEN value; - GetSQLColAttributesNumeric(stmt, wsql, 1, SQL_COLUMN_CASE_SENSITIVE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Varchar column - GetSQLColAttributesNumeric(stmt, wsql, 28, SQL_COLUMN_CASE_SENSITIVE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 28, SQL_COLUMN_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); } #endif // __APPLE__ @@ -1935,7 +1936,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeUniqueValue) { std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); ASSERT_EQ(SQL_FALSE, value); DropAllDataTypeTable(); @@ -1950,7 +1951,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAutoIncrement) { std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); ASSERT_EQ(SQL_FALSE, value); DropAllDataTypeTable(); @@ -1962,7 +1963,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeBaseTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -1976,7 +1977,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -1990,7 +1991,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeCatalogName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2001,7 +2002,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeCatalogName) { std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); ASSERT_EQ(std::wstring(L""), value); } @@ -2015,7 +2016,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesQualifierName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2026,7 +2027,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesQualifierName) { // Tests ODBC 2.0 API SQLColAttributes std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); ASSERT_EQ(std::wstring(L""), value); } #endif // __APPLE__ @@ -2035,7 +2036,7 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeCount) { std::wstring wsql = this->GetQueryAllDataTypes(); // Pass 0 as column number, driver should ignore it SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 0, SQL_DESC_COUNT, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 0, SQL_DESC_COUNT, &value); ASSERT_EQ(32, value); } @@ -2043,14 +2044,14 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeLocalTypeName) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server doesn't have local type name std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); ASSERT_EQ(std::wstring(L""), value); } TEST_F(ColumnsRemoteTest, TestSQLColAttributeLocalTypeName) { std::wstring wsql = this->GetQueryAllDataTypes(); std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); } @@ -2060,7 +2061,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeSchemaName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2073,7 +2074,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeSchemaName) { // Remote server limitation: doesn't return schema name, expected schema name is // $scratch std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); ASSERT_EQ(std::wstring(L""), value); } @@ -2086,7 +2087,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesOwnerName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2099,7 +2100,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesOwnerName) { // Remote server limitation: doesn't return schema name, expected schema name is // $scratch std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); ASSERT_EQ(std::wstring(L""), value); } #endif // __APPLE__ @@ -2109,7 +2110,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -2120,13 +2121,13 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(stmt, L"", 2, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributeString(stmt, L"", 3, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributeString(stmt, L"", 4, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); DropAllDataTypeTable(); @@ -2135,23 +2136,23 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { TEST_F(ColumnsRemoteTest, TestSQLColAttributeTypeName) { std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributeString(stmt, L"", 2, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(stmt, L"", 3, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributeString(stmt, L"", 4, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributeString(stmt, L"", 5, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 5, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributeString(stmt, L"", 6, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 6, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributeString(stmt, L"", 7, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 7, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributeString(stmt, L"", 8, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 8, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributeString(stmt, L"", 9, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 9, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); } @@ -2164,13 +2165,13 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTypeName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't return data source-dependent data type name std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributesString(stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributesString(stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); DropAllDataTypeTable(); @@ -2180,23 +2181,23 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { // Tests ODBC 2.0 API SQLColAttributes std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributesString(stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributesString(stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributesString(stmt, L"", 5, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 5, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributesString(stmt, L"", 6, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 6, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributesString(stmt, L"", 7, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 7, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributesString(stmt, L"", 8, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 8, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributesString(stmt, L"", 9, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 9, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); } #endif // __APPLE__ @@ -2204,7 +2205,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { TYPED_TEST(ColumnsTest, TestSQLColAttributeUnnamed) { std::wstring wsql = this->GetQueryAllDataTypes(); SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_UNNAMED, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UNNAMED, &value); ASSERT_EQ(SQL_NAMED, value); } @@ -2212,7 +2213,7 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeUpdatable) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server and remote server do not return updatable information SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_UPDATABLE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UPDATABLE, &value); ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); } @@ -2223,7 +2224,7 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesUpdatable) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server and remote server do not return updatable information SQLLEN value; - GetSQLColAttributesNumeric(stmt, wsql, 1, SQL_COLUMN_UPDATABLE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_UPDATABLE, &value); ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); } #endif // __APPLE__ @@ -2244,32 +2245,32 @@ TEST_F(ColumnsMockTest, SQLDescribeColValidateInput) { SQLSMALLINT decimal_digits = 0; SQLSMALLINT nullable = 0; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Invalid descriptor index - Bookmarks are not supported - EXPECT_EQ(SQL_ERROR, - SQLDescribeCol(stmt, bookmark_column, column_name, buf_char_len, &name_length, - &data_type, &column_size, &decimal_digits, &nullable)); + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, bookmark_column, column_name, + buf_char_len, &name_length, &data_type, + &column_size, &decimal_digits, &nullable)); #ifdef __APPLE__ // non-standard odbc error code for invalid column index - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1002); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); #endif // __APPLE__ // Invalid descriptor index - index out of range - EXPECT_EQ(SQL_ERROR, SQLDescribeCol(stmt, out_of_range_column, column_name, + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, out_of_range_column, column_name, buf_char_len, &name_length, &data_type, &column_size, &decimal_digits, &nullable)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); // Invalid descriptor index - index out of range - EXPECT_EQ(SQL_ERROR, - SQLDescribeCol(stmt, negative_column, column_name, buf_char_len, &name_length, - &data_type, &column_size, &decimal_digits, &nullable)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, negative_column, column_name, + buf_char_len, &name_length, &data_type, + &column_size, &decimal_digits, &nullable)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); DropTestTable(); } @@ -2308,15 +2309,15 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { SQL_WVARCHAR, SQL_WVARCHAR}; ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2372,16 +2373,16 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 23, 23}; ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2424,16 +2425,16 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColODBCTestTableMetadata) { SQLULEN column_sizes[] = {4, 8, 19, 8, 8, 1, 10, 12, 23}; SQLULEN columndecimal_digits[] = {0, 0, 0, 0, 0, 0, 10, 12, 23}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2475,16 +2476,16 @@ TEST_F(ColumnsOdbcV2RemoteTest, SQLDescribeColODBCTestTableMetadataODBCVer2) { SQLULEN column_sizes[] = {4, 8, 19, 8, 8, 1, 10, 12, 23}; SQLULEN columndecimal_digits[] = {0, 0, 0, 0, 0, 0, 10, 12, 23}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2522,16 +2523,16 @@ TEST_F(ColumnsMockTest, SQLDescribeColAllTypesTableMetadata) { SQLSMALLINT column_data_types[] = {SQL_BIGINT, SQL_WVARCHAR, SQL_BINARY, SQL_DOUBLE}; SQLULEN column_sizes[] = {8, 0, 0, 8}; - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2566,13 +2567,13 @@ TEST_F(ColumnsMockTest, SQLDescribeColUnicodeTableMetadata) { ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from 数据 LIMIT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, - SQLDescribeCol(stmt, column_index, column_name, buf_char_len, &name_length, - &column_data_type, &column_size, &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); std::wstring expected_column_name_wstr = std::wstring(L"资料"); size_t expected_column_name_len = expected_column_name_wstr.length(); @@ -2612,14 +2613,14 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { 2, 2, 1024, 1024, 2, 2, 4, 4, 1024}; ASSERT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -2674,14 +2675,14 @@ TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBCVer2) { 2, 2, 1024, 1024, 2, 2, 4, 4, 1024}; ASSERT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); 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 9db2ff74a109..c2391f071424 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 @@ -42,58 +42,58 @@ TYPED_TEST_SUITE(ConnectionAttributePreConnectTest, TestTypesHandle); #ifdef SQL_ATTR_ASYNC_DBC_EVENT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); + 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, conn, kErrorStateHY118); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY118); } #endif #ifdef SQL_ATTR_ASYNC_ENABLE TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncEnableUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAutoIpdReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_AUTO_IPD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionDeadReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #ifdef SQL_ATTR_DBC_INFO_TOKEN TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } -TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { +TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { SQLHENV test_env = SQL_NULL_HENV; SQLHDBC test_conn = SQL_NULL_HDBC; this->AllocEnvConnHandles(test_env, test_conn); @@ -110,8 +110,8 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_QUIET_MODE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } // iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACE @@ -119,7 +119,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTraceDMOnly) { // Verify DM-only attribute is settable via Driver Manager ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_TRACE, + SQLSetConnectAttr(this->conn, SQL_ATTR_TRACE, reinterpret_cast(SQL_OPT_TRACE_OFF), 0)); } #endif // __APPLE__ @@ -133,44 +133,46 @@ TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrTracefileDMOn std::vector trace_file0(trace_file.begin(), trace_file.end()); #ifdef _WIN32 - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], static_cast(trace_file0.size()))); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY000); #else // Mac & Linux - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_TRACEFILE, &trace_file0[0], - static_cast(trace_file0.size()))); + ASSERT_EQ(SQL_SUCCESS, + SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + static_cast(trace_file0.size()))); #endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateLabDMOnly) { // Verify DM-only attribute is handled by Driver Manager - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); // Checks for invalid argument return error #ifdef _WIN32 - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY024); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY024); #else // Mac & Linux - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); #endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTxnIsolationUnsupported) { ASSERT_EQ(SQL_ERROR, - SQLSetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, + SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_DBC_INFO_TOKEN TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { // Verify that set-only attribute cannot be read SQLPOINTER ptr = NULL; - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #endif @@ -179,15 +181,16 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrOdbcCursorsDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLULEN cursor_attr; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ODBC_CURSORS, &cursor_attr, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, + &cursor_attr, 0, nullptr)); EXPECT_EQ(SQL_CUR_USE_DRIVER, cursor_attr); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLUINTEGER trace; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_TRACE, &trace, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_TRACE, &trace, 0, nullptr)); EXPECT_EQ(SQL_OPT_TRACE_OFF, trace); } @@ -195,7 +198,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_TRACEFILE, out_str, + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, kOdbcBufferSize, &out_str_len)); // Length is returned in bytes for SQLGetConnectAttr, // we want the number of characters @@ -209,23 +212,23 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) { SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TRANSLATE_LIB, out_str, + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, kOdbcBufferSize, &out_str_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateOptionUnsupported) { SQLINTEGER option; - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, + 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTxnIsolationUnsupported) { SQLINTEGER isolation; - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, + 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE @@ -234,12 +237,13 @@ TYPED_TEST(ConnectionAttributeTest, SQLUINTEGER enable; # ifdef _WIN32 // Verifies that the Windows driver manager returns HY114 for unsupported functionality - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY114); + 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(conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); + ASSERT_EQ( + SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); # endif } #endif @@ -250,7 +254,7 @@ TYPED_TEST(ConnectionAttributeTest, TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcEventDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -259,7 +263,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcEventDefault) { TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcallbackDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -268,7 +272,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcallbackDefaul TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcontextDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -276,33 +280,35 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcontextDefault TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncEnableDefault) { SQLULEN enable; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, nullptr)); EXPECT_EQ(SQL_ASYNC_ENABLE_OFF, enable); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutoIpdDefault) { SQLUINTEGER ipd; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_AUTO_IPD, &ipd, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, &ipd, 0, nullptr)); EXPECT_EQ(static_cast(SQL_FALSE), ipd); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutocommitDefault) { SQLUINTEGER auto_commit; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, nullptr)); EXPECT_EQ(SQL_AUTOCOMMIT_ON, auto_commit); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrEnlistInDtcDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrQuietModeDefault) { HWND ptr = NULL; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_QUIET_MODE, ptr, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } @@ -312,40 +318,40 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAccessModeValid) { // Check default value first SQLUINTEGER mode = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, reinterpret_cast(SQL_MODE_READ_WRITE), 0)); mode = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); // Attempt to set to SQL_MODE_READ_ONLY, driver should return warning and not error EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLSetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, reinterpret_cast(SQL_MODE_READ_ONLY), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + &timeout, 0, nullptr)); EXPECT_EQ(0, timeout); - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast(42), 0)); timeout = -1; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + &timeout, 0, nullptr)); EXPECT_EQ(42, timeout); } @@ -353,15 +359,15 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrLoginTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); EXPECT_EQ(0, timeout); - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast(42), 0)); timeout = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); EXPECT_EQ(42, timeout); } @@ -375,33 +381,34 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) { // Check default value first SQLUINTEGER size = -1; #ifdef __linux__ - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState08003); + 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(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); EXPECT_EQ(0, size); #endif - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(0), 0)); size = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); EXPECT_EQ(0, size); // Attempt to set to non-zero value, #ifdef __linux__ - EXPECT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, + EXPECT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(2), 0)); #else // Windows & Mac // driver should return warning and not error - EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(2), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); #endif } 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 737c5b0ce1d3..a1116bb1c47e 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 @@ -79,10 +79,10 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTruncation) { SQLSMALLINT message_length; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetInfo(conn, SQL_INTEGRITY, value, info_len, &message_length)); + SQLGetInfo(this->conn, SQL_INTEGRITY, value, info_len, &message_length)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01004); EXPECT_GT(message_length, 0); } @@ -90,7 +90,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTruncation) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoActiveEnvironments) { SQLUSMALLINT value; - GetInfo(conn, SQL_ACTIVE_ENVIRONMENTS, &value); + GetInfo(this->conn, SQL_ACTIVE_ENVIRONMENTS, &value); EXPECT_EQ(static_cast(0), value); } @@ -98,7 +98,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoActiveEnvironments) { #ifdef SQL_ASYNC_DBC_FUNCTIONS TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncDbcFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_DBC_FUNCTIONS, &value); + GetInfo(this->conn, SQL_ASYNC_DBC_FUNCTIONS, &value); EXPECT_EQ(static_cast(SQL_ASYNC_DBC_NOT_CAPABLE), value); } @@ -106,7 +106,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncDbcFunctions) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncMode) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_MODE, &value); + GetInfo(this->conn, SQL_ASYNC_MODE, &value); EXPECT_EQ(static_cast(SQL_AM_NONE), value); } @@ -114,7 +114,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncMode) { #ifdef SQL_ASYNC_NOTIFICATION TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncNotification) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_NOTIFICATION, &value); + GetInfo(this->conn, SQL_ASYNC_NOTIFICATION, &value); EXPECT_EQ(static_cast(SQL_ASYNC_NOTIFICATION_NOT_CAPABLE), value); } @@ -122,21 +122,21 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncNotification) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchRowCount) { SQLUINTEGER value; - GetInfo(conn, SQL_BATCH_ROW_COUNT, &value); + GetInfo(this->conn, SQL_BATCH_ROW_COUNT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchSupport) { SQLUINTEGER value; - GetInfo(conn, SQL_BATCH_SUPPORT, &value); + GetInfo(this->conn, SQL_BATCH_SUPPORT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DATA_SOURCE_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_DATA_SOURCE_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -152,7 +152,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) { // driver's return value for it. SQLUINTEGER value; - GetInfo(conn, SQL_DRIVER_AWARE_POOLING_SUPPORTED, &value); + GetInfo(this->conn, SQL_DRIVER_AWARE_POOLING_SUPPORTED, &value); EXPECT_EQ(static_cast(SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE), value); } @@ -163,7 +163,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdbc) { // Value returned from driver manager is the connection address SQLULEN value; - GetInfo(conn, SQL_DRIVER_HDBC, &value); + GetInfo(this->conn, SQL_DRIVER_HDBC, &value); EXPECT_GT(value, static_cast(0)); } @@ -173,11 +173,12 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdesc) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); // Value returned from driver manager is the desc address SQLHDESC local_desc = descriptor; - ASSERT_EQ(SQL_SUCCESS, SQLGetInfo(conn, SQL_HANDLE_DESC, &local_desc, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetInfo(this->conn, SQL_HANDLE_DESC, &local_desc, 0, nullptr)); EXPECT_GT(local_desc, static_cast(0)); // Free descriptor handle @@ -188,7 +189,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdesc) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHenv) { // Value returned from driver manager is the env address SQLULEN value; - GetInfo(conn, SQL_DRIVER_HENV, &value); + GetInfo(this->conn, SQL_DRIVER_HENV, &value); EXPECT_GT(value, static_cast(0)); } @@ -196,7 +197,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHenv) { // These information types are implemented by the Driver Manager alone. TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHlib) { SQLULEN value; - GetInfo(conn, SQL_DRIVER_HLIB, &value); + GetInfo(this->conn, SQL_DRIVER_HLIB, &value); EXPECT_GT(value, static_cast(0)); } @@ -204,14 +205,15 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHlib) { // These information types are implemented by the Driver Manager alone. TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHstmt) { // Value returned from driver manager is the stmt address - SQLHSTMT local_stmt = stmt; - ASSERT_EQ(SQL_SUCCESS, SQLGetInfo(conn, SQL_DRIVER_HSTMT, &local_stmt, 0, nullptr)); + SQLHSTMT local_stmt = this->stmt; + ASSERT_EQ(SQL_SUCCESS, + SQLGetInfo(this->conn, SQL_DRIVER_HSTMT, &local_stmt, 0, nullptr)); EXPECT_GT(local_stmt, static_cast(0)); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DRIVER_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_DRIVER_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"Arrow Flight ODBC Driver"), result); @@ -219,7 +221,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverOdbcVer) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DRIVER_ODBC_VER, value); + GetInfoSQLWCHAR(this->conn, SQL_DRIVER_ODBC_VER, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"03.80"), result); @@ -227,7 +229,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverOdbcVer) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverVer) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DRIVER_VER, value); + GetInfoSQLWCHAR(this->conn, SQL_DRIVER_VER, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"00.09.0000.0"), result); @@ -235,49 +237,49 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverVer) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDynamicCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDynamicCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoForwardOnlyCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(SQL_CA1_NEXT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoForwardOnlyCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(SQL_CA2_READ_ONLY_CONCURRENCY), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoFileUsage) { SQLUSMALLINT value; - GetInfo(conn, SQL_FILE_USAGE, &value); + GetInfo(this->conn, SQL_FILE_USAGE, &value); EXPECT_EQ(static_cast(SQL_FILE_NOT_SUPPORTED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoGetDataExtensions) { SQLUINTEGER value; - GetInfo(conn, SQL_GETDATA_EXTENSIONS, &value); + GetInfo(this->conn, SQL_GETDATA_EXTENSIONS, &value); EXPECT_EQ(static_cast(SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaViews) { SQLUINTEGER value; - GetInfo(conn, SQL_INFO_SCHEMA_VIEWS, &value); + GetInfo(this->conn, SQL_INFO_SCHEMA_VIEWS, &value); EXPECT_EQ(static_cast(SQL_ISV_TABLES | SQL_ISV_COLUMNS | SQL_ISV_VIEWS), value); @@ -285,42 +287,42 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaViews) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeysetCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_KEYSET_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_KEYSET_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeysetCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_KEYSET_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_KEYSET_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxAsyncConcurrentStatements) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_ASYNC_CONCURRENT_STATEMENTS, &value); + GetInfo(this->conn, SQL_MAX_ASYNC_CONCURRENT_STATEMENTS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxConcurrentActivities) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CONCURRENT_ACTIVITIES, &value); + GetInfo(this->conn, SQL_MAX_CONCURRENT_ACTIVITIES, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxDriverConnections) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_DRIVER_CONNECTIONS, &value); + GetInfo(this->conn, SQL_MAX_DRIVER_CONNECTIONS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcInterfaceConformance) { SQLUINTEGER value; - GetInfo(conn, SQL_ODBC_INTERFACE_CONFORMANCE, &value); + GetInfo(this->conn, SQL_ODBC_INTERFACE_CONFORMANCE, &value); EXPECT_EQ(static_cast(SQL_OIC_CORE), value); } @@ -329,7 +331,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcVer) { // This is implemented only in the Driver Manager. SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_ODBC_VER, value); + GetInfoSQLWCHAR(this->conn, SQL_ODBC_VER, value); std::wstring result = ConvertToWString(value); @@ -344,21 +346,21 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcVer) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArrayRowCounts) { SQLUINTEGER value; - GetInfo(conn, SQL_PARAM_ARRAY_ROW_COUNTS, &value); + GetInfo(this->conn, SQL_PARAM_ARRAY_ROW_COUNTS, &value); EXPECT_EQ(static_cast(SQL_PARC_NO_BATCH), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArraySelects) { SQLUINTEGER value; - GetInfo(conn, SQL_PARAM_ARRAY_SELECTS, &value); + GetInfo(this->conn, SQL_PARAM_ARRAY_SELECTS, &value); EXPECT_EQ(static_cast(SQL_PAS_NO_SELECT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoRowUpdates) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_ROW_UPDATES, value); + GetInfoSQLWCHAR(this->conn, SQL_ROW_UPDATES, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -366,7 +368,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoRowUpdates) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSearchPatternEscape) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_SEARCH_PATTERN_ESCAPE, value); + GetInfoSQLWCHAR(this->conn, SQL_SEARCH_PATTERN_ESCAPE, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"\\"), result); @@ -374,7 +376,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSearchPatternEscape) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoServerName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_SERVER_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_SERVER_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_GT(result.length(), 0); @@ -382,14 +384,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoServerName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_STATIC_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_STATIC_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_STATIC_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_STATIC_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } @@ -398,7 +400,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes2) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDatabaseName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DATABASE_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_DATABASE_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -406,7 +408,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDatabaseName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DBMS_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_DBMS_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_GT(result.length(), 0); @@ -414,7 +416,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DBMS_VER, value); + GetInfoSQLWCHAR(this->conn, SQL_DBMS_VER, value); std::wstring result = ConvertToWString(value); EXPECT_GT(result.length(), 0); @@ -424,7 +426,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleProcedures) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_ACCESSIBLE_PROCEDURES, value); + GetInfoSQLWCHAR(this->conn, SQL_ACCESSIBLE_PROCEDURES, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -432,7 +434,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleProcedures) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleTables) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_ACCESSIBLE_TABLES, value); + GetInfoSQLWCHAR(this->conn, SQL_ACCESSIBLE_TABLES, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"Y"), result); @@ -440,14 +442,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleTables) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBookmarkPersistence) { SQLUINTEGER value; - GetInfo(conn, SQL_BOOKMARK_PERSISTENCE, &value); + GetInfo(this->conn, SQL_BOOKMARK_PERSISTENCE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogTerm) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_CATALOG_TERM, value); + GetInfoSQLWCHAR(this->conn, SQL_CATALOG_TERM, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -455,7 +457,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogTerm) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCollationSeq) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_COLLATION_SEQ, value); + GetInfoSQLWCHAR(this->conn, SQL_COLLATION_SEQ, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -463,35 +465,35 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCollationSeq) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConcatNullBehavior) { SQLUSMALLINT value; - GetInfo(conn, SQL_CONCAT_NULL_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CONCAT_NULL_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_NULL), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorCommitBehavior) { SQLUSMALLINT value; - GetInfo(conn, SQL_CURSOR_COMMIT_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CURSOR_COMMIT_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_CLOSE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorRollbackBehavior) { SQLUSMALLINT value; - GetInfo(conn, SQL_CURSOR_ROLLBACK_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CURSOR_ROLLBACK_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_CLOSE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorSensitivity) { SQLUINTEGER value; - GetInfo(conn, SQL_CURSOR_SENSITIVITY, &value); + GetInfo(this->conn, SQL_CURSOR_SENSITIVITY, &value); EXPECT_EQ(static_cast(SQL_UNSPECIFIED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceReadOnly) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DATA_SOURCE_READ_ONLY, value); + GetInfoSQLWCHAR(this->conn, SQL_DATA_SOURCE_READ_ONLY, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -499,14 +501,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceReadOnly) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDefaultTxnIsolation) { SQLUINTEGER value; - GetInfo(conn, SQL_DEFAULT_TXN_ISOLATION, &value); + GetInfo(this->conn, SQL_DEFAULT_TXN_ISOLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDescribeParameter) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_DESCRIBE_PARAMETER, value); + GetInfoSQLWCHAR(this->conn, SQL_DESCRIBE_PARAMETER, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -514,7 +516,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDescribeParameter) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultResultSets) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_MULT_RESULT_SETS, value); + GetInfoSQLWCHAR(this->conn, SQL_MULT_RESULT_SETS, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -522,7 +524,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultResultSets) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultipleActiveTxn) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_MULTIPLE_ACTIVE_TXN, value); + GetInfoSQLWCHAR(this->conn, SQL_MULTIPLE_ACTIVE_TXN, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -530,7 +532,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMultipleActiveTxn) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoNeedLongDataLen) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_NEED_LONG_DATA_LEN, value); + GetInfoSQLWCHAR(this->conn, SQL_NEED_LONG_DATA_LEN, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -538,13 +540,13 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoNeedLongDataLen) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNullCollation) { SQLUSMALLINT value; - GetInfo(conn, SQL_NULL_COLLATION, &value); + GetInfo(this->conn, SQL_NULL_COLLATION, &value); EXPECT_EQ(static_cast(SQL_NC_START), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoProcedureTerm) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_PROCEDURE_TERM, value); + GetInfoSQLWCHAR(this->conn, SQL_PROCEDURE_TERM, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -552,7 +554,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoProcedureTerm) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaTerm) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_SCHEMA_TERM, value); + GetInfoSQLWCHAR(this->conn, SQL_SCHEMA_TERM, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"schema"), result); @@ -560,14 +562,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaTerm) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoScrollOptions) { SQLUINTEGER value; - GetInfo(conn, SQL_SCROLL_OPTIONS, &value); + GetInfo(this->conn, SQL_SCROLL_OPTIONS, &value); EXPECT_EQ(static_cast(SQL_SO_FORWARD_ONLY), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTableTerm) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_TABLE_TERM, value); + GetInfoSQLWCHAR(this->conn, SQL_TABLE_TERM, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"table"), result); @@ -575,21 +577,21 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTableTerm) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnCapable) { SQLUSMALLINT value; - GetInfo(conn, SQL_TXN_CAPABLE, &value); + GetInfo(this->conn, SQL_TXN_CAPABLE, &value); EXPECT_EQ(static_cast(SQL_TC_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnIsolationOption) { SQLUINTEGER value; - GetInfo(conn, SQL_TXN_ISOLATION_OPTION, &value); + GetInfo(this->conn, SQL_TXN_ISOLATION_OPTION, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoUserName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_USER_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_USER_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -599,7 +601,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoUserName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAggregateFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_AGGREGATE_FUNCTIONS, &value); + GetInfo(this->conn, SQL_AGGREGATE_FUNCTIONS, &value); EXPECT_EQ(value, static_cast(SQL_AF_ALL | SQL_AF_AVG | SQL_AF_COUNT | SQL_AF_DISTINCT | SQL_AF_MAX | SQL_AF_MIN | @@ -608,14 +610,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAggregateFunctions) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_ALTER_DOMAIN, &value); + GetInfo(this->conn, SQL_ALTER_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { SQLUINTEGER value; - GetInfo(conn, SQL_ALTER_TABLE, &value); + GetInfo(this->conn, SQL_ALTER_TABLE, &value); EXPECT_EQ(static_cast(0), value); } @@ -623,20 +625,20 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoCatalogLocation) { // GH-49482 TODO: resolve inconsitent return value for SQL_CATALOG_LOCATION and change // test type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString(), conn); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUSMALLINT value; - GetInfo(conn, SQL_CATALOG_LOCATION, &value); + GetInfo(this->conn, SQL_CATALOG_LOCATION, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogName) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_CATALOG_NAME, value); + GetInfoSQLWCHAR(this->conn, SQL_CATALOG_NAME, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -644,7 +646,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogName) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogNameSeparator) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_CATALOG_NAME_SEPARATOR, value); + GetInfoSQLWCHAR(this->conn, SQL_CATALOG_NAME_SEPARATOR, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -652,14 +654,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogNameSeparator) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCatalogUsage) { SQLUINTEGER value; - GetInfo(conn, SQL_CATALOG_USAGE, &value); + GetInfo(this->conn, SQL_CATALOG_USAGE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoColumnAlias) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_COLUMN_ALIAS, value); + GetInfoSQLWCHAR(this->conn, SQL_COLUMN_ALIAS, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"Y"), result); @@ -667,91 +669,91 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoColumnAlias) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCorrelationName) { SQLUSMALLINT value; - GetInfo(conn, SQL_CORRELATION_NAME, &value); + GetInfo(this->conn, SQL_CORRELATION_NAME, &value); EXPECT_EQ(static_cast(SQL_CN_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateAssertion) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_ASSERTION, &value); + GetInfo(this->conn, SQL_CREATE_ASSERTION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateCharacterSet) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_CHARACTER_SET, &value); + GetInfo(this->conn, SQL_CREATE_CHARACTER_SET, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateCollation) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_COLLATION, &value); + GetInfo(this->conn, SQL_CREATE_COLLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_DOMAIN, &value); + GetInfo(this->conn, SQL_CREATE_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCreateSchema) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_SCHEMA, &value); + GetInfo(this->conn, SQL_CREATE_SCHEMA, &value); EXPECT_EQ(static_cast(1), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCreateTable) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_TABLE, &value); + GetInfo(this->conn, SQL_CREATE_TABLE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateTranslation) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_TRANSLATION, &value); + GetInfo(this->conn, SQL_CREATE_TRANSLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDdlIndex) { SQLUINTEGER value; - GetInfo(conn, SQL_DDL_INDEX, &value); + GetInfo(this->conn, SQL_DDL_INDEX, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropAssertion) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_ASSERTION, &value); + GetInfo(this->conn, SQL_DROP_ASSERTION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropCharacterSet) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_CHARACTER_SET, &value); + GetInfo(this->conn, SQL_DROP_CHARACTER_SET, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropCollation) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_COLLATION, &value); + GetInfo(this->conn, SQL_DROP_COLLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_DOMAIN, &value); + GetInfo(this->conn, SQL_DROP_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } @@ -759,48 +761,48 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_SCHEMA and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString(), conn); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUINTEGER value; - GetInfo(conn, SQL_DROP_SCHEMA, &value); + GetInfo(this->conn, SQL_DROP_SCHEMA, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropTable) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_TABLE and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString(), conn); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUINTEGER value; - GetInfo(conn, SQL_DROP_TABLE, &value); + GetInfo(this->conn, SQL_DROP_TABLE, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropTranslation) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_TRANSLATION, &value); + GetInfo(this->conn, SQL_DROP_TRANSLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropView) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_VIEW, &value); + GetInfo(this->conn, SQL_DROP_VIEW, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoExpressionsInOrderby) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_EXPRESSIONS_IN_ORDERBY, value); + GetInfoSQLWCHAR(this->conn, SQL_EXPRESSIONS_IN_ORDERBY, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -808,21 +810,21 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoExpressionsInOrderby) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoGroupBy) { SQLUSMALLINT value; - GetInfo(conn, SQL_GROUP_BY, &value); + GetInfo(this->conn, SQL_GROUP_BY, &value); EXPECT_EQ(static_cast(SQL_GB_GROUP_BY_CONTAINS_SELECT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierCase) { SQLUSMALLINT value; - GetInfo(conn, SQL_IDENTIFIER_CASE, &value); + GetInfo(this->conn, SQL_IDENTIFIER_CASE, &value); EXPECT_EQ(static_cast(SQL_IC_MIXED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierQuoteChar) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_IDENTIFIER_QUOTE_CHAR, value); + GetInfoSQLWCHAR(this->conn, SQL_IDENTIFIER_QUOTE_CHAR, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"\""), result); @@ -830,14 +832,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierQuoteChar) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIndexKeywords) { SQLUINTEGER value; - GetInfo(conn, SQL_INDEX_KEYWORDS, &value); + GetInfo(this->conn, SQL_INDEX_KEYWORDS, &value); EXPECT_EQ(static_cast(SQL_IK_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoInsertStatement) { SQLUINTEGER value; - GetInfo(conn, SQL_INSERT_STATEMENT, &value); + GetInfo(this->conn, SQL_INSERT_STATEMENT, &value); EXPECT_EQ(value, static_cast(SQL_IS_INSERT_LITERALS | SQL_IS_INSERT_SEARCHED | SQL_IS_SELECT_INTO)); @@ -845,7 +847,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoInsertStatement) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIntegrity) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_INTEGRITY, value); + GetInfoSQLWCHAR(this->conn, SQL_INTEGRITY, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -855,7 +857,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { // Keyword strings can require 10000 buffer length static constexpr int info_len = kOdbcBufferSize * 10; SQLWCHAR value[info_len] = {}; - GetInfoSQLWCHAR(conn, SQL_KEYWORDS, value, info_len); + GetInfoSQLWCHAR(this->conn, SQL_KEYWORDS, value, info_len); std::wstring result = ConvertToWString(value, -1, info_len); EXPECT_GT(result.length(), 0); @@ -863,7 +865,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeywords) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_LIKE_ESCAPE_CLAUSE, value); + GetInfoSQLWCHAR(this->conn, SQL_LIKE_ESCAPE_CLAUSE, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"Y"), result); @@ -871,21 +873,21 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNonNullableColumns) { SQLUSMALLINT value; - GetInfo(conn, SQL_NON_NULLABLE_COLUMNS, &value); + GetInfo(this->conn, SQL_NON_NULLABLE_COLUMNS, &value); EXPECT_EQ(static_cast(SQL_NNC_NULL), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOjCapabilities) { SQLUINTEGER value; - GetInfo(conn, SQL_OJ_CAPABILITIES, &value); + GetInfo(this->conn, SQL_OJ_CAPABILITIES, &value); EXPECT_EQ(static_cast(SQL_OJ_LEFT | SQL_OJ_RIGHT | SQL_OJ_FULL), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOrderByColumnsInSelect) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, value); + GetInfoSQLWCHAR(this->conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"Y"), result); @@ -893,7 +895,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOrderByColumnsInSelect) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOuterJoins) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_OUTER_JOINS, value); + GetInfoSQLWCHAR(this->conn, SQL_OUTER_JOINS, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -901,7 +903,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOuterJoins) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoProcedures) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_PROCEDURES, value); + GetInfoSQLWCHAR(this->conn, SQL_PROCEDURES, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -909,21 +911,21 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoProcedures) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoQuotedIdentifierCase) { SQLUSMALLINT value; - GetInfo(conn, SQL_QUOTED_IDENTIFIER_CASE, &value); + GetInfo(this->conn, SQL_QUOTED_IDENTIFIER_CASE, &value); EXPECT_EQ(static_cast(SQL_IC_MIXED), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSchemaUsage) { SQLUINTEGER value; - GetInfo(conn, SQL_SCHEMA_USAGE, &value); + GetInfo(this->conn, SQL_SCHEMA_USAGE, &value); EXPECT_EQ(static_cast(SQL_SU_DML_STATEMENTS), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSpecialCharacters) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_SPECIAL_CHARACTERS, value); + GetInfoSQLWCHAR(this->conn, SQL_SPECIAL_CHARACTERS, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -931,14 +933,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSpecialCharacters) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSqlConformance) { SQLUINTEGER value; - GetInfo(conn, SQL_SQL_CONFORMANCE, &value); + GetInfo(this->conn, SQL_SQL_CONFORMANCE, &value); EXPECT_EQ(static_cast(SQL_SC_SQL92_ENTRY), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSubqueries) { SQLUINTEGER value; - GetInfo(conn, SQL_SUBQUERIES, &value); + GetInfo(this->conn, SQL_SUBQUERIES, &value); EXPECT_EQ(value, static_cast(SQL_SQ_CORRELATED_SUBQUERIES | SQL_SQ_COMPARISON | @@ -947,7 +949,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSubqueries) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoUnion) { SQLUINTEGER value; - GetInfo(conn, SQL_UNION, &value); + GetInfo(this->conn, SQL_UNION, &value); EXPECT_EQ(static_cast(SQL_U_UNION | SQL_U_UNION_ALL), value); } @@ -956,98 +958,98 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoUnion) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxBinaryLiteralLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_BINARY_LITERAL_LEN, &value); + GetInfo(this->conn, SQL_MAX_BINARY_LITERAL_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxCatalogNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CATALOG_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_CATALOG_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxCharLiteralLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_CHAR_LITERAL_LEN, &value); + GetInfo(this->conn, SQL_MAX_CHAR_LITERAL_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxColumnNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMN_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_COLUMN_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInGroupBy) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_GROUP_BY, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_GROUP_BY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInIndex) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_INDEX, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_INDEX, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInOrderBy) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_ORDER_BY, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_ORDER_BY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInSelect) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_SELECT, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_SELECT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInTable) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_TABLE, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_TABLE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxCursorNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CURSOR_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_CURSOR_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxIdentifierLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_IDENTIFIER_LEN, &value); + GetInfo(this->conn, SQL_MAX_IDENTIFIER_LEN, &value); EXPECT_EQ(static_cast(65535), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxIndexSize) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_INDEX_SIZE, &value); + GetInfo(this->conn, SQL_MAX_INDEX_SIZE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxProcedureNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_PROCEDURE_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_PROCEDURE_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxRowSize) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_MAX_ROW_SIZE, value); + GetInfoSQLWCHAR(this->conn, SQL_MAX_ROW_SIZE, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L""), result); @@ -1055,7 +1057,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxRowSize) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxRowSizeIncludesLong) { SQLWCHAR value[kOdbcBufferSize] = {}; - GetInfoSQLWCHAR(conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, value); + GetInfoSQLWCHAR(this->conn, SQL_MAX_ROW_SIZE_INCLUDES_LONG, value); std::wstring result = ConvertToWString(value); EXPECT_EQ(std::wstring(L"N"), result); @@ -1063,35 +1065,35 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxRowSizeIncludesLong) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxSchemaNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_SCHEMA_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_SCHEMA_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxStatementLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_STATEMENT_LEN, &value); + GetInfo(this->conn, SQL_MAX_STATEMENT_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxTableNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_TABLE_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_TABLE_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxTablesInSelect) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_TABLES_IN_SELECT, &value); + GetInfo(this->conn, SQL_MAX_TABLES_IN_SELECT, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxUserNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_USER_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_USER_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } @@ -1100,21 +1102,21 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxUserNameLen) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_FUNCTIONS, &value); + GetInfo(this->conn, SQL_CONVERT_FUNCTIONS, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNumericFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_NUMERIC_FUNCTIONS, &value); + GetInfo(this->conn, SQL_NUMERIC_FUNCTIONS, &value); EXPECT_EQ(static_cast(4058942), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoStringFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_STRING_FUNCTIONS, &value); + GetInfo(this->conn, SQL_STRING_FUNCTIONS, &value); EXPECT_EQ(value, static_cast(SQL_FN_STR_LTRIM | SQL_FN_STR_LENGTH | SQL_FN_STR_REPLACE | SQL_FN_STR_RTRIM)); @@ -1122,14 +1124,14 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoStringFunctions) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSystemFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_SYSTEM_FUNCTIONS, &value); + GetInfo(this->conn, SQL_SYSTEM_FUNCTIONS, &value); EXPECT_EQ(static_cast(SQL_FN_SYS_IFNULL | SQL_FN_SYS_USERNAME), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateAddIntervals) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_ADD_INTERVALS, &value); + GetInfo(this->conn, SQL_TIMEDATE_ADD_INTERVALS, &value); EXPECT_EQ(value, static_cast( SQL_FN_TSI_FRAC_SECOND | SQL_FN_TSI_SECOND | SQL_FN_TSI_MINUTE | @@ -1139,7 +1141,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateAddIntervals) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateDiffIntervals) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_DIFF_INTERVALS, &value); + GetInfo(this->conn, SQL_TIMEDATE_DIFF_INTERVALS, &value); EXPECT_EQ(value, static_cast( SQL_FN_TSI_FRAC_SECOND | SQL_FN_TSI_SECOND | SQL_FN_TSI_MINUTE | @@ -1149,7 +1151,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateDiffIntervals) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoTimedateFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_FUNCTIONS, &value); + GetInfo(this->conn, SQL_TIMEDATE_FUNCTIONS, &value); EXPECT_EQ(value, static_cast( @@ -1166,147 +1168,147 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoTimedateFunctions) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertBigint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BIGINT, &value); + GetInfo(this->conn, SQL_CONVERT_BIGINT, &value); EXPECT_EQ(static_cast(8), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertBinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BINARY, &value); + GetInfo(this->conn, SQL_CONVERT_BINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertBit) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BIT, &value); + GetInfo(this->conn, SQL_CONVERT_BIT, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertChar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_CHAR, &value); + GetInfo(this->conn, SQL_CONVERT_CHAR, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertDate) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DATE, &value); + GetInfo(this->conn, SQL_CONVERT_DATE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertDecimal) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DECIMAL, &value); + GetInfo(this->conn, SQL_CONVERT_DECIMAL, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertDouble) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DOUBLE, &value); + GetInfo(this->conn, SQL_CONVERT_DOUBLE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertFloat) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_FLOAT, &value); + GetInfo(this->conn, SQL_CONVERT_FLOAT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertInteger) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTEGER, &value); + GetInfo(this->conn, SQL_CONVERT_INTEGER, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertIntervalDayTime) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTERVAL_DAY_TIME, &value); + GetInfo(this->conn, SQL_CONVERT_INTERVAL_DAY_TIME, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertIntervalYearMonth) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTERVAL_YEAR_MONTH, &value); + GetInfo(this->conn, SQL_CONVERT_INTERVAL_YEAR_MONTH, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertLongvarbinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_LONGVARBINARY, &value); + GetInfo(this->conn, SQL_CONVERT_LONGVARBINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertLongvarchar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_LONGVARCHAR, &value); + GetInfo(this->conn, SQL_CONVERT_LONGVARCHAR, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertNumeric) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_NUMERIC, &value); + GetInfo(this->conn, SQL_CONVERT_NUMERIC, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertReal) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_REAL, &value); + GetInfo(this->conn, SQL_CONVERT_REAL, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertSmallint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_SMALLINT, &value); + GetInfo(this->conn, SQL_CONVERT_SMALLINT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTime) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TIME, &value); + GetInfo(this->conn, SQL_CONVERT_TIME, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTimestamp) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TIMESTAMP, &value); + GetInfo(this->conn, SQL_CONVERT_TIMESTAMP, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTinyint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TINYINT, &value); + GetInfo(this->conn, SQL_CONVERT_TINYINT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertVarbinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_VARBINARY, &value); + GetInfo(this->conn, SQL_CONVERT_VARBINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertVarchar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_VARCHAR, &value); + GetInfo(this->conn, SQL_CONVERT_VARCHAR, &value); EXPECT_EQ(static_cast(0), value); } 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 5c816d5ca9d5..837c18c9cbdf 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc @@ -155,7 +155,7 @@ TYPED_TEST(ConnectionTest, TestSQLGetEnvAttrOutputNTS) { SQLINTEGER output_nts; ASSERT_EQ(SQL_SUCCESS, - SQLGetEnvAttr(env, SQL_ATTR_OUTPUT_NTS, &output_nts, 0, nullptr)); + SQLGetEnvAttr(this->env, SQL_ATTR_OUTPUT_NTS, &output_nts, 0, nullptr)); ASSERT_EQ(SQL_TRUE, output_nts); } @@ -165,7 +165,8 @@ TYPED_TEST(ConnectionTest, DISABLED_TestSQLGetEnvAttrGetLength) { // Windows. Windows driver manager ignores the length pointer. // This test case can be potentially used on macOS/Linux SQLINTEGER length; - ASSERT_EQ(SQL_SUCCESS, SQLGetEnvAttr(env, SQL_ATTR_ODBC_VERSION, nullptr, 0, &length)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, nullptr, 0, &length)); EXPECT_EQ(sizeof(SQLINTEGER), length); } @@ -174,7 +175,8 @@ TYPED_TEST(ConnectionTest, DISABLED_TestSQLGetEnvAttrNullValuePointer) { // Test is disabled because call to SQLGetEnvAttr is handled by the driver manager on // Windows. The Windows driver manager doesn't error out when null pointer is passed. // This test case can be potentially used on macOS/Linux - ASSERT_EQ(SQL_ERROR, SQLGetEnvAttr(env, SQL_ATTR_ODBC_VERSION, nullptr, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, nullptr, 0, nullptr)); } TEST(SQLSetEnvAttr, TestSQLSetEnvAttrOutputNTSValid) { @@ -227,10 +229,10 @@ TYPED_TEST(ConnectionHandleTest, 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); @@ -242,8 +244,8 @@ TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnect) { ASSERT_TRUE(CompareConnPropertyMap(out_properties, in_properties)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnectDsn) { @@ -269,17 +271,17 @@ TYPED_TEST(ConnectionHandleTest, 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); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionHandleTest, TestSQLConnect) { @@ -301,17 +303,17 @@ TYPED_TEST(ConnectionHandleTest, 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); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { @@ -342,17 +344,17 @@ TEST_F(ConnectionRemoteTest, 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); + << 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); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { @@ -384,11 +386,11 @@ TEST_F(ConnectionRemoteTest, 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)); @@ -416,17 +418,17 @@ TEST_F(ConnectionRemoteTest, 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); + << 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); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { @@ -442,11 +444,11 @@ TEST_F(ConnectionRemoteTest, 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()); @@ -454,17 +456,17 @@ TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { 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); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState08003); } TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) { SQLHSTMT statement; // Allocate a statement using alloc statement - ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(conn, &statement)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement)); // Close statement handle ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_CLOSE)); @@ -487,23 +489,23 @@ TYPED_TEST(ConnectionHandleTest, 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)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << 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)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)); } TYPED_TEST(ConnectionTest, TestSQLAllocFreeDesc) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); // Free descriptor handle ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DESC, descriptor)); @@ -513,37 +515,37 @@ TYPED_TEST(ConnectionTest, TestSQLSetStmtAttrDescriptor) { SQLHDESC apd_descriptor, ard_descriptor; // Allocate an APD descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &apd_descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &apd_descriptor)); // Allocate an ARD descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &ard_descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &ard_descriptor)); // Save implicitly allocated internal APD and ARD descriptor pointers SQLPOINTER internal_apd, internal_ard = nullptr; - EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &internal_apd, - sizeof(internal_apd), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, + &internal_apd, sizeof(internal_apd), 0)); - EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &internal_ard, + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &internal_ard, sizeof(internal_ard), 0)); // Set APD descriptor to explicitly allocated handle - EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, + EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, reinterpret_cast(apd_descriptor), 0)); // Set ARD descriptor to explicitly allocated handle - EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, + EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, reinterpret_cast(ard_descriptor), 0)); // Verify APD and ARD descriptors are set to explicitly allocated pointers SQLPOINTER value = nullptr; - EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value, sizeof(value), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value, + sizeof(value), 0)); EXPECT_EQ(apd_descriptor, value); EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); EXPECT_EQ(ard_descriptor, value); @@ -555,13 +557,13 @@ TYPED_TEST(ConnectionTest, TestSQLSetStmtAttrDescriptor) { // Verify APD and ARD descriptors has been reverted to implicit descriptors value = nullptr; - EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value, sizeof(value), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value, + sizeof(value), 0)); EXPECT_EQ(internal_apd, value); EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); EXPECT_EQ(internal_ard, value); } 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 d12d8669ee9e..7e734accb8d5 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -62,7 +62,7 @@ TYPED_TEST(ErrorsHandleTest, 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)); @@ -75,7 +75,7 @@ TYPED_TEST(ErrorsHandleTest, 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); @@ -85,15 +85,16 @@ TYPED_TEST(ErrorsHandleTest, 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 SQLWCHAR message_text[kOdbcBufferSize]; SQLSMALLINT message_text_length; - SQLRETURN ret = SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, - message_text, kOdbcBufferSize, &message_text_length); + SQLRETURN ret = + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, + message_text, kOdbcBufferSize, &message_text_length); // dependent on the size of the message it could output SQL_SUCCESS_WITH_INFO EXPECT_TRUE(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO); @@ -105,8 +106,8 @@ TYPED_TEST(ErrorsHandleTest, 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); @@ -115,9 +116,10 @@ TYPED_TEST(ErrorsHandleTest, 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 * GetSqlWCharSize(), &sql_state_length)); + EXPECT_EQ( + SQL_SUCCESS, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_SQLSTATE, sql_state, + sql_state_size * GetSqlWCharSize(), &sql_state_length)); EXPECT_EQ(kErrorState28000, SqlWcharToString(sql_state)); } @@ -138,7 +140,7 @@ TYPED_TEST(ErrorsHandleTest, 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)); @@ -152,7 +154,7 @@ TYPED_TEST(ErrorsHandleTest, 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); @@ -164,7 +166,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagFieldWForDescriptorFailureFromDriverManager SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); EXPECT_EQ(SQL_ERROR, SQLGetDescField(descriptor, 1, SQL_DESC_DATETIME_INTERVAL_CODE, 0, 0, nullptr)); @@ -230,7 +232,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForDescriptorFailureFromDriverManager) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); EXPECT_EQ(SQL_ERROR, SQLGetDescField(descriptor, 1, SQL_DESC_DATETIME_INTERVAL_CODE, 0, 0, nullptr)); @@ -272,7 +274,7 @@ TYPED_TEST(ErrorsHandleTest, 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)); @@ -280,8 +282,9 @@ TYPED_TEST(ErrorsHandleTest, 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); @@ -302,17 +305,18 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) { SQLSMALLINT message_length; // Pass invalid record number - EXPECT_EQ(SQL_ERROR, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 0, sql_state, &native_error, - message, kOdbcBufferSize, &message_length)); + EXPECT_EQ(SQL_ERROR, + SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 0, sql_state, &native_error, + message, kOdbcBufferSize, &message_length)); // Pass valid record number with null inputs - EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 1, nullptr, nullptr, nullptr, - 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 1, nullptr, nullptr, + nullptr, 0, nullptr)); #ifdef __APPLE__ // MacOS ODBC driver manager requires connection handle EXPECT_EQ(SQL_INVALID_HANDLE, - SQLGetDiagRec(0, conn, 1, nullptr, nullptr, nullptr, 0, nullptr)); + SQLGetDiagRec(0, this->conn, 1, nullptr, nullptr, nullptr, 0, nullptr)); #else // Linux & Windows driver managers have different expected return values # ifdef __linux__ @@ -331,17 +335,17 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorInputData) { // Pass valid handles with null inputs EXPECT_EQ(SQL_NO_DATA, - SQLError(env, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); + SQLError(this->env, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); - EXPECT_EQ(SQL_NO_DATA, - SQLError(nullptr, conn, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(nullptr, this->conn, nullptr, nullptr, nullptr, nullptr, + 0, nullptr)); #ifdef __APPLE__ - EXPECT_EQ(SQL_NO_DATA, - SQLError(SQL_NULL_HENV, conn, stmt, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(SQL_NULL_HENV, this->conn, this->stmt, nullptr, nullptr, + nullptr, 0, nullptr)); #else - EXPECT_EQ(SQL_NO_DATA, - SQLError(nullptr, nullptr, stmt, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(nullptr, nullptr, this->stmt, nullptr, nullptr, nullptr, + 0, nullptr)); #endif // __APPLE__ // Invalid handle @@ -356,14 +360,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorEnvErrorFromDriverManager) { // DM passes 512 as buffer length to SQLError. // Attempt to set environment attribute after connection handle allocation - ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC2), 0)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(env, nullptr, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(this->env, nullptr, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 40); @@ -384,13 +388,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorConnError) { // DM passes 512 as buffer length to SQLError. // Attempt to set unsupported attribute - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, conn, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, this->conn, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 60); @@ -412,14 +417,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtError) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"1"); - ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - SQLRETURN ret = SQLError(nullptr, conn, stmt, sql_state, &native_error, message, - SQL_MAX_MESSAGE_LENGTH, &message_length); + SQLRETURN ret = SQLError(nullptr, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length); EXPECT_TRUE(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO); @@ -438,9 +443,9 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtWarning) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; @@ -448,14 +453,15 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtWarning) { SQLLEN ind; EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 50); @@ -475,14 +481,14 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) { // DM passes 512 as buffer length to SQLError. // Attempt to set environment attribute after connection handle allocation - ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC2), 0)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(env, nullptr, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(this->env, nullptr, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 40); @@ -515,13 +521,14 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorConnError) { // macOS Excel. // Attempt to set unsupported attribute - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, conn, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, this->conn, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 60); @@ -544,14 +551,15 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtError) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT * from non_existent_table;"); - ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLSMALLINT message_length = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 70); EXPECT_EQ(100, native_error); @@ -568,9 +576,9 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtWarning) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; @@ -578,14 +586,15 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtWarning) { SQLLEN ind; EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 50); 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 cf94c20aa12b..b01b0d71d5e4 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 @@ -78,7 +78,8 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsAllFunctions) { SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, SQL_API_SQLTABLEPRIVILEGES}; - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists)); for (int api : supported_functions) { EXPECT_EQ(SQL_TRUE, SQL_FUNC_EXISTS(api_exists, api)); @@ -114,7 +115,7 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsAllFunctions) { SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, SQL_API_SQLTABLEPRIVILEGES}; - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, SQL_API_ALL_FUNCTIONS, api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, SQL_API_ALL_FUNCTIONS, api_exists)); for (int api : supported_functions) { EXPECT_EQ(SQL_TRUE, api_exists[api]); @@ -149,7 +150,7 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsSupportedSingleAPI) { SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : supported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_TRUE, api_exists); @@ -169,7 +170,7 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsUnsupportedSingleAPI) { SQL_API_SQLTABLEPRIVILEGES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : unsupported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_FALSE, api_exists); @@ -193,7 +194,7 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsSupportedSingleAPI) { SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : supported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_TRUE, api_exists); @@ -211,7 +212,7 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsUnsupportedSingleAPI) { SQL_API_SQLTABLEPRIVILEGES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : unsupported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_FALSE, api_exists); 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 47ef32da997a..f803e135765d 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 @@ -100,6 +100,10 @@ ::testing::Environment* mock_server_env = ::testing::Environment* odbc_test_env = ::testing::AddGlobalTestEnvironment(new OdbcTestEnvironment); +SQLHENV ODBCTestBase::env = SQL_NULL_HENV; +SQLHDBC ODBCTestBase::conn = SQL_NULL_HDBC; +SQLHSTMT ODBCTestBase::stmt = SQL_NULL_HSTMT; + void ODBCTestBase::AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle, SQLINTEGER odbc_ver) { // Allocate an environment handle @@ -262,11 +266,7 @@ void FlightSQLOdbcEnvConnHandleRemoteTestBase::SetUpTestSuite() { return; } - AllocEnvConnHandles(remote_non_connection_handles.env, - remote_non_connection_handles.conn); - env = remote_non_connection_handles.env; - conn = remote_non_connection_handles.conn; - stmt = remote_non_connection_handles.stmt; + AllocEnvConnHandles(env, conn); } void FlightSQLOdbcEnvConnHandleRemoteTestBase::TearDownTestSuite() { @@ -274,8 +274,7 @@ void FlightSQLOdbcEnvConnHandleRemoteTestBase::TearDownTestSuite() { return; } - FreeEnvConnHandles(remote_non_connection_handles.env, - remote_non_connection_handles.conn); + FreeEnvConnHandles(env, conn); } std::string FindTokenInCallHeaders(const CallHeaders& incoming_headers) { @@ -458,14 +457,11 @@ void FlightSQLOdbcV2MockTestBase::SetUpTestSuite() { } void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { - AllocEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn); - env = mock_non_connection_handles.env; - conn = mock_non_connection_handles.conn; - stmt = mock_non_connection_handles.stmt; + AllocEnvConnHandles(env, conn); } void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { - FreeEnvConnHandles(mock_non_connection_handles.env, mock_non_connection_handles.conn); + FreeEnvConnHandles(env, conn); } bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, 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 5271d2171c90..1b9ac212f848 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 @@ -68,16 +68,8 @@ struct OdbcHandles { inline OdbcHandles remote_odbcv3_handles; inline OdbcHandles remote_odbcv2_handles; -inline OdbcHandles remote_non_connection_handles; inline OdbcHandles mock_odbcv3_handles; inline OdbcHandles mock_odbcv2_handles; -inline OdbcHandles mock_non_connection_handles; - -// These handles are meant to point to to the relevant handle above -// depending on the test fixture. -inline SQLHENV env = SQL_NULL_HENV; -inline SQLHDBC conn = SQL_NULL_HDBC; -inline SQLHSTMT stmt = SQL_NULL_HSTMT; inline std::shared_ptr mock_server; inline int mock_server_port = 0; @@ -116,6 +108,10 @@ class ODBCTestBase : public ::testing::Test { protected: void SetUp() override; void TearDown() override; + + static SQLHENV env; + static SQLHDBC conn; + static SQLHSTMT stmt; }; /// \brief Base test fixture for running tests against a remote server. 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 d1d97fc3e115..fc5c5f9d1e64 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 @@ -123,21 +123,21 @@ void ValidateSetStmtAttrErrorCode(SQLHSTMT statement, SQLINTEGER attribute, TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAppParamDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAppRowDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncEnable) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ASYNC_ENABLE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ASYNC_ENABLE, &value); EXPECT_EQ(static_cast(SQL_ASYNC_ENABLE_OFF), value); } @@ -145,188 +145,190 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncEnable) { #ifdef SQL_ATTR_ASYNC_STMT_EVENT TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtEventUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_EVENT, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_EVENT, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_STMT_PCALLBACK TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtPCCallbackUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, + kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_STMT_PCONTEXT TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtPCContextUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, + kErrorStateHYC00); } #endif TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrConcurrency) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CONCURRENCY, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CONCURRENCY, &value); EXPECT_EQ(static_cast(SQL_CONCUR_READ_ONLY), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorScrollable) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_SCROLLABLE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SCROLLABLE, &value); EXPECT_EQ(static_cast(SQL_NONSCROLLABLE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorSensitivity) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_SENSITIVITY, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SENSITIVITY, &value); EXPECT_EQ(static_cast(SQL_UNSPECIFIED), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_TYPE, &value); EXPECT_EQ(static_cast(SQL_CURSOR_FORWARD_ONLY), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrEnableAutoIPD) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ENABLE_AUTO_IPD, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ENABLE_AUTO_IPD, &value); EXPECT_EQ(static_cast(SQL_FALSE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrFetchBookmarkPointer) { SQLLEN value; - GetStmtAttr(stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, &value); EXPECT_EQ(static_cast(NULL), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrIMPParamDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_IMP_PARAM_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_IMP_PARAM_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrIMPRowDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_IMP_ROW_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_IMP_ROW_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrKeysetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_KEYSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_KEYSET_SIZE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMaxLength) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_MAX_LENGTH, &value); + GetStmtAttr(this->stmt, SQL_ATTR_MAX_LENGTH, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMaxRows) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_MAX_ROWS, &value); + GetStmtAttr(this->stmt, SQL_ATTR_MAX_ROWS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMetadataID) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_METADATA_ID, &value); + GetStmtAttr(this->stmt, SQL_ATTR_METADATA_ID, &value); EXPECT_EQ(static_cast(SQL_FALSE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrNoscan) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_NOSCAN, &value); + GetStmtAttr(this->stmt, SQL_ATTR_NOSCAN, &value); EXPECT_EQ(static_cast(SQL_NOSCAN_OFF), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamBindOffsetPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamBindType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_TYPE, &value); EXPECT_EQ(static_cast(SQL_PARAM_BIND_BY_COLUMN), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamOperationPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamStatusPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamsProcessedPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamsetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMSET_SIZE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrQueryTimeout) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, &value); + GetStmtAttr(this->stmt, SQL_ATTR_QUERY_TIMEOUT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRetrieveData) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_RETRIEVE_DATA, &value); + GetStmtAttr(this->stmt, SQL_ATTR_RETRIEVE_DATA, &value); EXPECT_EQ(static_cast(SQL_RD_ON), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowArraySize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindOffsetPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_TYPE, &value); EXPECT_EQ(static_cast(0), value); } @@ -334,47 +336,47 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindType) { TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowNumber) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_NUMBER, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_NUMBER, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowOperationPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowStatusPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowsFetchedPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrSimulateCursor) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_SIMULATE_CURSOR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_SIMULATE_CURSOR, &value); EXPECT_EQ(static_cast(SQL_SC_UNIQUE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrUseBookmarks) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_USE_BOOKMARKS, &value); + GetStmtAttr(this->stmt, SQL_ATTR_USE_BOOKMARKS, &value); EXPECT_EQ(static_cast(SQL_UB_OFF), value); } @@ -382,7 +384,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrUseBookmarks) { // This is a pre ODBC 3 attribute TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowsetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ROWSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ROWSET_SIZE, &value); EXPECT_EQ(static_cast(1), value); } @@ -391,12 +393,12 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAppParamDesc) { SQLULEN app_param_desc = 0; SQLINTEGER string_length_ptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &app_param_desc, 0, - &string_length_ptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, + &app_param_desc, 0, &string_length_ptr)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(0)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(app_param_desc)); } @@ -404,18 +406,19 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAppRowDesc) { SQLULEN app_row_desc = 0; SQLINTEGER string_length_ptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &app_row_desc, 0, - &string_length_ptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &app_row_desc, + 0, &string_length_ptr)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, static_cast(0)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, static_cast(app_row_desc)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, + static_cast(app_row_desc)); } #ifdef SQL_ATTR_ASYNC_ENABLE TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) { // Optional feature not implemented - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF, SQL_ERROR, kErrorStateHYC00); } #endif @@ -423,7 +426,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) { #ifdef SQL_ATTR_ASYNC_STMT_EVENT TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtEventUnsupported) { // Driver does not support asynchronous notification - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR, # ifdef __linux__ kErrorStateHYC00); # else // Windows & Mac @@ -434,7 +437,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtEventUnsupported) #ifdef SQL_ATTR_ASYNC_STMT_PCALLBACK TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCCallbackUnsupported) { - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, 0, SQL_ERROR, kErrorStateHYC00); } #endif @@ -442,43 +445,44 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCCallbackUnsuppor #ifdef SQL_ATTR_ASYNC_STMT_PCONTEXT TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCContextUnsupported) { // Optional feature not implemented - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, 0, SQL_ERROR, kErrorStateHYC00); } #endif TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrConcurrency) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CONCURRENCY, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CONCURRENCY, static_cast(SQL_CONCUR_READ_ONLY)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorScrollable) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_SCROLLABLE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SCROLLABLE, static_cast(SQL_NONSCROLLABLE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorSensitivity) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_SENSITIVITY, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SENSITIVITY, static_cast(SQL_UNSPECIFIED)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_TYPE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_TYPE, static_cast(SQL_CURSOR_FORWARD_ONLY)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrEnableAutoIPD) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ENABLE_AUTO_IPD, static_cast(SQL_FALSE)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ENABLE_AUTO_IPD, + static_cast(SQL_FALSE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrFetchBookmarkPointer) { - ValidateSetStmtAttr(stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, static_cast(NULL)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, static_cast(NULL)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPParamDesc) { // Invalid use of an automatically allocated descriptor handle - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_IMP_PARAM_DESC, static_cast(0), - SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_IMP_PARAM_DESC, + static_cast(0), SQL_ERROR, #ifdef __APPLE__ // static iODBC on MacOS returns IM001 for this case kErrorStateIM001); @@ -489,7 +493,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPParamDesc) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPRowDesc) { // Invalid use of an automatically allocated descriptor handle - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_IMP_ROW_DESC, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_IMP_ROW_DESC, static_cast(0), SQL_ERROR, #ifdef __APPLE__ // static iODBC on MacOS returns IM001 for this case @@ -500,41 +504,41 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPRowDesc) { } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrKeysetSizeUnsupported) { - ValidateSetStmtAttr(stmt, SQL_ATTR_KEYSET_SIZE, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_KEYSET_SIZE, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMaxLength) { - ValidateSetStmtAttr(stmt, SQL_ATTR_MAX_LENGTH, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_MAX_LENGTH, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMaxRows) { // Cannot set read-only attribute - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_MAX_ROWS, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_MAX_ROWS, static_cast(0), SQL_ERROR, kErrorStateHY092); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMetadataID) { - ValidateSetStmtAttr(stmt, SQL_ATTR_METADATA_ID, static_cast(SQL_FALSE)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_METADATA_ID, static_cast(SQL_FALSE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrNoscan) { - ValidateSetStmtAttr(stmt, SQL_ATTR_NOSCAN, static_cast(SQL_NOSCAN_OFF)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_NOSCAN, static_cast(SQL_NOSCAN_OFF)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamBindOffsetPtr) { SQLULEN offset = 1000; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, static_cast(&offset)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(&offset), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamBindType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_TYPE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_TYPE, static_cast(SQL_PARAM_BIND_BY_COLUMN)); } @@ -543,11 +547,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamOperationPtr) { SQLUSMALLINT param_operations[param_set_size] = {SQL_PARAM_PROCEED, SQL_PARAM_IGNORE, SQL_PARAM_PROCEED, SQL_PARAM_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, static_cast(param_operations)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); EXPECT_EQ(static_cast(param_operations), value); } @@ -558,11 +562,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamStatusPtr) { SQLUSMALLINT param_status[param_status_size] = {SQL_PARAM_PROCEED, SQL_PARAM_IGNORE, SQL_PARAM_PROCEED, SQL_PARAM_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, static_cast(param_status)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); EXPECT_EQ(static_cast(param_status), value); } @@ -570,50 +574,51 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamStatusPtr) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamsProcessedPtr) { SQLULEN processed_count = 0; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, static_cast(&processed_count)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); EXPECT_EQ(static_cast(&processed_count), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamsetSize) { - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAMSET_SIZE, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrQueryTimeout) { - ValidateSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_QUERY_TIMEOUT, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRetrieveData) { - ValidateSetStmtAttr(stmt, SQL_ATTR_RETRIEVE_DATA, static_cast(SQL_RD_ON)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_RETRIEVE_DATA, + static_cast(SQL_RD_ON)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowArraySize) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowBindOffsetPtr) { SQLULEN offset = 1000; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, static_cast(&offset)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(&offset), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowBindType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_TYPE, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowNumber) { // Cannot set read-only attribute - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ROW_NUMBER, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ROW_NUMBER, static_cast(0), SQL_ERROR, kErrorStateHY092); } @@ -622,11 +627,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowOperationPtr) { SQLUSMALLINT row_operations[param_set_size] = {SQL_ROW_PROCEED, SQL_ROW_IGNORE, SQL_ROW_PROCEED, SQL_ROW_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, static_cast(row_operations)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); EXPECT_EQ(static_cast(row_operations), value); } @@ -635,10 +640,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowStatusPtr) { constexpr SQLULEN row_status_size = 4; SQLUSMALLINT values[row_status_size] = {0, 0, 0, 0}; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, static_cast(values)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, + static_cast(values)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, &value); EXPECT_EQ(static_cast(values), value); } @@ -646,27 +652,28 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowStatusPtr) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowsFetchedPtr) { SQLULEN rows_fetched = 1; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, static_cast(&rows_fetched)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); EXPECT_EQ(static_cast(&rows_fetched), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrSimulateCursor) { - ValidateSetStmtAttr(stmt, SQL_ATTR_SIMULATE_CURSOR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_SIMULATE_CURSOR, static_cast(SQL_SC_UNIQUE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrUseBookmarks) { - ValidateSetStmtAttr(stmt, SQL_ATTR_USE_BOOKMARKS, static_cast(SQL_UB_OFF)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_USE_BOOKMARKS, + static_cast(SQL_UB_OFF)); } // This is a pre ODBC 3 attribute TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowsetSize) { - ValidateSetStmtAttr(stmt, SQL_ROWSET_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ROWSET_SIZE, static_cast(1)); } } // namespace arrow::flight::sql::odbc 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 9f7c408bef64..3e80bfab110a 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc @@ -40,79 +40,79 @@ TYPED_TEST_SUITE(StatementTest, TestTypes); TYPED_TEST(StatementTest, TestSQLExecDirectSimpleQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned EXPECT_EQ(1, val); - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(1, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLExecDirectInvalidQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT;"); - ASSERT_EQ(SQL_ERROR, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); } TYPED_TEST(StatementTest, TestSQLExecuteSimpleQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLPrepare(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLPrepare(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLExecute(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLExecute(this->stmt)); // Fetch data - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned EXPECT_EQ(1, val); - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(1, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLPrepareInvalidQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT;"); - ASSERT_EQ(SQL_ERROR, SQLPrepare(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_ERROR, SQLPrepare(this->stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); - ASSERT_EQ(SQL_ERROR, SQLExecute(stmt)); + ASSERT_EQ(SQL_ERROR, SQLExecute(this->stmt)); // Verify function sequence error state is returned #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ } @@ -121,9 +121,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types @@ -133,84 +133,88 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), stiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 2, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), stiny_int_val); // Unsigned Tiny Int uint8_t utiny_int_val; buf_len = sizeof(utiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 3, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), utiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 4, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), utiny_int_val); // Signed Small Int int16_t ssmall_int_val; buf_len = sizeof(ssmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 5, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ssmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 6, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ssmall_int_val); // Unsigned Small Int uint16_t usmall_int_val; buf_len = sizeof(usmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 7, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 7, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), usmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 8, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 8, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), usmall_int_val); // Signed Integer SQLINTEGER slong_val; buf_len = sizeof(slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 9, SQL_C_SLONG, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 9, SQL_C_SLONG, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 10, SQL_C_SLONG, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 10, SQL_C_SLONG, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Unsigned Integer SQLUINTEGER ulong_val; buf_len = sizeof(ulong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 11, SQL_C_ULONG, &ulong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 11, SQL_C_ULONG, &ulong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ulong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 12, SQL_C_ULONG, &ulong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 12, SQL_C_ULONG, &ulong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ulong_val); // Signed Big Int SQLBIGINT sbig_int_val; buf_len = sizeof(sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Unsigned Big Int SQLUBIGINT ubig_int_val; buf_len = sizeof(ubig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 15, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ubig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 16, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ubig_int_val); // Decimal @@ -218,7 +222,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { memset(&decimal_val, 0, sizeof(decimal_val)); buf_len = sizeof(SQL_NUMERIC_STRUCT); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 17, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -228,7 +232,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { memset(&decimal_val, 0, sizeof(decimal_val)); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 18, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -239,30 +243,34 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Float float float_val; buf_len = sizeof(float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 19, SQL_C_FLOAT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 19, SQL_C_FLOAT, &float_val, buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 20, SQL_C_FLOAT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 20, SQL_C_FLOAT, &float_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; buf_len = sizeof(double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 21, SQL_C_DOUBLE, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 21, SQL_C_DOUBLE, &double_val, buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 22, SQL_C_DOUBLE, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 22, SQL_C_DOUBLE, &double_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; buf_len = sizeof(bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 23, SQL_C_BIT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 23, SQL_C_BIT, &bit_val, buf_len, &ind)); EXPECT_EQ(false, bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 24, SQL_C_BIT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 24, SQL_C_BIT, &bit_val, buf_len, &ind)); EXPECT_EQ(true, bit_val); // Characters @@ -270,27 +278,31 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Char SQLCHAR char_val[2]; buf_len = sizeof(SQLCHAR) * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); EXPECT_EQ('Z', char_val[0]); // WChar SQLWCHAR wchar_val[2]; size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wchar_val[0]); // WVarchar SQLWCHAR wvarchar_val[3]; buf_len = wchar_size * 3; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wvarchar_val[0]); EXPECT_EQ(L'好', wvarchar_val[1]); // varchar SQLCHAR varchar_val[4]; buf_len = sizeof(SQLCHAR) * 4; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); EXPECT_EQ('X', varchar_val[0]); EXPECT_EQ('Y', varchar_val[1]); EXPECT_EQ('Z', varchar_val[2]); @@ -300,13 +312,15 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Date SQL_DATE_STRUCT date_var{}; buf_len = sizeof(date_var); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 29, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 29, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 30, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 30, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -315,8 +329,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Timestamp SQL_TIMESTAMP_STRUCT timestamp_var{}; buf_len = sizeof(timestamp_var); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); EXPECT_EQ(1, timestamp_var.month); @@ -326,8 +340,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { EXPECT_EQ(0, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); EXPECT_EQ(12, timestamp_var.month); @@ -348,21 +362,23 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectTimeQuery) { CAST(TIME '23:59:59' AS TIME) AS time_max; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQL_TIME_STRUCT time_var{}; SQLLEN buf_len = sizeof(time_var); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); // Check min values for time. EXPECT_EQ(0, time_var.hour); EXPECT_EQ(0, time_var.minute); EXPECT_EQ(0, time_var.second); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 2, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 2, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); // Check max values for time. EXPECT_EQ(23, time_var.hour); EXPECT_EQ(59, time_var.minute); @@ -375,16 +391,16 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEF' AS c_varbinary;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); @@ -399,9 +415,9 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types // Signed Integer @@ -409,10 +425,12 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { SQLLEN buf_len = sizeof(slong_val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 9, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 9, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 10, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 10, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Signed Big Int @@ -420,11 +438,11 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 13, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 14, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Decimal @@ -433,7 +451,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(SQL_NUMERIC_STRUCT); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 17, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -443,7 +461,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { memset(&decimal_val, 0, sizeof(decimal_val)); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 18, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -455,32 +473,38 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { float float_val; buf_len = sizeof(float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 19, SQL_C_DEFAULT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 19, SQL_C_DEFAULT, &float_val, buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 20, SQL_C_DEFAULT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 20, SQL_C_DEFAULT, &float_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; buf_len = sizeof(double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 21, SQL_C_DEFAULT, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 21, SQL_C_DEFAULT, &double_val, buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 22, SQL_C_DEFAULT, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 22, SQL_C_DEFAULT, &double_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; buf_len = sizeof(bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 23, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 23, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); EXPECT_EQ(false, bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 24, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 24, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); EXPECT_EQ(true, bit_val); // Characters @@ -490,13 +514,15 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 25, SQL_C_DEFAULT, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 25, SQL_C_DEFAULT, &wchar_val, buf_len, &ind)); EXPECT_EQ(L'Z', wchar_val[0]); // WChar SQLWCHAR wchar_val2[2]; buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 26, SQL_C_DEFAULT, &wchar_val2, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 26, SQL_C_DEFAULT, &wchar_val2, buf_len, &ind)); EXPECT_EQ(L'你', wchar_val2[0]); // WVarchar @@ -504,7 +530,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = wchar_size * 3; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 27, SQL_C_DEFAULT, &wvarchar_val, buf_len, &ind)); + SQLGetData(this->stmt, 27, SQL_C_DEFAULT, &wvarchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wvarchar_val[0]); EXPECT_EQ(L'好', wvarchar_val[1]); @@ -513,7 +539,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = wchar_size * 4; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 28, SQL_C_DEFAULT, &wvarchar_val2, buf_len, &ind)); + SQLGetData(this->stmt, 28, SQL_C_DEFAULT, &wvarchar_val2, buf_len, &ind)); EXPECT_EQ(L'X', wvarchar_val2[0]); EXPECT_EQ(L'Y', wvarchar_val2[1]); EXPECT_EQ(L'Z', wvarchar_val2[2]); @@ -524,13 +550,15 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { SQL_DATE_STRUCT date_var{}; buf_len = sizeof(date_var); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 29, SQL_C_DEFAULT, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 29, SQL_C_DEFAULT, &date_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 30, SQL_C_DEFAULT, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 30, SQL_C_DEFAULT, &date_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -541,7 +569,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(timestamp_var); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 31, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); + SQLGetData(this->stmt, 31, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); EXPECT_EQ(1, timestamp_var.month); @@ -552,7 +580,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { EXPECT_EQ(0, timestamp_var.fraction); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 32, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); + SQLGetData(this->stmt, 32, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); EXPECT_EQ(12, timestamp_var.month); @@ -573,21 +601,23 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectTimeQueryDefaultType) { CAST(TIME '23:59:59' AS TIME) AS time_max; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQL_TIME_STRUCT time_var{}; SQLLEN buf_len = sizeof(time_var); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &time_var, buf_len, &ind)); // Check min values for time. EXPECT_EQ(0, time_var.hour); EXPECT_EQ(0, time_var.minute); EXPECT_EQ(0, time_var.second); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 2, SQL_C_DEFAULT, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 2, SQL_C_DEFAULT, &time_var, buf_len, &ind)); // Check max values for time. EXPECT_EQ(23, time_var.hour); EXPECT_EQ(59, time_var.minute); @@ -601,16 +631,16 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectVarbinaryQueryDefaultType) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT from_hex('ABCDEF') AS c_varbinary;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_DEFAULT, &varbinary_val[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &varbinary_val[0], buf_len, &ind)); EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); @@ -621,15 +651,16 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { // Verify that SQLGetData uses IRD precision/scale as defaults when ARD values are unset ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Get precision and scale from IRD SQLLEN ird_precision = 0; SQLLEN ird_scale = 0; SQLHDESC ird = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_IMP_ROW_DESC, &ird, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_IMP_ROW_DESC, &ird, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLGetDescField(ird, 1, SQL_DESC_PRECISION, &ird_precision, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLGetDescField(ird, 1, SQL_DESC_SCALE, &ird_scale, 0, nullptr)); @@ -638,7 +669,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { SQL_NUMERIC_STRUCT numeric_val; memset(&numeric_val, 0, sizeof(numeric_val)); SQLLEN indicator; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_NUMERIC, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_NUMERIC, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(static_cast(ird_precision), numeric_val.precision); EXPECT_EQ(static_cast(ird_scale), numeric_val.scale); @@ -646,14 +677,15 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { // Test with SQL_C_DEFAULT when ARD is unset (0) - should fall back to IRD // precision/scale SQLHDESC ard = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLSetDescField(ard, 1, SQL_DESC_PRECISION, reinterpret_cast(0), 0)); ASSERT_EQ(SQL_SUCCESS, SQLSetDescField(ard, 1, SQL_DESC_SCALE, reinterpret_cast(0), 0)); memset(&numeric_val, 0, sizeof(numeric_val)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(static_cast(ird_precision), numeric_val.precision); EXPECT_EQ(static_cast(ird_scale), numeric_val.scale); @@ -665,12 +697,13 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { // SQL_C_DEFAULT ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT CAST('123.45' AS NUMERIC) as decimal_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLHDESC ard = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); // Test with SQL_ARD_TYPE SQLSMALLINT ard_precision = 15; @@ -685,7 +718,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { SQL_NUMERIC_STRUCT numeric_val; memset(&numeric_val, 0, sizeof(numeric_val)); SQLLEN indicator; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_ARD_TYPE, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_ARD_TYPE, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(ard_precision, numeric_val.precision); EXPECT_EQ(ard_scale, numeric_val.scale); @@ -699,7 +732,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { reinterpret_cast(ard_scale), 0)); memset(&numeric_val, 0, sizeof(numeric_val)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(ard_precision, numeric_val.precision); EXPECT_EQ(ard_scale, numeric_val.scale); @@ -710,16 +743,16 @@ TYPED_TEST(StatementTest, TestSQLExecDirectGuidQueryUnsupported) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'C77313CF-4E08-47CE-B6DF-94DD2FCF3541' AS guid;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLGUID guid_var; SQLLEN buf_len = sizeof(guid_var); SQLLEN ind; - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_GUID, &guid_var, buf_len, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_GUID, &guid_var, buf_len, &ind)); // GUID is not supported by ODBC - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); } TYPED_TEST(StatementTest, TestSQLExecDirectRowFetching) { @@ -732,53 +765,53 @@ TYPED_TEST(StatementTest, TestSQLExecDirectRowFetching) { SELECT 3; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; SQLLEN buf_len = sizeof(val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 1 is returned EXPECT_EQ(1, val); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 2 is returned EXPECT_EQ(2, val); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 3 is returned EXPECT_EQ(3, val); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(3, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { SQLLEN rows_fetched; - SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0); + SQLSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, LR"( @@ -789,25 +822,25 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { SELECT 3; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); SQLINTEGER val; SQLLEN buf_len = sizeof(val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 1 is returned EXPECT_EQ(1, val); // Verify 1 row is fetched EXPECT_EQ(1, rows_fetched); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 2 is returned EXPECT_EQ(2, val); @@ -815,9 +848,9 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { EXPECT_EQ(1, rows_fetched); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 3 is returned EXPECT_EQ(3, val); @@ -825,16 +858,16 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { EXPECT_EQ(1, rows_fetched); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_NO_DATA, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(3, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } @@ -843,54 +876,54 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollUnsupportedOrientation) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_PRIOR, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_PRIOR, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); SQLLEN fetch_offset = 1; - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_RELATIVE, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_RELATIVE, fetch_offset)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_ABSOLUTE, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_ABSOLUTE, fetch_offset)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_FIRST, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_FIRST, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_LAST, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_LAST, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_BOOKMARK, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_BOOKMARK, fetch_offset)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); #else // Windows DM returns state HY106 for SQL_FETCH_BOOKMARK - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY106); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY106); #endif // __APPLE__ } TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 'VERY LONG STRING here' AS string_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; SQLLEN buf_len = sizeof(SQLCHAR) * len; SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); EXPECT_EQ(std::string("VERY LONG STRING"), ODBC::SqlStringToString(char_val)); EXPECT_EQ(21, ind); @@ -900,9 +933,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { SQLCHAR char_val2[len2]; buf_len = sizeof(SQLCHAR) * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val2, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val2, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); EXPECT_EQ(std::string(" "), ODBC::SqlStringToString(char_val2)); EXPECT_EQ(5, ind); @@ -913,7 +946,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { buf_len = sizeof(SQLCHAR) * len3; // Verify that there is no more truncation reports. The full string has been fetched. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_CHAR, &char_val3, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val3, buf_len, &ind)); EXPECT_EQ(std::string("here"), ODBC::SqlStringToString(char_val3)); EXPECT_EQ(4, ind); @@ -921,16 +955,16 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { // Attempt to fetch data 4th time SQLCHAR char_val4[len]; // Verify SQL_NO_DATA is returned - ASSERT_EQ(SQL_NO_DATA, SQLGetData(stmt, 1, SQL_C_CHAR, &char_val4, 0, &ind)); + ASSERT_EQ(SQL_NO_DATA, SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val4, 0, &ind)); } TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { ASSIGN_SQLWCHAR_ARR_AND_LEN( wsql, L"SELECT 'VERY LONG Unicode STRING 句子 here' AS wstring_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 28; SQLWCHAR wchar_val[len]; @@ -938,9 +972,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { SQLLEN buf_len = wchar_size * len; SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); std::wstring wchar_result = ConvertToWString(wchar_val); EXPECT_EQ(std::wstring(L"VERY LONG Unicode STRING 句子"), wchar_result); @@ -951,9 +985,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { SQLWCHAR wchar_val2[len2]; buf_len = wchar_size * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val2, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val2, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); wchar_result = ConvertToWString(wchar_val2); EXPECT_EQ(std::wstring(L" "), wchar_result); @@ -965,7 +999,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { buf_len = wchar_size * len3; // Verify that there is no more truncation reports. The full string has been fetched. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val3, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val3, buf_len, &ind)); wchar_result = ConvertToWString(wchar_val3); EXPECT_EQ(std::wstring(L"here"), wchar_result); @@ -974,7 +1009,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { // Attempt to fetch data 4th time SQLWCHAR wchar_val4[len]; // Verify SQL_NO_DATA is returned - ASSERT_EQ(SQL_NO_DATA, SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val4, 0, &ind)); + ASSERT_EQ(SQL_NO_DATA, SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val4, 0, &ind)); } TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { @@ -983,18 +1018,18 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEFAB' AS c_varbinary;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); // Verify binary truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); @@ -1006,7 +1041,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { // Verify that there is no more truncation reports. The full binary has been fetched. ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val2[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val2[0], buf_len, &ind)); EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(1, ind); @@ -1016,7 +1051,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { buf_len = varbinary_val3.size(); // Verify SQL_NO_DATA is returned ASSERT_EQ(SQL_NO_DATA, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val3[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val3[0], buf_len, &ind)); } TYPED_TEST(StatementTest, DISABLED_TestSQLExecDirectFloatTruncation) { @@ -1031,16 +1066,16 @@ TYPED_TEST(StatementTest, DISABLED_TestSQLExecDirectFloatTruncation) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); int16_t ssmall_int_val; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_SSHORT, &ssmall_int_val, 0, nullptr)); + SQLGetData(this->stmt, 1, SQL_C_SSHORT, &ssmall_int_val, 0, nullptr)); // Verify float truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01S07); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01S07); EXPECT_EQ(1, ssmall_int_val); } @@ -1051,14 +1086,14 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectNullQuery) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Verify SQL_NULL_DATA is returned for indicator EXPECT_EQ(SQL_NULL_DATA, ind); @@ -1077,12 +1112,12 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { X'ABCDEFAB' AS c_varbinary; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned for non-truncation case. EXPECT_EQ(1, val); @@ -1091,9 +1126,9 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { SQLCHAR char_val[len]; SQLLEN buf_len = sizeof(SQLCHAR) * len; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 2, SQL_C_CHAR, &char_val, buf_len, nullptr)); + SQLGetData(this->stmt, 2, SQL_C_CHAR, &char_val, buf_len, nullptr)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); // WChar const int len2 = 28; @@ -1101,17 +1136,17 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 3, SQL_C_WCHAR, &wchar_val, buf_len, nullptr)); + SQLGetData(this->stmt, 3, SQL_C_WCHAR, &wchar_val, buf_len, nullptr)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); // varbinary std::vector varbinary_val(3); buf_len = varbinary_val.size(); ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 4, SQL_C_BINARY, &varbinary_val[0], buf_len, nullptr)); + SQLGetData(this->stmt, 4, SQL_C_BINARY, &varbinary_val[0], buf_len, nullptr)); // Verify binary truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); } TEST_F(StatementRemoteTest, TestSQLExecDirectNullQueryNullIndicator) { @@ -1120,15 +1155,15 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectNullQueryNullIndicator) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify invalid null indicator is reported, as it is required - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } // The MacOS and Linux Driver Managers return SQL_ERROR when invalid buffer length is @@ -1141,9 +1176,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types @@ -1152,91 +1187,91 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { SQLLEN invalid_buf_len = -1; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_STINYINT, &stiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), stiny_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 2, SQL_C_STINYINT, &stiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), stiny_int_val); // Unsigned Tiny Int uint8_t utiny_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 3, SQL_C_UTINYINT, &utiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), utiny_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 4, SQL_C_UTINYINT, &utiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), utiny_int_val); // Signed Small Int int16_t ssmall_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 5, SQL_C_SSHORT, &ssmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ssmall_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 6, SQL_C_SSHORT, &ssmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ssmall_int_val); // Unsigned Small Int uint16_t usmall_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 7, SQL_C_USHORT, &usmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 7, SQL_C_USHORT, &usmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), usmall_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 8, SQL_C_USHORT, &usmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 8, SQL_C_USHORT, &usmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), usmall_int_val); // Signed Integer SQLINTEGER slong_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 9, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 9, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 10, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 10, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Unsigned Integer SQLUINTEGER ulong_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 11, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 11, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ulong_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 12, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 12, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ulong_val); // Signed Big Int SQLBIGINT sbig_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_SBIGINT, &sbig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_SBIGINT, &sbig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Unsigned Big Int SQLUBIGINT ubig_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 15, SQL_C_UBIGINT, &ubig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ubig_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 16, SQL_C_UBIGINT, &ubig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ubig_int_val); // Decimal SQL_NUMERIC_STRUCT decimal_val; memset(&decimal_val, 0, sizeof(decimal_val)); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_NUMERIC, &decimal_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 17, SQL_C_NUMERIC, &decimal_val, + invalid_buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -1246,8 +1281,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { memset(&decimal_val, 0, sizeof(decimal_val)); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_NUMERIC, &decimal_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 18, SQL_C_NUMERIC, &decimal_val, + invalid_buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -1259,48 +1294,48 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { float float_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 19, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 19, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 20, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 20, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 21, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 21, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 22, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 22, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 23, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 23, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); EXPECT_EQ(false, bit_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 24, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 24, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); EXPECT_EQ(true, bit_val); // Date and Timestamp // Date SQL_DATE_STRUCT date_var{}; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 29, SQL_C_TYPE_DATE, &date_var, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 29, SQL_C_TYPE_DATE, &date_var, + invalid_buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 30, SQL_C_TYPE_DATE, &date_var, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 30, SQL_C_TYPE_DATE, &date_var, + invalid_buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -1309,7 +1344,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { // Timestamp SQL_TIMESTAMP_STRUCT timestamp_var{}; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, invalid_buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); @@ -1320,7 +1355,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { EXPECT_EQ(0, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, invalid_buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); @@ -1343,79 +1378,80 @@ TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_STINYINT, &stiny_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 2, SQL_C_STINYINT, &stiny_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val_max, buf_len, &ind)); // Unsigned Tiny Int uint8_t utiny_int_val_min; uint8_t utiny_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 3, SQL_C_UTINYINT, &utiny_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 4, SQL_C_UTINYINT, &utiny_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val_max, buf_len, &ind)); // Signed Small Int int16_t ssmall_int_val_min; int16_t ssmall_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 5, SQL_C_SSHORT, &ssmall_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 6, SQL_C_SSHORT, &ssmall_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val_max, buf_len, &ind)); // Unsigned Small Int uint16_t usmall_int_val_min; uint16_t usmall_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 7, SQL_C_USHORT, &usmall_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 7, SQL_C_USHORT, &usmall_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 8, SQL_C_USHORT, &usmall_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 8, SQL_C_USHORT, &usmall_int_val_max, buf_len, &ind)); // Signed Integer SQLINTEGER slong_val_min; SQLINTEGER slong_val_max; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 9, SQL_C_SLONG, &slong_val_min, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 9, SQL_C_SLONG, &slong_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 10, SQL_C_SLONG, &slong_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 10, SQL_C_SLONG, &slong_val_max, buf_len, &ind)); // Unsigned Integer SQLUINTEGER ulong_val_min; SQLUINTEGER ulong_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 11, SQL_C_ULONG, &ulong_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 11, SQL_C_ULONG, &ulong_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 12, SQL_C_ULONG, &ulong_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 12, SQL_C_ULONG, &ulong_val_max, buf_len, &ind)); // Signed Big Int SQLBIGINT sbig_int_val_min; SQLBIGINT sbig_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 13, SQL_C_SBIGINT, &sbig_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 14, SQL_C_SBIGINT, &sbig_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val_max, buf_len, &ind)); // Unsigned Big Int SQLUBIGINT ubig_int_val_min; SQLUBIGINT ubig_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 15, SQL_C_UBIGINT, &ubig_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 16, SQL_C_UBIGINT, &ubig_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val_max, buf_len, &ind)); // Decimal SQL_NUMERIC_STRUCT decimal_val_neg; @@ -1424,87 +1460,93 @@ TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { memset(&decimal_val_pos, 0, sizeof(decimal_val_pos)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 17, SQL_C_NUMERIC, &decimal_val_neg, buf_len, &ind)); + SQLBindCol(this->stmt, 17, SQL_C_NUMERIC, &decimal_val_neg, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 18, SQL_C_NUMERIC, &decimal_val_pos, buf_len, &ind)); + SQLBindCol(this->stmt, 18, SQL_C_NUMERIC, &decimal_val_pos, buf_len, &ind)); // Float float float_val_min; float float_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 19, SQL_C_FLOAT, &float_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 19, SQL_C_FLOAT, &float_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 20, SQL_C_FLOAT, &float_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 20, SQL_C_FLOAT, &float_val_max, buf_len, &ind)); // Double SQLDOUBLE double_val_min; SQLDOUBLE double_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 21, SQL_C_DOUBLE, &double_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 21, SQL_C_DOUBLE, &double_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 22, SQL_C_DOUBLE, &double_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 22, SQL_C_DOUBLE, &double_val_max, buf_len, &ind)); // Bit bool bit_val_false; bool bit_val_true; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 23, SQL_C_BIT, &bit_val_false, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 23, SQL_C_BIT, &bit_val_false, buf_len, &ind)); - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 24, SQL_C_BIT, &bit_val_true, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 24, SQL_C_BIT, &bit_val_true, buf_len, &ind)); // Characters SQLCHAR char_val[2]; buf_len = sizeof(SQLCHAR) * 2; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR wchar_val[2]; size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); SQLWCHAR wvarchar_val[3]; buf_len = wchar_size * 3; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); SQLCHAR varchar_val[4]; buf_len = sizeof(SQLCHAR) * 4; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); // Date and Timestamp SQL_DATE_STRUCT date_val_min{}, date_val_max{}; buf_len = 0; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 29, SQL_C_TYPE_DATE, &date_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 29, SQL_C_TYPE_DATE, &date_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 30, SQL_C_TYPE_DATE, &date_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 30, SQL_C_TYPE_DATE, &date_val_max, buf_len, &ind)); SQL_TIMESTAMP_STRUCT timestamp_val_min{}, timestamp_val_max{}; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_val_min, - buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, + ×tamp_val_min, buf_len, &ind)); - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_val_max, - buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, + ×tamp_val_max, buf_len, &ind)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Data verification @@ -1612,10 +1654,10 @@ TEST_F(StatementRemoteTest, TestSQLBindColTimeQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_TYPE_TIME, &time_var_min, buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_TYPE_TIME, &time_var_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 2, SQL_C_TYPE_TIME, &time_var_max, buf_len, &ind)); + SQLBindCol(this->stmt, 2, SQL_C_TYPE_TIME, &time_var_max, buf_len, &ind)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, LR"( @@ -1623,9 +1665,9 @@ TEST_F(StatementRemoteTest, TestSQLBindColTimeQuery) { CAST(TIME '23:59:59' AS TIME) AS time_max; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Check min values for time. EXPECT_EQ(0, time_var_min.hour); @@ -1647,13 +1689,13 @@ TEST_F(StatementMockTest, TestSQLBindColVarbinaryQuery) { SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT X'ABCDEF' AS c_varbinary;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Check varbinary values EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); @@ -1668,13 +1710,13 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQuery) { SQLINTEGER val; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify SQL_NULL_DATA is returned for indicator EXPECT_EQ(SQL_NULL_DATA, ind); @@ -1686,15 +1728,15 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQueryNullIndicator) { SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, 0)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_ERROR, SQLFetch(stmt)); + ASSERT_EQ(SQL_ERROR, SQLFetch(this->stmt)); // Verify invalid null indicator is reported, as it is required - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { @@ -1704,7 +1746,7 @@ TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, LR"( @@ -1715,28 +1757,28 @@ TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { SELECT 3; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 1 is returned EXPECT_EQ(1, val); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 2 is returned EXPECT_EQ(2, val); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 3 is returned EXPECT_EQ(3, val); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { @@ -1749,11 +1791,11 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, val, buf_len, ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, val, buf_len, ind)); SQLLEN rows_fetched; ASSERT_EQ(SQL_SUCCESS, - SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0)); + SQLSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, LR"( @@ -1764,13 +1806,13 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { SELECT 3; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, + ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, reinterpret_cast(rows), 0)); // Fetch 3 rows at once - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 3 rows are fetched EXPECT_EQ(3, rows_fetched); @@ -1783,7 +1825,7 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { EXPECT_EQ(3, val[2]); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(StatementTest, DISABLED_TestSQLBindColIndicatorOnly) { @@ -1795,21 +1837,22 @@ TYPED_TEST(StatementTest, DISABLED_TestSQLBindColIndicatorOnly) { // Signed Tiny Int SQLLEN stiny_int_ind; - EXPECT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_STINYINT, 0, 0, &stiny_int_ind)); + EXPECT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_STINYINT, 0, 0, &stiny_int_ind)); // Characters SQLLEN buf_len = sizeof(SQLCHAR) * 2; SQLLEN char_val_ind; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 25, SQL_C_CHAR, 0, buf_len, &char_val_ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 25, SQL_C_CHAR, 0, buf_len, &char_val_ind)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify values for indicator pointer // Signed Tiny Int @@ -1828,26 +1871,26 @@ TYPED_TEST(StatementTest, TestSQLBindColIndicatorOnlySQLUnbind) { int8_t stiny_int_val; SQLLEN stiny_int_ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_STINYINT, &stiny_int_val, 0, &stiny_int_ind)); + SQLBindCol(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, 0, &stiny_int_ind)); // Characters SQLCHAR char_val[2]; SQLLEN buf_len = sizeof(SQLCHAR) * 2; SQLLEN char_val_ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &char_val_ind)); + SQLBindCol(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &char_val_ind)); // Driver should still be able to execute queries after unbinding columns - EXPECT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_UNBIND)); + EXPECT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_UNBIND)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // GH-47021 TODO: implement driver to return indicator value when data pointer is null // and uncomment the checks Verify values for indicator pointer Signed Tiny Int @@ -1867,10 +1910,10 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, val, buf_len, ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, val, buf_len, ind)); - ASSERT_EQ(SQL_SUCCESS, - SQLSetStmtAttr(stmt, SQL_ROWSET_SIZE, reinterpret_cast(rows), 0)); + ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ROWSET_SIZE, + reinterpret_cast(rows), 0)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, LR"( @@ -1881,14 +1924,14 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { SELECT 3; )"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1-3. SQLULEN row_count; SQLUSMALLINT row_status[rows]; ASSERT_EQ(SQL_SUCCESS, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count, row_status)); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count, row_status)); EXPECT_EQ(3, row_count); for (SQLULEN i = 0; i < rows; i++) { @@ -1906,7 +1949,7 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { SQLULEN row_count2; SQLUSMALLINT row_status2[rows]; EXPECT_EQ(SQL_NO_DATA, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count2, row_status2)); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count2, row_status2)); } TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { @@ -1915,19 +1958,19 @@ TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { // server instead. Mock server has type `DENSE_UNION` for null column data. SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT null as null_col;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLULEN row_count1; SQLUSMALLINT row_status1[1]; // SQLExtendedFetch should return SQL_SUCCESS_WITH_INFO for 22002 state ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count1, row_status1)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count1, row_status1)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) { @@ -1935,20 +1978,20 @@ TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(this->stmt)); } TYPED_TEST(StatementTest, TestSQLMoreResultsInvalidFunctionSequence) { // Verify function sequence error state is reported when SQLMoreResults is called // without executing any queries #ifdef __linux__ - ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(stmt)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState00000); + ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(this->stmt)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState00000); #else // Windows & Mac - ASSERT_EQ(SQL_ERROR, SQLMoreResults(stmt)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + ASSERT_EQ(SQL_ERROR, SQLMoreResults(this->stmt)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif } @@ -1958,8 +2001,8 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputString) { ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(conn, input_str, input_str_len, buf, buf_char_len, - &output_char_len)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->conn, input_str, input_str_len, buf, + buf_char_len, &output_char_len)); EXPECT_EQ(input_str_len, output_char_len); @@ -1976,8 +2019,8 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsNTSInputString) { ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - ASSERT_EQ(SQL_SUCCESS, - SQLNativeSql(conn, input_str, SQL_NTS, buf, buf_char_len, &output_char_len)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->conn, input_str, SQL_NTS, buf, buf_char_len, + &output_char_len)); EXPECT_EQ(input_str_len, output_char_len); @@ -1992,13 +2035,13 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsInputStringLength) { ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - ASSERT_EQ(SQL_SUCCESS, - SQLNativeSql(conn, input_str, input_str_len, nullptr, 0, &output_char_len)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->conn, input_str, input_str_len, nullptr, 0, + &output_char_len)); EXPECT_EQ(input_str_len, output_char_len); ASSERT_EQ(SQL_SUCCESS, - SQLNativeSql(conn, input_str, SQL_NTS, nullptr, 0, &output_char_len)); + SQLNativeSql(this->conn, input_str, SQL_NTS, nullptr, 0, &output_char_len)); EXPECT_EQ(input_str_len, output_char_len); } @@ -2017,9 +2060,10 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsTruncatedString) { std::wstring expected_string(expected_string_buf, expected_string_buf + small_buf_size_in_char); - ASSERT_EQ(SQL_SUCCESS_WITH_INFO, SQLNativeSql(conn, input_str, input_str_len, small_buf, - small_buf_char_len, &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01004); + ASSERT_EQ(SQL_SUCCESS_WITH_INFO, + SQLNativeSql(this->conn, input_str, input_str_len, small_buf, + small_buf_char_len, &output_char_len)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01004); // Returned text length represents full string char length regardless of truncation EXPECT_EQ(input_str_len, output_char_len); @@ -2035,20 +2079,20 @@ TYPED_TEST(StatementTest, TestSQLNativeSqlReturnsErrorOnBadInputs) { ASSIGN_SQLWCHAR_ARR_AND_LEN(input_str, L"SELECT * FROM mytable WHERE id == 1"); SQLINTEGER output_char_len = 0; - ASSERT_EQ(SQL_ERROR, SQLNativeSql(conn, nullptr, input_str_len, buf, buf_char_len, + ASSERT_EQ(SQL_ERROR, SQLNativeSql(this->conn, nullptr, input_str_len, buf, buf_char_len, &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY009); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY009); - ASSERT_EQ(SQL_ERROR, - SQLNativeSql(conn, nullptr, SQL_NTS, buf, buf_char_len, &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY009); + ASSERT_EQ(SQL_ERROR, SQLNativeSql(this->conn, nullptr, SQL_NTS, buf, buf_char_len, + &output_char_len)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY009); - ASSERT_EQ(SQL_ERROR, - SQLNativeSql(conn, input_str, -100, buf, buf_char_len, &output_char_len)); + ASSERT_EQ(SQL_ERROR, SQLNativeSql(this->conn, input_str, -100, buf, buf_char_len, + &output_char_len)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateS1090); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateS1090); #else - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY090); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY090); #endif // __APPLE__ } @@ -2057,15 +2101,15 @@ TYPED_TEST(StatementTest, SQLNumResultColsReturnsColumnsOnSelect) { SQLSMALLINT expected_value = 3; ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(this->stmt, &column_count)); EXPECT_EQ(expected_value, column_count); } @@ -2073,33 +2117,33 @@ TYPED_TEST(StatementTest, SQLNumResultColsReturnsColumnsOnSelect) { TYPED_TEST(StatementTest, SQLNumResultColsReturnsSuccessOnNullptr) { ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(stmt, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(this->stmt, nullptr)); } TYPED_TEST(StatementTest, SQLNumResultColsFunctionSequenceErrorOnNoQuery) { SQLSMALLINT column_count = 0; SQLSMALLINT expected_value = 0; - ASSERT_EQ(SQL_ERROR, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_ERROR, SQLNumResultCols(this->stmt, &column_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ - ASSERT_EQ(SQL_ERROR, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_ERROR, SQLNumResultCols(this->stmt, &column_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ ASSERT_EQ(expected_value, column_count); @@ -2110,15 +2154,15 @@ TYPED_TEST(StatementTest, SQLRowCountReturnsNegativeOneOnSelect) { SQLLEN expected_value = -1; ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLRowCount(stmt, &row_count)); + ASSERT_EQ(SQL_SUCCESS, SQLRowCount(this->stmt, &row_count)); EXPECT_EQ(expected_value, row_count); } @@ -2126,15 +2170,15 @@ TYPED_TEST(StatementTest, SQLRowCountReturnsNegativeOneOnSelect) { TYPED_TEST(StatementTest, SQLRowCountReturnsSuccessOnNullptr) { ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT 1 AS col1, 'One' AS col2, 3 AS col3"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, sql_query_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLRowCount(stmt, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLRowCount(this->stmt, nullptr)); } TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { @@ -2145,11 +2189,11 @@ TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { SQLLEN expected_value = 0; #endif - ASSERT_EQ(SQL_ERROR, SQLRowCount(stmt, &row_count)); + ASSERT_EQ(SQL_ERROR, SQLRowCount(this->stmt, &row_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ EXPECT_EQ(expected_value, row_count); @@ -2158,30 +2202,30 @@ TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { TYPED_TEST(StatementTest, TestSQLFreeStmtSQLClose) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_CLOSE)); + ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_CLOSE)); } TYPED_TEST(StatementTest, TestSQLCloseCursor) { ASSIGN_SQLWCHAR_ARR_AND_LEN(wsql, L"SELECT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, wsql, wsql_len)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLCloseCursor(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLCloseCursor(this->stmt)); } TYPED_TEST(StatementTest, TestSQLFreeStmtSQLCloseWithoutCursor) { // Verify SQLFreeStmt(SQL_CLOSE) does not throw error with invalid cursor - ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_CLOSE)); + ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_CLOSE)); } TYPED_TEST(StatementTest, TestSQLCloseCursorWithoutCursor) { - ASSERT_EQ(SQL_ERROR, SQLCloseCursor(stmt)); + ASSERT_EQ(SQL_ERROR, SQLCloseCursor(this->stmt)); // Verify invalid cursor error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); } } // namespace arrow::flight::sql::odbc 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 ca3972a91d04..8d253ab3bcf2 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -50,31 +50,32 @@ TYPED_TEST(TablesTest, SQLTablesTestInputData) { SQLWCHAR table_type[] = {0}; // All values populated - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, sizeof(catalog_name), schema_name, - sizeof(schema_name), table_name, sizeof(table_name), - table_type, sizeof(table_type))); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, sizeof(catalog_name), + schema_name, sizeof(schema_name), table_name, + sizeof(table_name), table_type, sizeof(table_type))); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, 0, schema_name, 0, table_name, 0, - table_type, 0)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, 0, schema_name, 0, + table_name, 0, table_type, 0)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Names are nulls - EXPECT_EQ(SQL_SUCCESS, - SQLTables(stmt, nullptr, sizeof(catalog_name), nullptr, sizeof(schema_name), - nullptr, sizeof(table_name), nullptr, sizeof(table_type))); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, sizeof(catalog_name), nullptr, + sizeof(schema_name), nullptr, sizeof(table_name), + nullptr, sizeof(table_type))); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); // Close statement cursor to avoid leaving in an invalid state - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Names are nulls and sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); } // GH-49702: TODO Disabled on Linux due to BlockingQueue issue @@ -85,18 +86,18 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllCatalogs) { std::wstring expected_catalog_name = std::wstring(L"main"); // Get Catalog metadata - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, SQL_ALL_CATALOGS_W, SQL_NTS, empty, SQL_NTS, - empty, SQL_NTS, empty, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, SQL_ALL_CATALOGS_W, SQL_NTS, empty, + SQL_NTS, empty, SQL_NTS, empty, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckNullColumnW(stmt, 4); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckNullColumnW(this->stmt, 4); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } #endif // __linux__ @@ -111,21 +112,21 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForNamedCatalog) { // Get named Catalog metadata - Mock server returns the system table sqlite_sequence as // type "table" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -134,10 +135,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetSchemaHasNoData) { ASSIGN_SQLWCHAR_ARR(SQL_ALL_SCHEMAS_W, L"%"); // Validate that no schema data is available for Mock server - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, - nullptr, SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, + SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } // GH-49702: TODO Disabled on Linux due to BlockingQueue issue @@ -151,19 +152,19 @@ TEST_F(TablesRemoteTest, SQLTablesTestGetMetadataForAllSchemas) { // Return is unordered and contains user specific schemas, so collect schema names for // comparison with a known list - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS)); while (true) { - SQLRETURN ret = SQLFetch(stmt); + SQLRETURN ret = SQLFetch(this->stmt); if (ret == SQL_NO_DATA) break; ASSERT_EQ(SQL_SUCCESS, ret); - CheckNullColumnW(stmt, 1); - std::wstring schema = GetStringColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckNullColumnW(stmt, 4); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + std::wstring schema = GetStringColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckNullColumnW(this->stmt, 4); + CheckNullColumnW(this->stmt, 5); // Skip user-specific schemas like "@UserName" if (!schema.empty() && schema[0] != L'@') { @@ -212,11 +213,11 @@ TEST_F(TablesRemoteTest, SQLTablesTestFilterByAllSchema) { std::wstring expected_system_table_type = std::wstring(L"SYSTEM_TABLE"); std::wstring expected_user_table_type = std::wstring(L"TABLE"); - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, - nullptr, SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, + SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(schema_names) / sizeof(*schema_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); const std::wstring& expected_table_type = (std::wstring(schema_names[i]).rfind(L"sys", 0) == 0 || @@ -224,14 +225,14 @@ TEST_F(TablesRemoteTest, SQLTablesTestFilterByAllSchema) { ? expected_system_table_type : expected_user_table_type; - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, schema_names[i]); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, schema_names[i]); // Ignore table name - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { @@ -241,18 +242,18 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { std::wstring expected_table_name = std::wstring(L"ODBCTest"); std::wstring expected_table_type = std::wstring(L"TABLE"); - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, schema_name, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, schema_name, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, expected_schema_name); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, expected_schema_name); // Ignore table name - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { @@ -266,21 +267,21 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { // Get all Table metadata - Mock server returns the system table sqlite_sequence as type // "table" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, SQL_ALL_TABLES_W, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -300,22 +301,22 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { // Get specific Table metadata - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_names[i], SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); + CheckNullColumnW(this->stmt, 2); std::wstring table_name = ConvertToWString(table_names[i]); - CheckStringColumnW(stmt, 3, table_name); + CheckStringColumnW(this->stmt, 3, table_name); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } DropTestTable(); @@ -330,19 +331,19 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForUnicodeTableByTableName) { std::wstring expected_table_type = std::wstring(L"table"); // Get specific Table metadata - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, unicodetable_name, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, expected_table_name); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, expected_table_name); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropUnicodeTable(); } @@ -354,10 +355,10 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForInvalidTableNameNoData) { ASSIGN_SQLWCHAR_ARR(invalid_table_name, L"NonExistenttable_name"); // Try to get metadata for a non-existent table name - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, invalid_table_name, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -376,37 +377,39 @@ TEST_F(TablesMockTest, SQLTablesGetMetadataForTableType) { std::wstring expected_table_name = std::wstring(L"TestTable"); std::wstring expected_table_type = std::wstring(L"table"); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_table_uppercase, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS, + table_type_table_uppercase, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, table_type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_table_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, table_type_table_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Returns user table as well as system tables, even though only type table requested - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_table_lowercase, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS, + table_type_table_lowercase, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -427,18 +430,18 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { std::wstring expected_table_type = std::wstring(L"TABLE"); for (size_t i = 0; i < sizeof(type_list) / sizeof(*type_list); ++i) { - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, type_list[i], SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, type_list[i], SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, expected_schema_name); - CheckStringColumnW(stmt, 3, expected_table_name); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, expected_schema_name); + CheckStringColumnW(this->stmt, 3, expected_table_name); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } } #endif // __linux__ @@ -447,15 +450,15 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeViewHasNoData) { SQLWCHAR empty[] = {0}; ASSIGN_SQLWCHAR_ARR(type_view, L"VIEW"); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, empty, + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, empty, SQL_NTS, type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, type_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } // GH-49702: TODO Disabled on Linux due to BlockingQueue issue @@ -466,18 +469,18 @@ TEST_F(TablesMockTest, SQLTablesGetSupportedTableTypes) { std::wstring expected_table_type = std::wstring(L"table"); // Mock server returns lower case for supported type of "table" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS, - SQL_ALL_TABLE_TYPES_W, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, empty, SQL_NTS, empty, + SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { @@ -485,20 +488,20 @@ TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { ASSIGN_SQLWCHAR_ARR(SQL_ALL_TABLE_TYPES_W, L"%"); const std::wstring type_lists[] = {L"TABLE", L"SYSTEM_TABLE", L"VIEW"}; - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS, - SQL_ALL_TABLE_TYPES_W, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, empty, SQL_NTS, empty, + SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); for (size_t i = 0; i < sizeof(type_lists) / sizeof(*type_lists); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckStringColumnW(stmt, 4, type_lists[i]); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckStringColumnW(this->stmt, 4, type_lists[i]); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } #endif // __linux__ @@ -519,15 +522,15 @@ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); @@ -563,15 +566,15 @@ TYPED_TEST(TablesOdbcV2Test, SQLTablesGetMetadataBySQLDescribeColODBCVer2) { SQL_WVARCHAR, SQL_WVARCHAR}; SQLULEN column_sizes[] = {1024, 1024, 1024, 1024, 1024}; - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); EXPECT_EQ(column_names[i].length(), name_length); 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 623f4aa3f500..2458ea9974c0 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 @@ -1894,10 +1894,10 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoInvalidDataType) { TYPED_TEST(TypeInfoTest, TestSQLGetTypeInfoUnsupportedDataType) { // Assumes mock and remote server don't support GUID data type - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_GUID)); + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(this->stmt, SQL_GUID)); // Result set is empty with valid data type that is unsupported by the server - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } } // namespace arrow::flight::sql::odbc From eef3b6f10a1267b11dfbe7a2e3d25ad5408b389f Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:40:03 -0700 Subject: [PATCH 15/17] ODBC connection properties documentation for unix --- .../flight/sql/odbc/Connection-Options.md | 20 ------ .../flight/sql/odbc/connection-options.md | 64 +++++++++++++++++++ 2 files changed, 64 insertions(+), 20 deletions(-) delete mode 100644 cpp/src/arrow/flight/sql/odbc/Connection-Options.md create mode 100644 cpp/src/arrow/flight/sql/odbc/connection-options.md diff --git a/cpp/src/arrow/flight/sql/odbc/Connection-Options.md b/cpp/src/arrow/flight/sql/odbc/Connection-Options.md deleted file mode 100644 index 61ca1eac6e4d..000000000000 --- a/cpp/src/arrow/flight/sql/odbc/Connection-Options.md +++ /dev/null @@ -1,20 +0,0 @@ - - -GH-49723 TODO: enter ODBC connection options for unix DSN diff --git a/cpp/src/arrow/flight/sql/odbc/connection-options.md b/cpp/src/arrow/flight/sql/odbc/connection-options.md new file mode 100644 index 000000000000..6c1dd706bd94 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/connection-options.md @@ -0,0 +1,64 @@ + + +# Connection Properties on Apache Arrow Flight SQL ODBC Driver + +## Setting ODBC Connection Properties + +ODBC connection parameters can be set in a connection string or defined in a DSN inside your system's odbc.ini. + +The following sample connection string and sample DSN are two equivalent ways to connect to Arrow. + +### Sample Connection String +``` +"driver={Apache Arrow Flight SQL ODBC Driver};HOST=1234.56.789;port=12345;uid=sample_user;pwd=sample_password;useEncryption=false;UseWideChar=true;" +``` + +### Sample DSN +``` +[Apache Arrow Flight SQL] +Driver = Apache Arrow Flight SQL ODBC Driver +Host = 1234.56.789 +Port = 12345 +UID = sample_user +PWD = sample_password +useEncryption = false +UseWideChar = true +``` + +### Driver Connection Options +| Option | Description | Default | +|--------|-------------|---------------| +| `driver` | Required: the driver for this ODBC driver. | Apache Arrow Flight SQL +| `dsn` | Data Source Name used for configuring the connection. | `NONE` +| `host` | The IP address or hostname for the server. | `NONE` +| `port` | The TCP port number the server uses for ODBC connections. | `NONE` +| `user` | The username for authentication to the server. | `NONE` +| `user id` | The username for authentication to the server. | `NONE` +| `uid` | The username for authentication to the server. | `NONE` +| `password` | The password for authentication to the server. | `NONE` +| `pwd` | The password for authentication to the server. | `NONE` +| `token` | The personal access token for authentication to the server. | `NONE` +| `useEncryption` | Setting to determine if an SSL-encrypted connection should be used. | `true` on Windows & Linux, `false` on MacOS +| `disableCertificateVerification` | Setting to determine if the driver should verify the host certificate against the trust store. | `false` +| `trustedCerts` | The full path of the .pem file containing certificates for the purpose of verifying the server. | `NONE` +| `useSystemTrustStore` | Setting to determine whether to use a CA certificate from the system's trust store or from a specified .pem file. | `true` +| `stringColumnLength` | Maximum length of a string column. | `NONE` +| `useWideChar` | Setting to determine if wide characters should be used. | `true` on Windows, `false` on MacOS & Linux +| `chunkBufferCapacity` | Capacity of a chunk buffer. | 5 From 56c04807c7f750373e80f85fea318e8b20837e34 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Thu, 23 Apr 2026 13:54:53 -0700 Subject: [PATCH 16/17] Update README --- cpp/src/arrow/flight/sql/odbc/README.md | 44 ++++++++++++++++++------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/README.md b/cpp/src/arrow/flight/sql/odbc/README.md index 9261fbd3bb1b..9cb10162e960 100644 --- a/cpp/src/arrow/flight/sql/odbc/README.md +++ b/cpp/src/arrow/flight/sql/odbc/README.md @@ -17,19 +17,25 @@ under the License. --> -## Steps to Register the 64-bit Apache Arrow ODBC driver on Windows +## Steps to Register the Apache Arrow Flight SQL ODBC driver -After the build succeeds, the ODBC DLL will be located in -`build\debug\Debug` for a debug build and `build\release\Release` for a release build. +After building the repository you will find the built ODBC binaries in the build artifacts. -1. Open Windows Power Shell as administrator. +On Windows, the driver binary will be located at `build\debug\Debug\arrow_flight_sql_odbc.dll` for a debug build and `build\release\Release\arrow_flight_sql_odbc.dll` for a release build. -2. Register your ODBC DLL: +On MacOS, the driver binary will be located at `build/debug/libarrow_flight_sql_odbc.dylib` for a debug build and `build/release/libarrow_flight_sql_odbc.dylib` for a release build. - Need to replace `` with actual path to repository in the commands. +On Linux, the driver binary will be located at `build/debug/libarrow_flight_sql_odbc.so` for a debug build and `build/release/libarrow_flight_sql_odbc.so` for a release build. - 1. `cd ` - 2. Run script to register your ODBC DLL as Apache Arrow Flight SQL ODBC Driver +1. Open your system terminal. On Windows this should be Power Shell in administrator mode. + +2. Register your ODBC binary: + + These commands need `` to be replaced with the actual path to the repository. + + 1. `cd ` + 2. Run script to register your ODBC driver binary as Apache Arrow Flight SQL ODBC Driver.
+ On Windows: ``` .\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd \cpp\build\< release | debug >\< Release | Debug>\arrow_flight_sql_odbc.dll ``` @@ -37,9 +43,24 @@ After the build succeeds, the ODBC DLL will be located in ``` .\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd C:\path\to\arrow\cpp\build\release\Release\arrow_flight_sql_odbc.dll ``` + On MacOS: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.dylib + ``` + Example command for reference: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/release/libarrow_flight_sql_odbc.dylib + ``` + On Linux: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.so + ``` + Example command for reference: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/release/libarrow_flight_sql_odbc.so + ``` -If the registration is successful, then Apache Arrow Flight SQL ODBC Driver -should show as an available ODBC driver in the x64 ODBC Driver Manager. +If the registration is successful, then Apache Arrow Flight SQL ODBC Driver should show as an available ODBC driver. On Windows this should be visible in the x64 ODBC Driver Manager. On MacOS & Linux this should be visible in your system odbc.ini. ## Steps to Generate Windows Installer 1. Install WiX toolset v6 from [GitHub](https://github.com/wixtoolset/wix/releases/). @@ -138,10 +159,11 @@ ODBC installers are uploaded to the CI artifacts. ### Install `.RPM` on Ubuntu While installing via `.DEB` installer on Ubuntu is the recommended approach, users may install `.RPM` on Ubuntu using below command ``` -alien -i --scripts ArrowFlightSqlOdbcODBC-.rpm +alien -i --scripts ArrowFlightSqlOdbc-.rpm ``` ## Known Limitations - Conversion from timestamp data type with specified time zone value to strings is not supported at the moment. This doesn't impact driver's usage of retrieving timestamp data from Power BI on Windows, and Excel on macOS and Windows. See GH-47504 for more context. - Conversion from strings to big int data type has a limit range of -9007199254740992 to 9007199254740992. +- On Linux, `isql` commands `tables` and `columns` don’t work due to GH-49702. Users are not blocked from fetching data tables. From 0086825d966f2f0570cc4d191345a31ffaa1f4b9 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Fri, 24 Apr 2026 11:29:50 -0700 Subject: [PATCH 17/17] Linux DEB ODBC installer support * Initial draft of DEB installer * reuse script for RPM, and rename script to indicate `postinst` (postinstall) * Add `file` to dockerfile to enable Debian installation * Fix component settings with DEB * Fix package name * Clean up comments * Fix file name * Fix postinst variable for DEB * Fix upload artifact file name and doc file name --- .github/workflows/cpp_extra.yml | 17 ++++++++++++----- ci/docker/ubuntu-24.04-cpp.dockerfile | 1 + cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 18 +++++++++++++----- .../linux/{rpm/postinstall => postinst} | 0 4 files changed, 26 insertions(+), 10 deletions(-) rename cpp/src/arrow/flight/sql/odbc/install/linux/{rpm/postinstall => postinst} (100%) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 1d2cb99959c9..ca85e0a0e26a 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -384,6 +384,13 @@ jobs: run-options: >- -e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON -e ODBC_PACKAGE_FORMAT=RPM + - image: ubuntu-cpp-odbc + title: AMD64 Ubuntu DEB Release + build-type: release + format: deb + run-options: >- + -e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON + -e ODBC_PACKAGE_FORMAT=DEB # GH-49582: TODO Enable Debian build for ODBC # - image: debian-cpp-odbc # title: AMD64 Debian @@ -415,8 +422,8 @@ jobs: uses: actions/cache@v5 with: path: .docker - key: ${{ matrix.image }}-${{ matrix.build-type }}-${{ hashFiles('cpp/**') }} - restore-keys: ${{ matrix.image }}-${{ matrix.build-type }}- + key: ${{ matrix.image }}-${{ matrix.build-type }}-${{ matrix.format }}-${{ hashFiles('cpp/**') }} + restore-keys: ${{ matrix.image }}-${{ matrix.build-type }}-${{ matrix.format }}- - name: Setup Python on hosted runner uses: actions/setup-python@v6 with: @@ -437,8 +444,8 @@ jobs: if: matrix.build-type == 'release' uses: actions/upload-artifact@v7 with: - name: flight-sql-odbc-pkg-installer-${{ matrix.format }} - path: build/cpp/ArrowFlightSqlOdbcODBC-*.${{ matrix.format }} + name: flight-sql-odbc-${{ matrix.format }}-installer + path: build/cpp/ArrowFlightSqlOdbc-*.${{ matrix.format }} if-no-files-found: error - name: Docker Push @@ -564,7 +571,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} - path: build/cpp/ArrowFlightSqlOdbcODBC-*.pkg + path: build/cpp/ArrowFlightSqlOdbc-*.pkg if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | diff --git a/ci/docker/ubuntu-24.04-cpp.dockerfile b/ci/docker/ubuntu-24.04-cpp.dockerfile index eca5495b12f0..c13c6b27cbc0 100644 --- a/ci/docker/ubuntu-24.04-cpp.dockerfile +++ b/ci/docker/ubuntu-24.04-cpp.dockerfile @@ -70,6 +70,7 @@ RUN apt-get update -y -q && \ ccache \ cmake \ curl \ + file \ gdb \ git \ libbenchmark-dev \ diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index fa6c0938d871..8c576ae66ee1 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -157,7 +157,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp") else() set(ODBC_UNIX_FILE_NAME - "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + "ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" ) if(APPLE) set(CPACK_PACKAGE_FILE_NAME "${ODBC_UNIX_FILE_NAME}") @@ -178,13 +178,21 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Linux set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") if(${ODBC_PACKAGE_FORMAT} STREQUAL "DEB") - # GH-49595 TODO: implement DEB installer - message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64) + set(CPACK_GENERATOR DEB) + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/postinst") + set(CPACK_DEBIAN_FILE_NAME "${ODBC_UNIX_FILE_NAME}.deb") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) + # Exclude Unspecified components + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) elseif(${ODBC_PACKAGE_FORMAT} STREQUAL "RPM") set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) set(CPACK_GENERATOR RPM) set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/rpm/postinstall") + "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/postinst") set(CPACK_RPM_FILE_NAME "${ODBC_UNIX_FILE_NAME}.rpm") # Disable dependency check as ODBC embeds all third party dependencies set(CPACK_RPM_PACKAGE_AUTOREQPROV "no") @@ -231,7 +239,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" DESTINATION "${DOC_INSTALL_DIR}" COMPONENT Docs) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md" + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md" DESTINATION "${DOC_INSTALL_DIR}" COMPONENT Docs) endif() diff --git a/cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall b/cpp/src/arrow/flight/sql/odbc/install/linux/postinst similarity index 100% rename from cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall rename to cpp/src/arrow/flight/sql/odbc/install/linux/postinst