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 199c7e2d49fd..756993f68715 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 }} @@ -96,9 +106,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 @@ -107,16 +118,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 @@ -184,9 +196,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 +212,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 @@ -263,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" @@ -348,15 +363,23 @@ 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 + # GH-49582: TODO Enable Debian build for ODBC + # - image: debian-cpp-odbc + # title: AMD64 Debian env: ARCH: amd64 ARCHERY_DEBUG: 1 @@ -369,12 +392,18 @@ jobs: with: 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: 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: @@ -389,7 +418,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() && @@ -400,16 +429,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: 75 strategy: fail-fast: false @@ -518,13 +548,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 @@ -541,79 +573,15 @@ 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: 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 + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows 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 - 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: | @@ -636,7 +604,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 @@ -678,6 +646,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 @@ -724,39 +811,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: - 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: @@ -767,6 +821,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: inherit 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/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/compose.yaml b/compose.yaml index 17e08ad1173e..669cabdd9225 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: @@ -204,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++ ####################################### @@ -371,6 +377,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 @@ -509,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" @@ -516,7 +571,11 @@ 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 command: > /bin/bash -c " /arrow/ci/scripts/cpp_build.sh /arrow /build && diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index 665d1b5a1ec4..51b968fcb56d 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -1116,19 +1116,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) @@ -2689,51 +2680,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/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/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/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt index e0e562f2d255..a0e8685b63fc 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/tests/CMakeLists.txt @@ -42,6 +42,7 @@ set(ARROW_FLIGHT_SQL_ODBC_TEST_SRCS # GH-46889: move protobuf_test_util to a more common location ../../../../engine/substrait/protobuf_test_util.cc) +# GH-49652: TODO support static test linkage on macOS if(ARROW_TEST_LINKAGE STREQUAL "static") set(ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS arrow_flight_sql_odbc_static ${ARROW_TEST_STATIC_LINK_LIBS}) @@ -65,6 +66,13 @@ else() # Unix list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_STATIC_LINK_LIBS ${ARROW_FLIGHT_SQL_ODBC_TEST_LIBS} ${ARROW_FLIGHT_SQL_ODBC_TEST_LINK_LIBS}) + + if(NOT APPLE) + # Links static dependencies on Linux to support ARROW_TEST_LINKAGE=static + list(APPEND ARROW_FLIGHT_SQL_ODBC_TEST_STATIC_LINK_LIBS arrow_odbc_spi_impl + ${ARROW_PROTOBUF_LIBPROTOBUF}) + endif() + endif() add_arrow_test(flight_sql_odbc_test 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/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/dremio/docker-compose.yml b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml new file mode 100644 index 000000000000..bf8f7f32ed4d --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml @@ -0,0 +1,39 @@ +# 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. + +networks: + odbc_net: + external: true + +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 + 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 new file mode 100755 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/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..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 @@ -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,38 @@ 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 = SqlWCharArrLen(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..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 @@ -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 = 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); +#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,16 @@ 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 +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); 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",