diff --git a/.github/actions/odbc-windows/action.yml b/.github/actions/odbc-windows/action.yml new file mode 100644 index 000000000000..10ba9ebbc15c --- /dev/null +++ b/.github/actions/odbc-windows/action.yml @@ -0,0 +1,95 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: ODBC Windows Reusable +inputs: + github-token: + description: 'GITHUB_TOKEN for vcpkg caching' + required: true +runs: + using: "composite" + steps: + - name: Disable Crash Dialogs + shell: pwsh + run: | + reg add ` + "HKCU\SOFTWARE\Microsoft\Windows\Windows Error Reporting" ` + /v DontShowUI ` + /t REG_DWORD ` + /d 1 ` + /f + - name: Download Timezone Database + shell: bash + run: ci/scripts/download_tz_database.sh + - name: Install ccache + shell: bash + run: | + ci/scripts/install_ccache.sh 4.12.1 /usr + - name: Setup ccache + shell: bash + run: | + ci/scripts/ccache_setup.sh + - name: ccache info + id: ccache-info + shell: bash + run: | + echo "cache-dir=$(ccache --get-config cache_dir)" >> $GITHUB_OUTPUT + - name: Cache ccache + uses: actions/cache@v5 + with: + path: ${{ steps.ccache-info.outputs.cache-dir }} + key: cpp-odbc-ccache-windows-x64-${{ hashFiles('cpp/**') }} + restore-keys: cpp-odbc-ccache-windows-x64- + - name: Checkout vcpkg + uses: actions/checkout@v6 + with: + fetch-depth: 0 + path: vcpkg + repository: microsoft/vcpkg + - name: Bootstrap vcpkg + shell: pwsh + run: | + vcpkg\bootstrap-vcpkg.bat + $VCPKG_ROOT = $(Resolve-Path -LiteralPath "vcpkg").ToString() + Write-Output ${VCPKG_ROOT} | ` + Out-File -FilePath ${Env:GITHUB_PATH} -Encoding utf8 -Append + Write-Output "VCPKG_ROOT=${VCPKG_ROOT}" | ` + Out-File -FilePath ${Env:GITHUB_ENV} -Encoding utf8 -Append + - name: Setup NuGet credentials for vcpkg caching + shell: bash + run: | + $(vcpkg fetch nuget | tail -n 1) \ + sources add \ + -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ + -storepasswordincleartext \ + -name "GitHub" \ + -username "$GITHUB_REPOSITORY_OWNER" \ + -password "${{ inputs.github-token }}" + $(vcpkg fetch nuget | tail -n 1) \ + setapikey "${{ inputs.github-token }}" \ + -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" + - name: Build + shell: cmd + run: | + set VCPKG_ROOT_KEEP=%VCPKG_ROOT% + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 + set VCPKG_ROOT=%VCPKG_ROOT_KEEP% + bash -c "ci/scripts/cpp_build.sh $(pwd) $(pwd)/build" + - name: Register Flight SQL ODBC Driver + shell: cmd + run: | + call "cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd" ${{ github.workspace }}\build\cpp\%ARROW_BUILD_TYPE%\arrow_flight_sql_odbc.dll diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index c762b7cfcdb4..ca85e0a0e26a 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -73,6 +73,16 @@ on: schedule: - cron: | 0 0 * * * + workflow_dispatch: + inputs: + odbc_upload: + description: 'ODBC Component Upload' + required: true + default: 'dll' + type: choice + options: + - dll + - msi concurrency: group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} @@ -95,9 +105,10 @@ jobs: name: ${{ matrix.title }} runs-on: ${{ matrix.runs-on }} if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 75 strategy: fail-fast: false @@ -106,16 +117,17 @@ jobs: - image: alpine-linux-cpp runs-on: ubuntu-latest title: AMD64 Alpine Linux - - image: ubuntu-cpp - run-options: >- - -e ARROW_CTEST_TIMEOUT=2000 - -e ARROW_C_FLAGS_DEBUG="-O1" - -e ARROW_CXX_FLAGS_DEBUG="-O1" - -e ARROW_GANDIVA=OFF - -e ARROW_LARGE_MEMORY_TESTS=ON - -e BUILD_WARNING_LEVEL=PRODUCTION - runs-on: "runs-on=${{ github.run_id }}/family=x8i.2xlarge/volume=80gb/spot=capacity-optimized" - title: AMD64 Ubuntu Large Memory Tests + # Disable Large Memory Tests locally + # - image: ubuntu-cpp + # run-options: >- + # -e ARROW_CTEST_TIMEOUT=2000 + # -e ARROW_C_FLAGS_DEBUG="-O1" + # -e ARROW_CXX_FLAGS_DEBUG="-O1" + # -e ARROW_GANDIVA=OFF + # -e ARROW_LARGE_MEMORY_TESTS=ON + # -e BUILD_WARNING_LEVEL=PRODUCTION + # runs-on: "runs-on=${{ github.run_id }}/family=x8i.2xlarge/volume=80gb/spot=capacity-optimized" + # title: AMD64 Ubuntu Large Memory Tests - image: conda-cpp run-options: >- -e ARROW_USE_MESON=ON @@ -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 @@ -264,9 +278,10 @@ jobs: name: JNI macOS runs-on: macos-14 if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 45 env: MACOSX_DEPLOYMENT_TARGET: "14.0" @@ -350,15 +365,40 @@ 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 RPM Release + build-type: release + format: rpm + run-options: >- + -e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON + -e ODBC_PACKAGE_FORMAT=RPM + - image: ubuntu-cpp-odbc + title: AMD64 Ubuntu DEB Release + build-type: release + format: deb + run-options: >- + -e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON + -e ODBC_PACKAGE_FORMAT=DEB + # GH-49582: TODO Enable Debian build for ODBC + # - image: debian-cpp-odbc + # title: AMD64 Debian + - image: ubuntu-cpp-odbc + title: AMD64 Ubuntu Debug + build-type: debug + run-options: >- + -e ARROW_BUILD_TYPE=DEBUG env: ARCH: amd64 ARCHERY_DEBUG: 1 @@ -372,12 +412,18 @@ jobs: persist-credentials: false fetch-depth: 0 submodules: recursive + - name: Create Docker Test Network + run: docker network create odbc_net + - name: Set Up Dremio Instance + run: | + docker compose -f cpp/src/arrow/flight/sql/odbc/tests/dremio/docker-compose.yml up -d + cpp/src/arrow/flight/sql/odbc/tests/dremio/set_up_dremio_instance.sh - name: Cache Docker Volumes uses: actions/cache@v5 with: path: .docker - key: ubuntu-cpp-odbc-${{ hashFiles('cpp/**') }} - restore-keys: ubuntu-cpp-odbc- + key: ${{ matrix.image }}-${{ matrix.build-type }}-${{ matrix.format }}-${{ hashFiles('cpp/**') }} + restore-keys: ${{ matrix.image }}-${{ matrix.build-type }}-${{ matrix.format }}- - name: Setup Python on hosted runner uses: actions/setup-python@v6 with: @@ -392,7 +438,16 @@ 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.run-options || '' }} ${{ matrix.image }} + + - name: Upload ODBC ${{ matrix.format }} to the job + if: matrix.build-type == 'release' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-${{ matrix.format }}-installer + path: build/cpp/ArrowFlightSqlOdbc-*.${{ matrix.format }} + if-no-files-found: error + - name: Docker Push if: >- success() && @@ -403,16 +458,17 @@ jobs: ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }} ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }} continue-on-error: true - run: archery docker push ubuntu-cpp-odbc + run: archery docker push ${{ matrix.image }} odbc-macos: needs: check-labels name: ODBC ${{ matrix.build-type }} ${{ matrix.architecture }} macOS ${{ matrix.macos-version }} runs-on: macos-${{ matrix.macos-version }} if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || - contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')) timeout-minutes: 120 strategy: fail-fast: false @@ -428,6 +484,7 @@ jobs: ARROW_DEPENDENCY_SOURCE: BUNDLED ARROW_DEPENDENCY_USE_SHARED: OFF ARROW_FLIGHT_SQL_ODBC: ON + ARROW_FLIGHT_SQL_ODBC_INSTALLER: ON ARROW_HOME: /tmp/local ARROW_MIMALLOC: OFF steps: @@ -503,6 +560,19 @@ jobs: --allow libresolv \ --allow libz \ "$(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib" + - name: Generate macOS Installer + if: matrix.build-type == 'release' + shell: bash + run: | + cd $(pwd)/build/cpp + cpack + - name: Upload ODBC PKG to the job + if: matrix.build-type == 'release' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} + path: build/cpp/ArrowFlightSqlOdbc-*.pkg + if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib @@ -522,13 +592,15 @@ jobs: name: ODBC Windows runs-on: windows-2022 if: >- + github.event_name != 'workflow_dispatch' && ( needs.check-labels.outputs.force == 'true' || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') || contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++') + ) timeout-minutes: 240 permissions: packages: write - env: + env: &odbc_msvc_env ARROW_BUILD_SHARED: ON ARROW_BUILD_STATIC: OFF ARROW_BUILD_TESTS: ON @@ -545,81 +617,16 @@ jobs: VCPKG_BINARY_SOURCES: 'clear;nugettimeout,600;nuget,GitHub,readwrite' VCPKG_DEFAULT_TRIPLET: x64-windows steps: - - name: Disable Crash Dialogs - run: | - reg add ` - "HKCU\SOFTWARE\Microsoft\Windows\Windows Error Reporting" ` - /v DontShowUI ` - /t REG_DWORD ` - /d 1 ` - /f - name: Checkout Arrow uses: actions/checkout@v6 with: persist-credentials: false fetch-depth: 0 submodules: recursive - - name: Download Timezone Database - shell: bash - run: ci/scripts/download_tz_database.sh - - name: Install ccache - shell: bash - run: | - ci/scripts/install_ccache.sh 4.12.1 /usr - - name: Setup ccache - shell: bash - run: | - ci/scripts/ccache_setup.sh - - name: ccache info - id: ccache-info - shell: bash - run: | - echo "cache-dir=$(ccache --get-config cache_dir)" >> $GITHUB_OUTPUT - - name: Cache ccache - uses: actions/cache@v5 + - 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: - persist-credentials: false - fetch-depth: 0 - path: vcpkg - repository: microsoft/vcpkg - - name: Bootstrap vcpkg - run: | - vcpkg\bootstrap-vcpkg.bat - $VCPKG_ROOT = $(Resolve-Path -LiteralPath "vcpkg").ToString() - Write-Output ${VCPKG_ROOT} | ` - Out-File -FilePath ${Env:GITHUB_PATH} -Encoding utf8 -Append - Write-Output "VCPKG_ROOT=${VCPKG_ROOT}" | ` - Out-File -FilePath ${Env:GITHUB_ENV} -Encoding utf8 -Append - - name: Setup NuGet credentials for vcpkg caching - shell: bash - run: | - $(vcpkg fetch nuget | tail -n 1) \ - sources add \ - -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" \ - -storepasswordincleartext \ - -name "GitHub" \ - -username "$GITHUB_REPOSITORY_OWNER" \ - -password "${{ secrets.GITHUB_TOKEN }}" - $(vcpkg fetch nuget | tail -n 1) \ - setapikey "${{ secrets.GITHUB_TOKEN }}" \ - -source "https://nuget.pkg.github.com/$GITHUB_REPOSITORY_OWNER/index.json" - - name: Build - shell: cmd - run: | - set VCPKG_ROOT_KEEP=%VCPKG_ROOT% - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 - set VCPKG_ROOT=%VCPKG_ROOT_KEEP% - bash -c "ci/scripts/cpp_build.sh $(pwd) $(pwd)/build" - - name: Register Flight SQL ODBC Driver - shell: cmd - run: | - call "cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd" ${{ github.workspace }}\build\cpp\%ARROW_BUILD_TYPE%\arrow_flight_sql_odbc.dll + github-token: ${{ secrets.GITHUB_TOKEN }} - name: Test shell: cmd run: | @@ -642,7 +649,7 @@ jobs: wix --version cd build/cpp cpack - - name: Upload the artifacts to the job + - name: Upload ODBC MSI to the job uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-msi-installer @@ -684,6 +691,125 @@ jobs: Write-Error "ODBC DLL not found" exit 1 + odbc-msvc-upload-dll: + needs: check-labels + name: ODBC Windows Upload Unsigned DLL + runs-on: windows-2022 + if: inputs.odbc_upload == 'dll' + timeout-minutes: 240 + permissions: + packages: write + env: *odbc_msvc_env + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Name Unsigned ODBC DLL + run: | + Rename-Item ` + -Path build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc.dll ` + -NewName arrow_flight_sql_odbc_unsigned.dll + - name: Upload ODBC DLL to the job + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-dll + path: build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc_unsigned.dll + if-no-files-found: error + + odbc-dll-release: + needs: odbc-msvc-upload-dll + name: Upload Unsigned ODBC DLL + runs-on: ubuntu-latest + permissions: + # Upload to GitHub Release + contents: write + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Download the artifacts + uses: actions/download-artifact@v8 + with: + name: flight-sql-odbc-dll + - name: Wait for creating GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + dev/release/utils-watch-gh-workflow.sh \ + ${GITHUB_REF_NAME} \ + release_candidate.yml + - name: Upload the artifacts to GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload ${GITHUB_REF_NAME} \ + --clobber \ + arrow_flight_sql_odbc_unsigned.dll + + odbc-msvc-upload-msi: + needs: check-labels + name: ODBC Windows Upload Unsigned MSI + runs-on: windows-2022 + if: inputs.odbc_upload == 'msi' + timeout-minutes: 240 + permissions: + # Upload to GitHub Release + contents: write + packages: write + env: *odbc_msvc_env + steps: + - name: Checkout Arrow + uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - name: Download signed ODBC DLL + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release download $env:GITHUB_REF_NAME ` + --pattern arrow_flight_sql_odbc.dll ` + --clobber + - name: Build ODBC Windows + uses: ./.github/actions/odbc-windows + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Replace signed DLL with unsigned DLL + run: | + Move-Item ` + -Path ./arrow_flight_sql_odbc.dll ` + -Destination build/cpp/${{ env.ARROW_BUILD_TYPE }}/arrow_flight_sql_odbc.dll ` + -Force + - name: Install WiX Toolset + shell: pwsh + run: | + Invoke-WebRequest -Uri https://github.com/wixtoolset/wix/releases/download/v6.0.0/wix-cli-x64.msi -OutFile wix-cli-x64.msi + Start-Process -FilePath wix-cli-x64.msi -ArgumentList '/quiet', 'Include_freethreaded=1' -Wait + echo "C:\Program Files\WiX Toolset v6.0\bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: Build MSI ODBC installer + shell: pwsh + run: | + # Verify WiX version + wix --version + cd build/cpp + cpack + - name: Upload the artifacts to GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + cd build/cpp + gh release upload $env:GITHUB_REF_NAME ` + --clobber ` + Apache-Arrow-Flight-SQL-ODBC-*-win64.msi + odbc-nightly: needs: odbc-msvc name: ODBC nightly @@ -731,40 +857,6 @@ jobs: remote_key: ${{ secrets.NIGHTLIES_RSYNC_KEY }} remote_host_key: ${{ secrets.NIGHTLIES_RSYNC_HOST_KEY }} - odbc-release: - needs: odbc-msvc - name: ODBC release - runs-on: ubuntu-latest - if: ${{ startsWith(github.ref_name, 'apache-arrow-') && contains(github.ref_name, '-rc') }} - permissions: - # Upload to GitHub Release - contents: write - steps: - - name: Checkout Arrow - uses: actions/checkout@v6 - with: - persist-credentials: false - fetch-depth: 0 - submodules: recursive - - name: Download the artifacts - uses: actions/download-artifact@v8 - with: - name: flight-sql-odbc-msi-installer - - name: Wait for creating GitHub Release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - dev/release/utils-watch-gh-workflow.sh \ - ${GITHUB_REF_NAME} \ - release_candidate.yml - - name: Upload the artifacts to GitHub Release - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release upload ${GITHUB_REF_NAME} \ - --clobber \ - Apache-Arrow-Flight-SQL-ODBC-*-win64.msi - report-extra-cpp: if: github.event_name == 'schedule' && always() needs: @@ -775,6 +867,8 @@ jobs: - odbc-linux - odbc-macos - odbc-msvc + - odbc-msvc-upload-dll + - odbc-msvc-upload-msi - odbc-nightly uses: ./.github/workflows/report_ci.yml secrets: diff --git a/.gitignore b/.gitignore index 83458ab2057b..c7690ec2637f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ dependency-reduced-pom.xml MANIFEST compile_commands.json build.ninja +build*/ # Generated Visual Studio files *.vcxproj diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0544ff11bf88..6d22c1fb0a0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -347,7 +347,10 @@ repos: ?^cpp/build-support/update-thrift\.sh$| ?^cpp/examples/minimal_build/run\.sh$| ?^cpp/examples/tutorial_examples/run\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$| + ?^cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall$| ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$| ?^dev/release/05-binary-upload\.sh$| ?^dev/release/08-binary-verify\.sh$| ?^dev/release/binary-recover\.sh$| 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/docker/ubuntu-24.04-cpp.dockerfile b/ci/docker/ubuntu-24.04-cpp.dockerfile index 074301b472dc..c13c6b27cbc0 100644 --- a/ci/docker/ubuntu-24.04-cpp.dockerfile +++ b/ci/docker/ubuntu-24.04-cpp.dockerfile @@ -70,6 +70,7 @@ RUN apt-get update -y -q && \ ccache \ cmake \ curl \ + file \ gdb \ git \ libbenchmark-dev \ @@ -118,6 +119,7 @@ RUN apt-get update -y -q && \ python3-venv \ rados-objclass-dev \ rapidjson-dev \ + rpm \ rsync \ tzdata \ tzdata-legacy \ diff --git a/ci/scripts/cpp_build.sh b/ci/scripts/cpp_build.sh index 1e2f3e8f8f1a..5023c30a5df4 100755 --- a/ci/scripts/cpp_build.sh +++ b/ci/scripts/cpp_build.sh @@ -274,6 +274,7 @@ else -Dlz4_SOURCE=${lz4_SOURCE:-} \ -Dnlohmann_json_SOURCE=${nlohmann_json_SOURCE:-} \ -Dopentelemetry-cpp_SOURCE=${opentelemetry_cpp_SOURCE:-} \ + -DODBC_PACKAGE_FORMAT=${ODBC_PACKAGE_FORMAT:-} \ -DORC_SOURCE=${ORC_SOURCE:-} \ -DPARQUET_BUILD_EXAMPLES=${PARQUET_BUILD_EXAMPLES:-OFF} \ -DPARQUET_BUILD_EXECUTABLES=${PARQUET_BUILD_EXECUTABLES:-OFF} \ diff --git a/ci/scripts/cpp_test.sh b/ci/scripts/cpp_test.sh index 241addbfebd2..17c604680d18 100755 --- a/ci/scripts/cpp_test.sh +++ b/ci/scripts/cpp_test.sh @@ -87,7 +87,11 @@ case "$(uname)" in n_jobs=${NPROC:-1} ;; esac -if [ "${#exclude_tests[@]}" -gt 0 ]; then + +if [ "$ARROW_FLIGHT_SQL_ODBC" = "ON" ]; then + # GH-49816: Only run ODBC tests on ODBC CI pipelines + ctest_options+=(--tests-regex "arrow-flight-sql-odbc-test|arrow-odbc-spi-impl-test") +elif [ "${#exclude_tests[@]}" -gt 0 ]; then IFS="|" ctest_options+=(--exclude-regex "${exclude_tests[*]}") unset IFS diff --git a/compose.yaml b/compose.yaml index be32a95dd945..f797dbb7246c 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,12 +571,17 @@ services: ARROW_PARQUET: "OFF" ARROW_S3: "OFF" ARROW_SUBSTRAIT: "OFF" + networks: + - odbc_net + # Use `/arrow/build` so build artifacts are visible on the CI host + # Generate ODBC installer before testing # Register ODBC before running tests command: > /bin/bash -c " - /arrow/ci/scripts/cpp_build.sh /arrow /build && + /arrow/ci/scripts/cpp_build.sh /arrow /arrow/build && + (cd /arrow/build/cpp && cpack) && sudo /arrow/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /usr/local/lib/libarrow_flight_sql_odbc.so && - /arrow/ci/scripts/cpp_test.sh /arrow /build" + /arrow/ci/scripts/cpp_test.sh /arrow /arrow/build" ubuntu-cpp-minimal: # Arrow build with minimal components/dependencies diff --git a/cpp/cmake_modules/DefineOptions.cmake b/cpp/cmake_modules/DefineOptions.cmake index 017a5a6efb26..260dc4e9da65 100644 --- a/cpp/cmake_modules/DefineOptions.cmake +++ b/cpp/cmake_modules/DefineOptions.cmake @@ -343,6 +343,12 @@ takes precedence over ccache if a storage backend is configured" ON) ARROW_FLIGHT_SQL ARROW_COMPUTE) + define_option(ARROW_FLIGHT_SQL_ODBC_INSTALLER + "Build the installer Arrow Flight SQL ODBC extension" + OFF + DEPENDS + ARROW_FLIGHT_SQL_ODBC) + define_option(ARROW_GANDIVA "Build the Gandiva libraries" OFF diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake index cc632a62fe4d..ac037f99691f 100644 --- a/cpp/cmake_modules/ThirdpartyToolchain.cmake +++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake @@ -1108,19 +1108,10 @@ function(build_boost) endif() if(ARROW_FLIGHT_SQL_ODBC) # GH-49244: Replace boost beast with alternatives in ODBC - # GH-49243: Replace boost variant with std::variant in ODBC # GH-49245: Replace boost xpressive with alternatives in ODBC - list(APPEND - BOOST_INCLUDE_LIBRARIES - beast - variant - xpressive) + list(APPEND BOOST_INCLUDE_LIBRARIES beast xpressive) else() - list(APPEND - BOOST_EXCLUDE_LIBRARIES - beast - variant - xpressive) + list(APPEND BOOST_EXCLUDE_LIBRARIES beast xpressive) endif() set(BOOST_SKIP_INSTALL_RULES ON) if(NOT ARROW_ENABLE_THREADING) @@ -2754,51 +2745,53 @@ macro(build_zlib) # bundled. We need to do this for all packages # not just zlib as some depend on zlib, but we don't rebuild # if it exists already - if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") - # build zlib using Emscripten ports - if(NOT EXISTS ${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a) - execute_process(COMMAND embuilder --pic --force build zlib) - endif() - add_library(ZLIB::ZLIB STATIC IMPORTED) - set_property(TARGET ZLIB::ZLIB - PROPERTY IMPORTED_LOCATION - "${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a") - target_include_directories(ZLIB::ZLIB INTERFACE "${EMSCRIPTEN_SYSROOT}/include") - list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) - else() - set(ZLIB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib_ep/src/zlib_ep-install") - if(MSVC) - if(${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG") - set(ZLIB_STATIC_LIB_NAME zlibstaticd.lib) - else() - set(ZLIB_STATIC_LIB_NAME zlibstatic.lib) + if(NOT TARGET ZLIB::ZLIB) + if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + # build zlib using Emscripten ports + if(NOT EXISTS ${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a) + execute_process(COMMAND embuilder --pic --force build zlib) endif() + add_library(ZLIB::ZLIB STATIC IMPORTED) + set_property(TARGET ZLIB::ZLIB + PROPERTY IMPORTED_LOCATION + "${EMSCRIPTEN_SYSROOT}/lib/wasm32-emscripten/pic/libz.a") + target_include_directories(ZLIB::ZLIB INTERFACE "${EMSCRIPTEN_SYSROOT}/include") + list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) else() - set(ZLIB_STATIC_LIB_NAME libz.a) + set(ZLIB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib_ep/src/zlib_ep-install") + if(MSVC) + if(${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG") + set(ZLIB_STATIC_LIB_NAME zlibstaticd.lib) + else() + set(ZLIB_STATIC_LIB_NAME zlibstatic.lib) + endif() + else() + set(ZLIB_STATIC_LIB_NAME libz.a) + endif() + set(ZLIB_STATIC_LIB "${ZLIB_PREFIX}/lib/${ZLIB_STATIC_LIB_NAME}") + set(ZLIB_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=${ZLIB_PREFIX}") + + externalproject_add(zlib_ep + ${EP_COMMON_OPTIONS} + URL ${ZLIB_SOURCE_URL} + URL_HASH "SHA256=${ARROW_ZLIB_BUILD_SHA256_CHECKSUM}" + BUILD_BYPRODUCTS "${ZLIB_STATIC_LIB}" + CMAKE_ARGS ${ZLIB_CMAKE_ARGS}) + + file(MAKE_DIRECTORY "${ZLIB_PREFIX}/include") + + add_library(ZLIB::ZLIB STATIC IMPORTED) + set(ZLIB_LIBRARIES ${ZLIB_STATIC_LIB}) + set(ZLIB_INCLUDE_DIRS "${ZLIB_PREFIX}/include") + set_target_properties(ZLIB::ZLIB PROPERTIES IMPORTED_LOCATION ${ZLIB_LIBRARIES}) + target_include_directories(ZLIB::ZLIB BEFORE INTERFACE "${ZLIB_INCLUDE_DIRS}") + + add_dependencies(ZLIB::ZLIB zlib_ep) + list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) endif() - set(ZLIB_STATIC_LIB "${ZLIB_PREFIX}/lib/${ZLIB_STATIC_LIB_NAME}") - set(ZLIB_CMAKE_ARGS ${EP_COMMON_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=${ZLIB_PREFIX}") - - externalproject_add(zlib_ep - ${EP_COMMON_OPTIONS} - URL ${ZLIB_SOURCE_URL} - URL_HASH "SHA256=${ARROW_ZLIB_BUILD_SHA256_CHECKSUM}" - BUILD_BYPRODUCTS "${ZLIB_STATIC_LIB}" - CMAKE_ARGS ${ZLIB_CMAKE_ARGS}) - - file(MAKE_DIRECTORY "${ZLIB_PREFIX}/include") - add_library(ZLIB::ZLIB STATIC IMPORTED) - set(ZLIB_LIBRARIES ${ZLIB_STATIC_LIB}) - set(ZLIB_INCLUDE_DIRS "${ZLIB_PREFIX}/include") - set_target_properties(ZLIB::ZLIB PROPERTIES IMPORTED_LOCATION ${ZLIB_LIBRARIES}) - target_include_directories(ZLIB::ZLIB BEFORE INTERFACE "${ZLIB_INCLUDE_DIRS}") - - add_dependencies(ZLIB::ZLIB zlib_ep) - list(APPEND ARROW_BUNDLED_STATIC_LIBS ZLIB::ZLIB) + set(ZLIB_VENDORED TRUE) endif() - - set(ZLIB_VENDORED TRUE) endmacro() if(ARROW_WITH_ZLIB) diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 4227873706ff..8c576ae66ee1 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") @@ -132,7 +129,6 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache Arrow Flight SQL ODBC Driver") set(CPACK_PACKAGE_CONTACT "dev@arrow.apache.org") - # GH-47876 TODO: set up `arrow_flight_sql_odbc` component for macOS Installer # GH-47877 TODO: set up `arrow_flight_sql_odbc` component for Linux Installer if(WIN32) # Install ODBC and its Arrow dependencies @@ -159,6 +155,93 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp") + else() + set(ODBC_UNIX_FILE_NAME + "ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + ) + if(APPLE) + set(CPACK_PACKAGE_FILE_NAME "${ODBC_UNIX_FILE_NAME}") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + + set(CPACK_SET_DESTDIR ON) + set(CPACK_INSTALL_PREFIX "/Library/ODBC") + # Register ODBC after install + set(CPACK_POSTFLIGHT_ARROW_FLIGHT_SQL_ODBC_SCRIPT + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/postinstall") + set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/README.txt") + set(CPACK_RESOURCE_FILE_WELCOME + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/Welcome.txt") + + set(ODBC_INSTALL_DIR "arrow-odbc/lib") + set(DOC_INSTALL_DIR "arrow-odbc/doc") + else() + # Linux + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + if(${ODBC_PACKAGE_FORMAT} STREQUAL "DEB") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64) + set(CPACK_GENERATOR DEB) + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/postinst") + set(CPACK_DEBIAN_FILE_NAME "${ODBC_UNIX_FILE_NAME}.deb") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_CONTACT}") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) + # Exclude Unspecified components + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) + elseif(${ODBC_PACKAGE_FORMAT} STREQUAL "RPM") + set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) + set(CPACK_GENERATOR RPM) + set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/install/linux/postinst") + set(CPACK_RPM_FILE_NAME "${ODBC_UNIX_FILE_NAME}.rpm") + # Disable dependency check as ODBC embeds all third party dependencies + set(CPACK_RPM_PACKAGE_AUTOREQPROV "no") + set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1) + set(CPACK_RPM_COMPONENT_INSTALL ON) + else() + message(FATAL_ERROR "ODBC_PACKAGE_FORMAT '${ODBC_PACKAGE_FORMAT}' must be DEB or RPM for Linux installer." + ) + endif() + + # By default, Linux installs under /usr + set(ODBC_INSTALL_DIR "lib64/arrow-odbc/lib") + set(DOC_INSTALL_DIR "lib64/arrow-odbc/doc") + endif() + + # Install ODBC + install(TARGETS arrow_flight_sql_odbc_shared + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc) + + # Install temporary driver registration scripts, they will be removed after driver registration is complete + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc_ini.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + + # Install documentation files + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) endif() get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) @@ -173,8 +256,13 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Upgrade GUID is required to be unchanged for ODBC installer to upgrade set(CPACK_WIX_UPGRADE_GUID "DBF27A18-F8BF-423F-9E3A-957414D52C4B") set(CPACK_WIX_PRODUCT_GUID "279D087B-93B5-4DC3-BA69-BCF485022A26") + else() + # macOS and Linux + list(APPEND CPACK_COMPONENTS_ALL Docs) + if(APPLE) + set(CPACK_GENERATOR "productbuild") + endif() endif() - # GH-47876 TODO: create macOS Installer using cpack # GH-47877 TODO: create Linux Installer using cpack # Load CPack after all CPACK* variables are set @@ -183,4 +271,11 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) DISPLAY_NAME "ODBC library" DESCRIPTION "Apache Arrow Flight SQL ODBC library bin, required to install" REQUIRED) + if(UNIX) + # On macOS and Linux, provide connection string documentation since users need to manually enter DSN keys. + cpack_add_component(Docs + DISPLAY_NAME "Documentation" + DESCRIPTION "Documentation for Apache Arrow Flight SQL ODBC Driver" + ) + endif() endif() diff --git a/cpp/src/arrow/flight/sql/odbc/README.md b/cpp/src/arrow/flight/sql/odbc/README.md index a2a3fd79041a..9cb10162e960 100644 --- a/cpp/src/arrow/flight/sql/odbc/README.md +++ b/cpp/src/arrow/flight/sql/odbc/README.md @@ -17,19 +17,25 @@ under the License. --> -## Steps to Register the 64-bit Apache Arrow ODBC driver on Windows +## Steps to Register the Apache Arrow Flight SQL ODBC driver -After the build succeeds, the ODBC DLL will be located in -`build\debug\Debug` for a debug build and `build\release\Release` for a release build. +After building the repository you will find the built ODBC binaries in the build artifacts. -1. Open Windows Power Shell as administrator. +On Windows, the driver binary will be located at `build\debug\Debug\arrow_flight_sql_odbc.dll` for a debug build and `build\release\Release\arrow_flight_sql_odbc.dll` for a release build. -2. Register your ODBC DLL: +On MacOS, the driver binary will be located at `build/debug/libarrow_flight_sql_odbc.dylib` for a debug build and `build/release/libarrow_flight_sql_odbc.dylib` for a release build. - Need to replace `` with actual path to repository in the commands. +On Linux, the driver binary will be located at `build/debug/libarrow_flight_sql_odbc.so` for a debug build and `build/release/libarrow_flight_sql_odbc.so` for a release build. - 1. `cd ` - 2. Run script to register your ODBC DLL as Apache Arrow Flight SQL ODBC Driver +1. Open your system terminal. On Windows this should be Power Shell in administrator mode. + +2. Register your ODBC binary: + + These commands need `` to be replaced with the actual path to the repository. + + 1. `cd ` + 2. Run script to register your ODBC driver binary as Apache Arrow Flight SQL ODBC Driver.
+ On Windows: ``` .\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd \cpp\build\< release | debug >\< Release | Debug>\arrow_flight_sql_odbc.dll ``` @@ -37,9 +43,24 @@ After the build succeeds, the ODBC DLL will be located in ``` .\cpp\src\arrow\flight\sql\odbc\tests\install_odbc.cmd C:\path\to\arrow\cpp\build\release\Release\arrow_flight_sql_odbc.dll ``` + On MacOS: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.dylib + ``` + Example command for reference: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/release/libarrow_flight_sql_odbc.dylib + ``` + On Linux: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/< release | debug >/libarrow_flight_sql_odbc.so + ``` + Example command for reference: + ``` + ./cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /cpp/build/release/libarrow_flight_sql_odbc.so + ``` -If the registration is successful, then Apache Arrow Flight SQL ODBC Driver -should show as an available ODBC driver in the x64 ODBC Driver Manager. +If the registration is successful, then Apache Arrow Flight SQL ODBC Driver should show as an available ODBC driver. On Windows this should be visible in the x64 ODBC Driver Manager. On MacOS & Linux this should be visible in your system odbc.ini. ## Steps to Generate Windows Installer 1. Install WiX toolset v6 from [GitHub](https://github.com/wixtoolset/wix/releases/). @@ -125,7 +146,24 @@ After ODBC has been registered, you can run the ODBC tests. It is recommended to .\cpp\build\< release | debug >\< Release | Debug>\arrow-flight-sql-odbc-test.exe ``` +## Installers + +ODBC installers are uploaded to the CI artifacts. + +| Operating System | Package Format | +|------------------|----------------| +| Windows | MSI | +| macOS | PKG | +| Linux | DEB / RPM | + +### Install `.RPM` on Ubuntu +While installing via `.DEB` installer on Ubuntu is the recommended approach, users may install `.RPM` on Ubuntu using below command +``` +alien -i --scripts ArrowFlightSqlOdbc-.rpm +``` + ## Known Limitations - Conversion from timestamp data type with specified time zone value to strings is not supported at the moment. This doesn't impact driver's usage of retrieving timestamp data from Power BI on Windows, and Excel on macOS and Windows. See GH-47504 for more context. - Conversion from strings to big int data type has a limit range of -9007199254740992 to 9007199254740992. +- On Linux, `isql` commands `tables` and `columns` don’t work due to GH-49702. Users are not blocked from fetching data tables. diff --git a/cpp/src/arrow/flight/sql/odbc/connection-options.md b/cpp/src/arrow/flight/sql/odbc/connection-options.md new file mode 100644 index 000000000000..6c1dd706bd94 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/connection-options.md @@ -0,0 +1,64 @@ + + +# Connection Properties on Apache Arrow Flight SQL ODBC Driver + +## Setting ODBC Connection Properties + +ODBC connection parameters can be set in a connection string or defined in a DSN inside your system's odbc.ini. + +The following sample connection string and sample DSN are two equivalent ways to connect to Arrow. + +### Sample Connection String +``` +"driver={Apache Arrow Flight SQL ODBC Driver};HOST=1234.56.789;port=12345;uid=sample_user;pwd=sample_password;useEncryption=false;UseWideChar=true;" +``` + +### Sample DSN +``` +[Apache Arrow Flight SQL] +Driver = Apache Arrow Flight SQL ODBC Driver +Host = 1234.56.789 +Port = 12345 +UID = sample_user +PWD = sample_password +useEncryption = false +UseWideChar = true +``` + +### Driver Connection Options +| Option | Description | Default | +|--------|-------------|---------------| +| `driver` | Required: the driver for this ODBC driver. | Apache Arrow Flight SQL +| `dsn` | Data Source Name used for configuring the connection. | `NONE` +| `host` | The IP address or hostname for the server. | `NONE` +| `port` | The TCP port number the server uses for ODBC connections. | `NONE` +| `user` | The username for authentication to the server. | `NONE` +| `user id` | The username for authentication to the server. | `NONE` +| `uid` | The username for authentication to the server. | `NONE` +| `password` | The password for authentication to the server. | `NONE` +| `pwd` | The password for authentication to the server. | `NONE` +| `token` | The personal access token for authentication to the server. | `NONE` +| `useEncryption` | Setting to determine if an SSL-encrypted connection should be used. | `true` on Windows & Linux, `false` on MacOS +| `disableCertificateVerification` | Setting to determine if the driver should verify the host certificate against the trust store. | `false` +| `trustedCerts` | The full path of the .pem file containing certificates for the purpose of verifying the server. | `NONE` +| `useSystemTrustStore` | Setting to determine whether to use a CA certificate from the system's trust store or from a specified .pem file. | `true` +| `stringColumnLength` | Maximum length of a string column. | `NONE` +| `useWideChar` | Setting to determine if wide characters should be used. | `true` on Windows, `false` on MacOS & Linux +| `chunkBufferCapacity` | Capacity of a chunk buffer. | 5 diff --git a/cpp/src/arrow/flight/sql/odbc/install/linux/postinst b/cpp/src/arrow/flight/sql/odbc/install/linux/postinst new file mode 100755 index 000000000000..df20fab84a97 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/linux/postinst @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Use temporary driver registration script to register ODBC driver in system DSN +odbc_install_script="/usr/lib64/arrow-odbc/lib/install_odbc.sh" +"$odbc_install_script" /usr/lib64/arrow-odbc/lib/libarrow_flight_sql_odbc.so + +# Use temporary DSN registration script to register sample system DSN +dsn_install_script="/usr/lib64/arrow-odbc/lib/install_odbc_ini.sh" +"$dsn_install_script" /etc/odbc.ini + +# clean temporary script +rm -f "$odbc_install_script" +rm -f "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt new file mode 100644 index 000000000000..8624470eb8bb --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt @@ -0,0 +1,9 @@ +Files are available in '/Library/ODBC/arrow-odbc' after installation. + +To setup a connection, you can use DSN to store your data source connection information. +1. Open 'iODBC Data Source Administrator'. +2. To create a user DSN, go to 'User DSN' tab and click 'Add'. +3. Select 'Apache Arrow Flight SQL ODBC Driver' and click 'Finish'. +4. Enter DSN name and connection string values. +For the list of all supported options, check '/Library/ODBC/arrow-odbc/doc/Connection-Options.md'. +5. Click 'Ok' to save the DSN. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt new file mode 100644 index 000000000000..5898db428f6f --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt @@ -0,0 +1 @@ +Apache Arrow Flight SQL ODBC Driver is a read-only ODBC driver for connecting to data sources that support Arrow Flight SQL. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall new file mode 100755 index 000000000000..9499c2fe0e92 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Use temporary driver registration script to register ODBC driver in system DSN +odbc_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc.sh" +"$odbc_install_script" /Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib + +# Use temporary DSN registration script to register sample system DSN +dsn_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc_ini.sh" +"$dsn_install_script" /Library/ODBC/odbc.ini + +# clean temporary script +rm -f "$odbc_install_script" +rm -f "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh index 5ddcc8a4cbda..8c9423f1218e 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -# Used by macOS ODBC installer script `install_odbc_ini.sh` and macOS ODBC testing +# Used by arrow/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall set -euo pipefail @@ -42,20 +42,20 @@ fi case "$(uname)" in Linux) - USER_ODBCINST_FILE="/etc/odbcinst.ini" + SYSTEM_ODBCINST_FILE="/etc/odbcinst.ini" ;; *) # macOS - USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini" - mkdir -p "$HOME"/Library/ODBC + SYSTEM_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + mkdir -p /Library/ODBC ;; esac DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" -touch "$USER_ODBCINST_FILE" +touch "$SYSTEM_ODBCINST_FILE" -if grep -q "^\[$DRIVER_NAME\]" "$USER_ODBCINST_FILE"; then +if grep -q "^\[$DRIVER_NAME\]" "$SYSTEM_ODBCINST_FILE"; then echo "Driver [$DRIVER_NAME] already exists in odbcinst.ini" else echo "Adding [$DRIVER_NAME] to odbcinst.ini..." @@ -63,17 +63,24 @@ else [$DRIVER_NAME] Description=An ODBC Driver for Apache Arrow Flight SQL Driver=$ODBC_64BIT -" >>"$USER_ODBCINST_FILE" +" >>"$SYSTEM_ODBCINST_FILE" fi # Check if [ODBC Drivers] section exists -if grep -q '^\[ODBC Drivers\]' "$USER_ODBCINST_FILE"; then +if grep -q '^\[ODBC Drivers\]' "$SYSTEM_ODBCINST_FILE"; then # Section exists: check if driver entry exists - if ! grep -q "^${DRIVER_NAME}=" "$USER_ODBCINST_FILE"; then + if ! grep -q "^${DRIVER_NAME}=" "$SYSTEM_ODBCINST_FILE"; then # Driver entry does not exist, add under [ODBC Drivers] - sed -i '' "/^\[ODBC Drivers\]/a\\ -${DRIVER_NAME}=Installed -" "$USER_ODBCINST_FILE" + + awk -v driver="$DRIVER_NAME" ' + $0 ~ /^\[ODBC Drivers\]/ && !inserted { + print + print driver "=Installed" + inserted=1 + next + } + { print } + ' "$SYSTEM_ODBCINST_FILE" > "${SYSTEM_ODBCINST_FILE}.tmp" && mv "${SYSTEM_ODBCINST_FILE}.tmp" "$SYSTEM_ODBCINST_FILE" fi else # Section doesn't exist, append both section and driver entry at end @@ -81,5 +88,5 @@ else echo "" echo "[ODBC Drivers]" echo "${DRIVER_NAME}=Installed" - } >>"$USER_ODBCINST_FILE" + } >>"$SYSTEM_ODBCINST_FILE" fi 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..b86d4047b12c --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh @@ -0,0 +1,72 @@ +#!/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. + +SYSTEM_ODBC_FILE="$1" + +if [[ -z "$SYSTEM_ODBC_FILE" ]]; then + echo "error: path to system ODBC DSN is not specified. Call format: install_odbc_ini abs_path_to_odbc_dsn_ini" + exit 1 +fi + +DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" +DSN_NAME="Apache Arrow Flight SQL ODBC DSN" + +touch "$SYSTEM_ODBC_FILE" + +if grep -q "^\[$DSN_NAME\]" "$SYSTEM_ODBC_FILE"; then + echo "DSN [$DSN_NAME] already exists in $SYSTEM_ODBC_FILE" +else + echo "Adding [$DSN_NAME] to $SYSTEM_ODBC_FILE..." + cat >> "$SYSTEM_ODBC_FILE" < "${SYSTEM_ODBC_FILE}.tmp" && mv "${SYSTEM_ODBC_FILE}.tmp" "$SYSTEM_ODBC_FILE" + fi +else + # Section doesn't exist, append section and DSN entry at end + { + echo "" + echo "[ODBC Data Sources]" + echo "${DSN_NAME}=${DRIVER_NAME}" + } >> "$SYSTEM_ODBC_FILE" +fi diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc index 7c64dee21f5b..e2358e9a9f8f 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_api.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_api.cc @@ -588,7 +588,6 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT handle_type, SQLHANDLE handle, SQLSMALLINT r << ", message_text: " << static_cast(message_text) << ", buffer_length: " << buffer_length << ", text_length_ptr: " << static_cast(text_length_ptr); - using arrow::flight::sql::odbc::Diagnostics; using ODBC::GetStringAttribute; using ODBC::ODBCConnection; using ODBC::ODBCDescriptor; @@ -1435,7 +1434,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT record_number, } SQLRETURN SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT data_type) { - // GH-47237 TODO: return SQL_PRED_CHAR and SQL_PRED_BASIC for + // GH-47237 return SQL_PRED_CHAR and SQL_PRED_BASIC for // appropriate data types in `SEARCHABLE` field ARROW_LOG(DEBUG) << "SQLGetTypeInfoW called with stmt: " << stmt << " data_type: " << data_type; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc index e4625ace370f..939264bedb7d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.cc @@ -19,6 +19,7 @@ #include #include +#include #include "arrow/array.h" namespace arrow::flight::sql::odbc { @@ -39,7 +40,7 @@ inline RowStatus MoveSingleCellToBinaryBuffer(ColumnBinding* binding, BinaryArra auto* byte_buffer = static_cast(binding->buffer) + i * binding->buffer_length; - memcpy(byte_buffer, ((char*)value) + value_offset, value_length); + std::memcpy(byte_buffer, ((char*)value) + value_offset, value_length); if (remaining_length > binding->buffer_length) { result = RowStatus_SUCCESS_WITH_INFO; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc index 55ef46458e21..502eaf730689 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor_test.cc @@ -18,11 +18,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/binary_array_accessor.h" #include "arrow/testing/builder.h" #include "arrow/testing/gtest_util.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Basic) { +TEST(BinaryArrayAccessor, TestCDataTypeBinaryBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -53,7 +54,7 @@ TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Basic) { } } -TEST(BinaryArrayAccessor, Test_CDataType_BINARY_Truncation) { +TEST(BinaryArrayAccessor, TestCDataTypeBinaryTruncation) { std::vector values = {"ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEF"}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc index 68583b3f15e0..9299ee7602f0 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor_test.cc @@ -17,11 +17,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(BooleanArrayFlightSqlAccessor, Test_BooleanArray_CDataType_BIT) { +TEST(BooleanArrayFlightSqlAccessor, TestBooleanArrayCDataTypeBit) { const std::vector values = {true, false, true}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h index 0a79bc39dfb8..45f88b50fb8c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/common.h @@ -19,6 +19,7 @@ #include #include +#include #include "arrow/array.h" #include "arrow/flight/sql/odbc/odbc_impl/accessors/types.h" #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -42,7 +43,7 @@ inline size_t CopyFromArrayValuesToBinding(ARRAY_TYPE* array, ColumnBinding* bin } } } else { - // Duplicate this loop to avoid null checks within the loop. + // Duplicate above for-loop to exit early when null value is found for (int64_t i = starting_row; i < starting_row + cells; ++i) { if (array->IsNull(i)) { throw NullWithoutIndicatorException(); @@ -54,7 +55,7 @@ inline size_t CopyFromArrayValuesToBinding(ARRAY_TYPE* array, ColumnBinding* bin // Note that the array should already have been sliced down to the same number // of elements in the ODBC data array by the point in which this function is called. const auto* values = array->raw_values(); - memcpy(binding->buffer, &values[starting_row], element_size * cells); + std::memcpy(binding->buffer, &values[starting_row], element_size * cells); return cells; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc index 03716e2477a4..a482a838101c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/date_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/boolean_array_accessor.h" #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(DateArrayAccessor, Test_Date32Array_CDataType_DATE) { +TEST(DateArrayAccessor, TestDate32ArrayCDataTypeDate) { std::vector values = {7589, 12320, 18980, 19095, -1, 0}; std::vector expected = { {1990, 10, 12}, {2003, 9, 25}, {2021, 12, 19}, @@ -57,7 +58,7 @@ TEST(DateArrayAccessor, Test_Date32Array_CDataType_DATE) { } } -TEST(DateArrayAccessor, Test_Date64Array_CDataType_DATE) { +TEST(DateArrayAccessor, TestDate64ArrayCDataTypeDate) { std::vector values = { 86400000, 172800000, 259200000, 1649793238110, 0, 345600000, 432000000, 518400000, -86400000, -17987443200000, -24268068949000}; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc index 9833ea1d59c7..1b589b41c049 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/decimal_array_accessor_test.cc @@ -19,7 +19,8 @@ #include "arrow/builder.h" #include "arrow/testing/builder.h" #include "arrow/util/decimal.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { namespace { @@ -93,7 +94,7 @@ void AssertNumericOutput(int input_precision, int input_scale, } } -TEST(DecimalArrayFlightSqlAccessor, Test_Decimal128Array_CDataType_NUMERIC_SameScale) { +TEST(DecimalArrayFlightSqlAccessor, TestDecimal128ArrayCDataTypeNumericSameScale) { const std::vector& input_values = {"25.212", "-25.212", "-123456789.123", "123456789.123"}; const std::vector& output_values = diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc index bd9ecf3314fd..521a9c48b9aa 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/primitive_array_accessor_test.cc @@ -19,7 +19,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -52,43 +53,43 @@ void TestPrimitiveArraySqlAccessor() { } } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int64Array_CDataType_SBIGINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt64ArrayCDataTypeSbigint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int32Array_CDataType_SLONG) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt32ArrayCDataTypeSlong) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int16Array_CDataType_SSHORT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt16ArrayCDataTypeSshort) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_Int8Array_CDataType_STINYINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestInt8ArrayCDataTypeStinyint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt64Array_CDataType_UBIGINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt64ArrayCDataTypeUbigint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt32Array_CDataType_ULONG) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt32ArrayCDataTypeUlong) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt16Array_CDataType_USHORT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt16ArrayCDataTypeUshort) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_UInt8Array_CDataType_UTINYINT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestUInt8ArrayCDataTypeUtinyint) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_FloatArray_CDataType_FLOAT) { +TEST(PrimitiveArrayFlightSqlAccessor, TestFloatArrayCDataTypeFloat) { TestPrimitiveArraySqlAccessor(); } -TEST(PrimitiveArrayFlightSqlAccessor, Test_DoubleArray_CDataType_DOUBLE) { +TEST(PrimitiveArrayFlightSqlAccessor, TestDoubleArrayCDataTypeDouble) { TestPrimitiveArraySqlAccessor(); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc index 69b3b3049454..441b2a3394e7 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.cc @@ -18,6 +18,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor.h" #include +#include #include "arrow/array.h" #include "arrow/flight/sql/odbc/odbc_impl/encoding.h" @@ -79,7 +80,7 @@ inline RowStatus MoveSingleCellToCharBuffer( auto* byte_buffer = static_cast(binding->buffer) + i * binding->buffer_length; auto* char_buffer = (CHAR_TYPE*)byte_buffer; - memcpy(char_buffer, ((char*)value) + value_offset, value_length); + std::memcpy(char_buffer, ((char*)value) + value_offset, value_length); // Write a NUL terminator if (binding->buffer_length >= remaining_length + sizeof(CHAR_TYPE)) { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc index 9316571dd7b3..6950f3351b7c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/string_array_accessor_test.cc @@ -19,11 +19,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/encoding.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(StringArrayAccessor, Test_CDataType_CHAR_Basic) { +TEST(StringArrayAccessor, TestCDataTypeCharBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -49,7 +50,7 @@ TEST(StringArrayAccessor, Test_CDataType_CHAR_Basic) { } } -TEST(StringArrayAccessor, Test_CDataType_CHAR_Truncation) { +TEST(StringArrayAccessor, TestCDataTypeCharTruncation) { std::vector values = {"ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEF"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -82,7 +83,7 @@ TEST(StringArrayAccessor, Test_CDataType_CHAR_Truncation) { ASSERT_EQ(values[0], ss.str()); } -TEST(StringArrayAccessor, Test_CDataType_WCHAR_Basic) { +TEST(StringArrayAccessor, TestCDataTypeWcharBasic) { std::vector values = {"foo", "barx", "baz123"}; std::shared_ptr array; ArrayFromVector(values, &array); @@ -112,7 +113,7 @@ TEST(StringArrayAccessor, Test_CDataType_WCHAR_Basic) { } } -TEST(StringArrayAccessor, Test_CDataType_WCHAR_Truncation) { +TEST(StringArrayAccessor, TestCDataTypeWcharTruncation) { std::vector values = {"ABCDEFA"}; std::shared_ptr array; ArrayFromVector(values, &array); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc index eb49e4078cd8..41bd0d73ea77 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/time_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(TEST_TIME32, TIME_WITH_SECONDS) { +TEST(TestTime32, TimeWithSeconds) { auto value_field = field("f0", time32(TimeUnit::SECOND)); std::vector t32_values = {14896, 14897, 14892, 85400, 14893, 14895}; @@ -58,7 +59,7 @@ TEST(TEST_TIME32, TIME_WITH_SECONDS) { } } -TEST(TEST_TIME32, TIME_WITH_MILLI) { +TEST(TestTime32, TimeWithMilli) { auto value_field = field("f0", time32(TimeUnit::MILLI)); std::vector t32_values = {14896000, 14897000, 14892000, 85400000, 14893000, 14895000}; @@ -94,7 +95,7 @@ TEST(TEST_TIME32, TIME_WITH_MILLI) { } } -TEST(TEST_TIME64, TIME_WITH_MICRO) { +TEST(TestTime32, TimeWithMicro) { auto value_field = field("f0", time64(TimeUnit::MICRO)); std::vector t64_values = {14896000, 14897000, 14892000, @@ -131,7 +132,7 @@ TEST(TEST_TIME64, TIME_WITH_MICRO) { } } -TEST(TEST_TIME64, TIME_WITH_NANO) { +TEST(TestTime32, TimeWithNano) { auto value_field = field("f0", time64(TimeUnit::NANO)); std::vector t64_values = {14896000000, 14897000000, 14892000000, 85400000000, 14893000000, 14895000000}; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc index 37f14ebd9c52..93af94655769 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor.cc @@ -19,12 +19,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" -using arrow::TimeUnit; +#include +#include namespace arrow::flight::sql::odbc { namespace { - -int64_t GetConversionToSecondsDivisor(TimeUnit::type unit) { +inline int64_t GetConversionToSecondsDivisor(TimeUnit::type unit) { int64_t divisor = 1; switch (unit) { case TimeUnit::SECOND: @@ -79,6 +79,10 @@ template RowStatus TimestampArrayFlightSqlAccessor::MoveSingleCellImpl( ColumnBinding* binding, int64_t arrow_row, int64_t cell_counter, int64_t& value_offset, bool update_value_offset, Diagnostics& diagnostics) { + // Times less than the minimum integer number of seconds that can be represented + // for each time unit will not convert correctly. This is mostly interesting for + // nanoseconds as timestamps in other units are outside of the accepted range of + // Gregorian dates. auto* buffer = static_cast(binding->buffer); int64_t value = this->GetArray()->Value(arrow_row); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc index 393dd98501d9..dd4917b0e378 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/timestamp_array_accessor_test.cc @@ -20,11 +20,12 @@ #include "arrow/flight/sql/odbc/odbc_impl/calendar_utils.h" #include "arrow/flight/sql/odbc/odbc_impl/util.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) { +TEST(TestTimestamp, TimestampWithMilli) { std::vector values = {86400370, 172800000, 259200000, 1649793238110LL, 345600000, 432000000, 518400000, -86399000, 0, @@ -88,7 +89,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MILLI) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) { +TEST(TestTimestamp, TimestampWithSeconds) { std::vector values = {86400, 172800, 259200, 1649793238, 345600, 432000, 518400}; @@ -130,7 +131,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_SECONDS) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) { +TEST(TestTimestamp, TimestampWithMicro) { std::vector values = {86400000000, 1649793238000000}; std::shared_ptr timestamp_array; @@ -174,7 +175,7 @@ TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_MICRO) { } } -TEST(TEST_TIMESTAMP, TIMESTAMP_WITH_NANO) { +TEST(TestTimestamp, TimestampWithNano) { std::vector values = {86400000010000, 1649793238000000000}; std::shared_ptr timestamp_array; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h index f75d2894af99..7cd52af1bd02 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/accessors/types.h @@ -102,7 +102,7 @@ class FlightSqlAccessor : public Accessor { throw NullWithoutIndicatorException(); } } else { - // TODO: Optimize this by creating different versions of MoveSingleCell + // GH-47849 TODO: Optimize this by creating different versions of MoveSingleCell // depending on if str_len_buffer is null. auto row_status = MoveSingleCell(binding, current_arrow_row, i, value_offset, update_value_offset, diagnostics); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc index 7bdb4d58cf82..5dfc85a58f77 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.cc @@ -18,7 +18,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/address_info.h" #include -namespace driver { +namespace arrow::flight::sql::odbc { bool AddressInfo::GetAddressInfo(const std::string& host, char* host_name_info, int64_t max_host) { @@ -47,4 +47,5 @@ AddressInfo::~AddressInfo() { } AddressInfo::AddressInfo() : addrinfo_result_(nullptr) {} -} // namespace driver + +} // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h index c127c0f4a29d..7d538f912e0d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/address_info.h @@ -27,7 +27,7 @@ # include #endif -namespace driver { +namespace arrow::flight::sql::odbc { class AddressInfo { private: @@ -40,4 +40,5 @@ class AddressInfo { bool GetAddressInfo(const std::string& host, char* host_name_info, int64_t max_host); }; -} // namespace driver + +} // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc index 1dddae2a7c71..b47b33f2d93f 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/calendar_utils.cc @@ -40,6 +40,9 @@ int64_t GetTodayTimeFromEpoch() { #endif } +// GH-47631: add support for non-UTC time zone data. +// Read the time zone value from Arrow::Timestamp, and use the time zone value to convert +// seconds_since_epoch instead of converting to UTC time zone by default void GetTimeForSecondsSinceEpoch(const int64_t seconds_since_epoch, std::tm& out_tm) { std::memset(&out_tm, 0, sizeof(std::tm)); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc index 587dbdfb96ba..5da662e7aded 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_auth_method.cc @@ -37,6 +37,9 @@ class NoOpAuthMethod : public FlightSqlAuthMethod { void Authenticate(FlightSqlConnection& connection, FlightCallOptions& call_options) override { // Do nothing + + // GH-46733 TODO: implement NoOpAuthMethod to validate server address. + // Can use NoOpClientAuthHandler. } }; @@ -66,10 +69,10 @@ class UserPasswordAuthMethod : public FlightSqlAuthMethod { FlightCallOptions auth_call_options; const std::optional& login_timeout = connection.GetAttribute(Connection::LOGIN_TIMEOUT); - if (login_timeout && boost::get(*login_timeout) > 0) { + if (login_timeout && std::get(*login_timeout) > 0) { // ODBC's LOGIN_TIMEOUT attribute and FlightCallOptions.timeout use // seconds as time unit. - double timeout_seconds = static_cast(boost::get(*login_timeout)); + double timeout_seconds = static_cast(std::get(*login_timeout)); if (timeout_seconds > 0) { auth_call_options.timeout = TimeoutDuration{timeout_seconds}; } @@ -94,7 +97,9 @@ class UserPasswordAuthMethod : public FlightSqlAuthMethod { throw DriverException(bearer_result.status().message()); } - call_options.headers.push_back(bearer_result.ValueOrDie()); + // call_options may have already been populated with data from the connection string + // or DSN. Ensure auth-generated headers are placed at the front of the header list. + call_options.headers.insert(call_options.headers.begin(), bearer_result.ValueOrDie()); } std::string GetUser() override { return user_; } @@ -116,10 +121,11 @@ class TokenAuthMethod : public FlightSqlAuthMethod { void Authenticate(FlightSqlConnection& connection, FlightCallOptions& call_options) override { - // add the token to the headers + // add the token to the front of the headers. For consistency auth headers should be + // at the front. const std::pair token_header("authorization", "Bearer " + token_); - call_options.headers.push_back(token_header); + call_options.headers.insert(call_options.headers.begin(), token_header); const Status status = client_.Authenticate( call_options, std::unique_ptr(new NoOpClientAuthHandler())); @@ -143,22 +149,22 @@ std::unique_ptr FlightSqlAuthMethod::FromProperties( const std::unique_ptr& client, const Connection::ConnPropertyMap& properties) { // Check if should use user-password authentication - auto it_user = properties.find(FlightSqlConnection::USER); + auto it_user = properties.find(std::string(FlightSqlConnection::USER)); if (it_user == properties.end()) { // The Microsoft OLE DB to ODBC bridge provider (MSDASQL) will write // "User ID" and "Password" properties instead of mapping // to ODBC compliant UID/PWD keys. - it_user = properties.find(FlightSqlConnection::USER_ID); + it_user = properties.find(std::string(FlightSqlConnection::USER_ID)); } - auto it_password = properties.find(FlightSqlConnection::PASSWORD); - auto it_token = properties.find(FlightSqlConnection::TOKEN); + auto it_password = properties.find(std::string(FlightSqlConnection::PASSWORD)); + auto it_token = properties.find(std::string(FlightSqlConnection::TOKEN)); if (it_user == properties.end() || it_password == properties.end()) { // Accept UID/PWD as aliases for User/Password. These are suggested as // standard properties in the documentation for SQLDriverConnect. - it_user = properties.find(FlightSqlConnection::UID); - it_password = properties.find(FlightSqlConnection::PWD); + it_user = properties.find(std::string(FlightSqlConnection::UID)); + it_password = properties.find(std::string(FlightSqlConnection::PWD)); } if (it_user != properties.end() || it_password != properties.end()) { const std::string& user = it_user != properties.end() ? it_user->second : ""; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc index f00ce85d9f3e..e33268476d23 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.cc @@ -120,7 +120,7 @@ const std::set BUILT_IN_PROPERTIES Connection::ConnPropertyMap::const_iterator TrackMissingRequiredProperty( std::string_view property, const Connection::ConnPropertyMap& properties, std::vector& missing_attr) { - auto prop_iter = properties.find(property); + auto prop_iter = properties.find(std::string(property)); if (properties.end() == prop_iter) { missing_attr.push_back(property); } @@ -139,6 +139,7 @@ std::shared_ptr LoadFlightSslConfigs( AsBool(conn_property_map, FlightSqlConnection::USE_SYSTEM_TRUST_STORE) .value_or(SYSTEM_TRUST_STORE_DEFAULT); + // GH-47630: find co-located TLS certificate if `trusted certs` path is not specified auto trusted_certs_iterator = conn_property_map.find(std::string(FlightSqlConnection::TRUSTED_CERTS)); auto trusted_certs = trusted_certs_iterator != conn_property_map.end() @@ -244,9 +245,9 @@ const FlightCallOptions& FlightSqlConnection::PopulateCallOptions( // is the first request. const std::optional& connection_timeout = closed_ ? GetAttribute(LOGIN_TIMEOUT) : GetAttribute(CONNECTION_TIMEOUT); - if (connection_timeout && boost::get(*connection_timeout) > 0) { + if (connection_timeout && std::get(*connection_timeout) > 0) { call_options_.timeout = - TimeoutDuration{static_cast(boost::get(*connection_timeout))}; + TimeoutDuration{static_cast(std::get(*connection_timeout))}; } for (auto prop : props) { @@ -321,7 +322,7 @@ Location FlightSqlConnection::BuildLocation( Location location; if (ssl_config->UseEncryption()) { - driver::AddressInfo address_info; + AddressInfo address_info; char host_name_info[NI_MAXHOST] = ""; bool operation_result = false; @@ -335,7 +336,7 @@ Location FlightSqlConnection::BuildLocation( ThrowIfNotOK(Location::ForGrpcTls(host_name_info, port).Value(&location)); return location; } - // TODO: We should log that we could not convert an IP to hostname here. + // GH-47852 TODO: We should log that we could not convert an IP to hostname here. } } catch (...) { // This is expected. The Host attribute can be an IP or name, but make_address will @@ -403,7 +404,7 @@ Connection::Info FlightSqlConnection::GetInfo(uint16_t info_type) { if (info_type == SQL_DBMS_NAME || info_type == SQL_SERVER_NAME) { // Update the database component reported in error messages. // We do this lazily for performance reasons. - diagnostics_.SetDataSourceComponent(boost::get(result)); + diagnostics_.SetDataSourceComponent(std::get(result)); } return result; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h index 2561ea492f05..d1a194abcbd8 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h @@ -34,7 +34,7 @@ class FlightSqlSslConfig; /// \brief Create an instance of the FlightSqlSslConfig class, from the properties passed /// into the map. /// \param conn_property_map the map with the Connection properties. -/// \return An instance of the FlightSqlSslConfig. +/// \return An instance of the FlightSqlSslConfig. std::shared_ptr LoadFlightSslConfigs( const Connection::ConnPropertyMap& conn_property_map); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc index 87ae526f1582..bc26a113d77e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_connection_test.cc @@ -19,7 +19,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include "arrow/flight/types.h" -#include "gtest/gtest.h" + +#include #include @@ -33,17 +34,16 @@ TEST(AttributeTests, SetAndGetAttribute) { const std::optional first_value = connection.GetAttribute(Connection::CONNECTION_TIMEOUT); - EXPECT_TRUE(first_value); - - EXPECT_EQ(static_cast(200), boost::get(*first_value)); + ASSERT_TRUE(first_value); + ASSERT_EQ(static_cast(200), std::get(*first_value)); connection.SetAttribute(Connection::CONNECTION_TIMEOUT, static_cast(300)); const std::optional change_value = connection.GetAttribute(Connection::CONNECTION_TIMEOUT); - EXPECT_TRUE(change_value); - EXPECT_EQ(static_cast(300), boost::get(*change_value)); + ASSERT_TRUE(change_value); + ASSERT_EQ(static_cast(300), std::get(*change_value)); connection.Close(); } @@ -55,7 +55,7 @@ TEST(AttributeTests, GetAttributeWithoutSetting) { connection.GetAttribute(Connection::CONNECTION_TIMEOUT); connection.SetClosed(false); - EXPECT_EQ(0, boost::get(*optional)); + EXPECT_EQ(0, std::get(*optional)); connection.Close(); } @@ -77,8 +77,8 @@ TEST(MetadataSettingsTest, StringColumnLengthTest) { const std::optional actual_string_column_length = connection.GetStringColumnLength(properties); - EXPECT_TRUE(actual_string_column_length); - EXPECT_EQ(expected_string_column_length, *actual_string_column_length); + ASSERT_TRUE(actual_string_column_length); + ASSERT_EQ(expected_string_column_length, *actual_string_column_length); connection.Close(); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc index ebff8c40f2cb..a668353272b5 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_get_tables_reader.cc @@ -77,9 +77,9 @@ std::shared_ptr GetTablesReader::GetSchema() { const arrow::Result>& result = arrow::ipc::ReadSchema(&dataset_schema_reader, &in_memo); if (!result.ok()) { - // TODO: Ignoring this error until we fix the problem on Dremio server - // The problem is that complex types columns are being returned without the children - // types. + // GH-46561 TODO: Test and build the driver against a server that returns + // complex types columns with the children + // types and handle the failure properly return nullptr; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc index 9e2f45647a52..8278b42e36b1 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_result_set_metadata.cc @@ -158,19 +158,27 @@ size_t FlightSqlResultSetMetadata::GetLength(int column_position) { } std::string FlightSqlResultSetMetadata::GetLiteralPrefix(int column_position) { - // TODO: Flight SQL column metadata does not have this, should we add to the spec? + // GH-47853 TODO: use `ColumnMetadata` to get literal prefix after Flight SQL protocol + // adds support for it + + // Flight SQL column metadata does not have literal prefix, empty string is returned return ""; } std::string FlightSqlResultSetMetadata::GetLiteralSuffix(int column_position) { - // TODO: Flight SQL column metadata does not have this, should we add to the spec? + // GH-47853 TODO: use `ColumnMetadata` to get literal suffix after Flight SQL protocol + // adds support for it + + // Flight SQL column metadata does not have literal suffix, empty string is returned return ""; } std::string FlightSqlResultSetMetadata::GetLocalTypeName(int column_position) { ColumnMetadata metadata = GetMetadata(schema_->field(column_position - 1)); - // TODO: Is local type name the same as type name? + // Local type name is for display purpose only. + // Return type name as local type name as Flight SQL protocol doesn't have support for + // local type name. return metadata.GetTypeName().ValueOrElse([] { return ""; }); } @@ -193,7 +201,7 @@ size_t FlightSqlResultSetMetadata::GetOctetLength(int column_position) { // Workaround to get the precision for Decimal and Numeric types, since server doesn't // return it currently. - // TODO: Use the server precision when its fixed. + // GH-47854 TODO: Use the server precision when its fixed. std::shared_ptr arrow_type = field->type(); if (arrow_type->id() == Type::DECIMAL128) { int32_t precision = util::GetDecimalTypePrecision(arrow_type); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h index 10b121497121..c2d1423e97e6 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_ssl_config.h @@ -17,9 +17,9 @@ #pragma once -#include -#include #include +#include "arrow/flight/types.h" +#include "arrow/status.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc index 46456e8c3c91..c75631222605 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement.cc @@ -83,9 +83,9 @@ bool FlightSqlStatement::SetAttribute(StatementAttributeId attribute, case MAX_LENGTH: return CheckIfSetToOnlyValidValue(value, static_cast(0)); case QUERY_TIMEOUT: - if (boost::get(value) > 0) { + if (std::get(value) > 0) { call_options_.timeout = - TimeoutDuration{static_cast(boost::get(value))}; + TimeoutDuration{static_cast(std::get(value))}; } else { call_options_.timeout = TimeoutDuration{-1}; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc index 914cd8fa4520..a6200c0b1c15 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_columns.cc @@ -26,6 +26,8 @@ namespace arrow::flight::sql::odbc { using arrow::Result; +using arrow::Schema; +using arrow::flight::sql::ColumnMetadata; using util::AppendToBuilder; using std::make_optional; @@ -99,10 +101,9 @@ Result> TransformInner( const auto& table_name = reader.GetTableName(); const std::shared_ptr& schema = reader.GetSchema(); if (schema == nullptr) { - // TODO: Remove this if after fixing TODO on GetTablesReader::GetSchema() - // This is because of a problem on Dremio server, where complex types columns - // are being returned without the children types, so we are simply ignoring - // it by now. + // GH-46561 TODO: Test and build the driver against a server that returns + // complex types columns with the children + // types and handle the failure properly. continue; } for (int i = 0; i < schema->num_fields(); ++i) { @@ -126,8 +127,8 @@ Result> TransformInner( ? data_type_v3 : util::ConvertSqlDataTypeFromV3ToV2(data_type_v3); - // TODO: Use `metadata.GetTypeName()` when ARROW-16064 is merged. - const auto& type_name_result = field->metadata()->Get("ARROW:FLIGHT:SQL:TYPE_NAME"); + const auto& type_name_result = metadata.GetTypeName(); + data.type_name = type_name_result.ok() ? type_name_result.ValueOrDie() : util::GetTypeNameFromSqlDataType(data_type_v3); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h index 0c3ad10f97b5..5687134f1eb7 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h @@ -61,5 +61,4 @@ std::shared_ptr GetTablesForGenericUse( const std::string* catalog_name, const std::string* schema_name, const std::string* table_name, const std::vector& table_types, Diagnostics& diagnostics, const MetadataSettings& metadata_settings); - } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc index be788d9d08aa..d4812e30eee4 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/flight_sql_stream_chunk_buffer.cc @@ -20,8 +20,6 @@ namespace arrow::flight::sql::odbc { -using arrow::Result; - FlightStreamChunkBuffer::FlightStreamChunkBuffer( FlightSqlClient& flight_sql_client, const FlightClientOptions& client_options, const FlightCallOptions& call_options, const std::shared_ptr& flight_info, @@ -58,10 +56,10 @@ FlightStreamChunkBuffer::FlightStreamChunkBuffer( util::ThrowIfNotOK(result.status()); std::shared_ptr stream_reader_ptr(std::move(result.ValueOrDie())); - BlockingQueue, - std::shared_ptr>>::Supplier supplier = [=]() - -> std::optional< - std::pair, std::shared_ptr>> { + BlockingQueue, + std::shared_ptr>>::Supplier supplier = + [=]() -> std::optional, + std::shared_ptr>> { auto result = stream_reader_ptr->Next(); bool is_not_ok = !result.ok(); bool is_not_empty = result.ok() && (result.ValueOrDie().data != nullptr); @@ -82,13 +80,13 @@ FlightStreamChunkBuffer::FlightStreamChunkBuffer( } bool FlightStreamChunkBuffer::GetNext(FlightStreamChunk* chunk) { - std::pair, std::shared_ptr> + std::pair, std::shared_ptr> closeable_endpoint_stream_pair; if (!queue_.Pop(&closeable_endpoint_stream_pair)) { return false; } - Result result = closeable_endpoint_stream_pair.first; + arrow::Result result = closeable_endpoint_stream_pair.first; if (!result.status().ok()) { Close(); throw DriverException(result.status().message()); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h index a1452e4b466f..693ee000de52 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/get_info_cache.h @@ -17,13 +17,12 @@ #pragma once -#include "arrow/flight/sql/client.h" -#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" - #include #include #include #include +#include "arrow/flight/sql/client.h" +#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc index db6170f31027..acd68f0eef3c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.cc @@ -221,7 +221,7 @@ class ScalarToJson : public ScalarVisitor { } Status Visit(const DurationScalar& scalar) override { - // TODO: Append TimeUnit on conversion + // GH-47857 TODO: Append TimeUnit on conversion return ConvertScalarToStringAndWrite(scalar, writer_); } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h index 9c0b42748a8c..44321398b6fa 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter.h @@ -17,8 +17,8 @@ #pragma once -#include #include +#include "arrow/type_fwd.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc index a3c3275affd5..d6d7a3ed5062 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/json_converter_test.cc @@ -19,7 +19,8 @@ #include "arrow/scalar.h" #include "arrow/testing/builder.h" #include "arrow/type.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -163,7 +164,7 @@ TEST(ConvertToJson, MonthInterval) { } TEST(ConvertToJson, Duration) { - // TODO: Append TimeUnit on conversion + // GH-47857 TODO: Append TimeUnit on conversion ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::SECOND))); ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::MILLI))); ASSERT_EQ("\"123\"", ConvertToJson(DurationScalar(123, TimeUnit::MICRO))); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc index 142dac53ab6f..c92012cc84f9 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.cc @@ -22,6 +22,7 @@ #include "arrow/flight/sql/odbc/odbc_impl/odbc_connection.h" #include "arrow/flight/sql/odbc/odbc_impl/attribute_utils.h" +#include "arrow/flight/sql/odbc/odbc_impl/config/configuration.h" #include "arrow/flight/sql/odbc/odbc_impl/exceptions.h" #include "arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h" #include "arrow/flight/sql/odbc/odbc_impl/odbc_environment.h" @@ -236,8 +237,8 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_COLUMN_ALIAS: case SQL_DBMS_NAME: case SQL_DBMS_VER: - case SQL_DRIVER_NAME: // TODO: This should be the driver's filename and shouldn't - // come from the SPI. + case SQL_DRIVER_NAME: // GH-47858 TODO: This should be the driver's filename and + // shouldn't come from the SPI. case SQL_DRIVER_VER: case SQL_SEARCH_PATTERN_ESCAPE: case SQL_SERVER_NAME: @@ -263,7 +264,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_SPECIAL_CHARACTERS: case SQL_XOPEN_CLI_YEAR: { const auto& info = spi_connection_->GetInfo(info_type); - const std::string& info_value = boost::get(info); + const std::string& info_value = std::get(info); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -353,7 +354,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_SQL92_VALUE_EXPRESSIONS: case SQL_STANDARD_CLI_CONFORMANCE: { const auto& info = spi_connection_->GetInfo(info_type); - uint32_t info_value = boost::get(info); + uint32_t info_value = std::get(info); GetAttribute(info_value, value, buffer_length, output_length); return SQL_SUCCESS; } @@ -388,7 +389,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, case SQL_ODBC_SQL_CONFORMANCE: case SQL_ODBC_SAG_CLI_CONFORMANCE: { const auto& info = spi_connection_->GetInfo(info_type); - uint16_t info_value = boost::get(info); + uint16_t info_value = std::get(info); GetAttribute(info_value, value, buffer_length, output_length); return SQL_SUCCESS; } @@ -399,7 +400,7 @@ SQLRETURN ODBCConnection::GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, if (!attr) { throw DriverException("Optional feature not supported.", "HYC00"); } - const std::string& info_value = boost::get(*attr); + const std::string& info_value = std::get(*attr); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -417,7 +418,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, bool successfully_written = false; switch (attribute) { // Internal connection attributes -#ifdef SQL_ATR_ASYNC_DBC_EVENT +#ifdef SQL_ATTR_ASYNC_DBC_EVENT case SQL_ATTR_ASYNC_DBC_EVENT: throw DriverException("Optional feature not supported.", "HYC00"); #endif @@ -425,7 +426,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, case SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE: throw DriverException("Optional feature not supported.", "HYC00"); #endif -#ifdef SQL_ATTR_ASYNC_PCALLBACK +#ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK case SQL_ATTR_ASYNC_DBC_PCALLBACK: throw DriverException("Optional feature not supported.", "HYC00"); #endif @@ -453,7 +454,7 @@ void ODBCConnection::SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, throw DriverException("Cannot set read-only attribute", "HY092"); case SQL_ATTR_TRACE: // DM-only throw DriverException("Cannot set read-only attribute", "HY092"); - case SQL_ATTR_TRACEFILE: + case SQL_ATTR_TRACEFILE: // DM-only throw DriverException("Optional feature not supported.", "HYC00"); case SQL_ATTR_TRANSLATE_LIB: throw DriverException("Optional feature not supported.", "HYC00"); @@ -594,7 +595,7 @@ SQLRETURN ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, if (!catalog) { throw DriverException("Optional feature not supported.", "HYC00"); } - const std::string& info_value = boost::get(*catalog); + const std::string& info_value = std::get(*catalog); return GetStringAttribute(is_unicode, info_value, true, value, buffer_length, output_length, GetDiagnostics()); } @@ -623,7 +624,7 @@ SQLRETURN ODBCConnection::GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, throw DriverException("Invalid attribute", "HY092"); } - GetAttribute(static_cast(boost::get(*spi_attribute)), value, + GetAttribute(static_cast(std::get(*spi_attribute)), value, buffer_length, output_length); return SQL_SUCCESS; } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h index d50e99d0b619..4b7519f74a4e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_connection.h @@ -17,8 +17,8 @@ #pragma once -#include #include "arrow/flight/sql/odbc/odbc_impl/odbc_handle.h" +#include "arrow/flight/sql/odbc/odbc_impl/spi/connection.h" #include "arrow/flight/sql/odbc/odbc_impl/type_fwd.h" #include @@ -37,6 +37,9 @@ class ODBCConnection : public ODBCHandle { ODBCConnection(const ODBCConnection&) = delete; ODBCConnection& operator=(const ODBCConnection&) = delete; + /// \brief Constructor for ODBCConnection. + /// \param[in] environment the parent environment. + /// \param[in] spi_connection the underlying spi connection. ODBCConnection(ODBCEnvironment& environment, std::shared_ptr spi_connection); @@ -44,6 +47,11 @@ class ODBCConnection : public ODBCHandle { const std::string& GetDSN() const; bool IsConnected() const; + + /// \brief Connect to Arrow Flight SQL server. + /// \param[in] dsn the dsn name. + /// \param[in] properties the connection property map extracted from connection string. + /// \param[out] missing_properties report the properties that are missing void Connect(std::string dsn, const arrow::flight::sql::odbc::Connection::ConnPropertyMap& properties, std::vector& missing_properties); @@ -51,7 +59,7 @@ class ODBCConnection : public ODBCHandle { SQLRETURN GetInfo(SQLUSMALLINT info_type, SQLPOINTER value, SQLSMALLINT buffer_length, SQLSMALLINT* output_length, bool is_unicode); void SetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER string_length, - bool isUnicode); + bool is_unicode); SQLRETURN GetConnectAttr(SQLINTEGER attribute, SQLPOINTER value, SQLINTEGER buffer_length, SQLINTEGER* output_length, bool is_unicode); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc index e54fbf601eb6..ebb69720c887 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.cc @@ -64,7 +64,7 @@ ODBCDescriptor::ODBCDescriptor(Diagnostics& base_diagnostics, ODBCConnection* co parent_statement_(stmt), array_status_ptr_(nullptr), bind_offset_ptr_(nullptr), - rows_processed_ptr_(nullptr), + rows_proccessed_ptr_(nullptr), array_size_(1), bind_type_(SQL_BIND_BY_COLUMN), highest_one_based_bound_record_(0), @@ -111,7 +111,7 @@ void ODBCDescriptor::SetHeaderField(SQLSMALLINT field_identifier, SQLPOINTER val has_bindings_changed_ = true; break; case SQL_DESC_ROWS_PROCESSED_PTR: - SetPointerAttribute(value, rows_processed_ptr_); + SetPointerAttribute(value, rows_proccessed_ptr_); has_bindings_changed_ = true; break; case SQL_DESC_COUNT: { @@ -275,7 +275,7 @@ void ODBCDescriptor::GetHeaderField(SQLSMALLINT field_identifier, SQLPOINTER val GetAttribute(bind_type_, value, buffer_length, output_length); break; case SQL_DESC_ROWS_PROCESSED_PTR: - GetAttribute(rows_processed_ptr_, value, buffer_length, output_length); + GetAttribute(rows_proccessed_ptr_, value, buffer_length, output_length); break; case SQL_DESC_COUNT: { // highest_one_based_bound_record_ equals number of records + 1 @@ -509,10 +509,12 @@ void ODBCDescriptor::PopulateFromResultSetMetadata(ResultSetMetadata* rsmd) { rsmd->IsAutoUnique(one_based_index) ? SQL_TRUE : SQL_FALSE; records_[i].case_sensitive = rsmd->IsCaseSensitive(one_based_index) ? SQL_TRUE : SQL_FALSE; - records_[i].datetime_interval_precision; // TODO - update when rsmd adds this + records_[i].datetime_interval_precision; // GH-47869 TODO implement + // `SQL_DESC_DATETIME_INTERVAL_PRECISION` SQLINTEGER num_prec_radix = rsmd->GetNumPrecRadix(one_based_index); records_[i].num_prec_radix = num_prec_radix > 0 ? num_prec_radix : 0; - records_[i].datetime_interval_code; // TODO + records_[i].datetime_interval_code; // GH-47868 TODO implement + // `SQL_DESC_DATETIME_INTERVAL_CODE` records_[i].fixed_prec_scale = rsmd->IsFixedPrecScale(one_based_index) ? SQL_TRUE : SQL_FALSE; records_[i].nullable = rsmd->IsNullable(one_based_index); @@ -581,5 +583,5 @@ void ODBCDescriptor::SetDataPtrOnRecord(SQLPOINTER data_ptr, SQLSMALLINT record_ } void DescriptorRecord::CheckConsistency() { - // TODO + // GH-47870 TODO implement } diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h index f0259d40098c..7d59db91b6ef 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_descriptor.h @@ -121,8 +121,8 @@ class ODBCDescriptor : public ODBCHandle { inline SQLUSMALLINT* GetArrayStatusPtr() { return array_status_ptr_; } inline void SetRowsProcessed(SQLULEN rows) { - if (rows_processed_ptr_) { - *rows_processed_ptr_ = rows; + if (rows_proccessed_ptr_) { + *rows_proccessed_ptr_ = rows; } } @@ -139,7 +139,7 @@ class ODBCDescriptor : public ODBCHandle { ODBCStatement* parent_statement_; SQLUSMALLINT* array_status_ptr_; SQLULEN* bind_offset_ptr_; - SQLULEN* rows_processed_ptr_; + SQLULEN* rows_proccessed_ptr_; SQLULEN array_size_; SQLINTEGER bind_type_; SQLSMALLINT highest_one_based_bound_record_; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h index 9dd8fe37baf6..4674a4c9ff16 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_handle.h @@ -17,13 +17,14 @@ #pragma once -#include -#include +// platform.h includes windows.h, so it needs to be included first +#include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include #include #include #include +#include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" /** * @brief An abstraction over a generic ODBC handle. diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc index 51152c64782e..02579aaf5f74 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.cc @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -255,7 +254,7 @@ void ODBCStatement::CopyAttributesFromConnection(ODBCConnection& connection) { ODBCStatement& tracking_statement = connection.GetTrackingStatement(); // Get abstraction attributes and copy to this spi_statement_. - // Possible ODBC attributes are below, but many of these are not supported by warpdrive + // Possible ODBC attributes are below, but many of these are not supported by Arrow ODBC // or ODBCAbstaction: // SQL_ATTR_ASYNC_ENABLE: // SQL_ATTR_METADATA_ID: @@ -333,7 +332,7 @@ bool ODBCStatement::Fetch(size_t rows, SQLULEN* row_count_ptr, } if (current_ard_->HaveBindingsChanged()) { - // TODO: Deal handle when offset != buffer_length. + // GH-47871 TODO: handle when offset != buffer_length. // Wipe out all bindings in the ResultSet. // Note that the number of ARD records can both be more or less @@ -541,7 +540,7 @@ void ODBCStatement::GetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER outpu } if (spi_attribute) { - GetAttribute(static_cast(boost::get(*spi_attribute)), output, + GetAttribute(static_cast(std::get(*spi_attribute)), output, buffer_size, str_len_ptr); return; } @@ -625,6 +624,7 @@ void ODBCStatement::SetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER value return; case SQL_ATTR_ASYNC_ENABLE: + throw DriverException("Unsupported attribute", "HYC00"); #ifdef SQL_ATTR_ASYNC_STMT_EVENT case SQL_ATTR_ASYNC_STMT_EVENT: throw DriverException("Unsupported attribute", "HYC00"); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h index b5ee264f5544..f2226e84f6c9 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/odbc_statement.h @@ -17,10 +17,12 @@ #pragma once +// platform.h platform.h includes windows.h so it needs to be included first +#include "arrow/flight/sql/odbc/odbc_impl/platform.h" + #include "arrow/flight/sql/odbc/odbc_impl/odbc_handle.h" #include "arrow/flight/sql/odbc/odbc_impl/type_fwd.h" -#include #include #include #include @@ -57,7 +59,6 @@ class ODBCStatement : public ODBCHandle { /// row_count_ptr and row_status_array are optional arguments, they are only needed for /// SQLExtendedFetch bool Fetch(size_t rows, SQLULEN* row_count_ptr = 0, SQLUSMALLINT* row_status_array = 0); - bool IsPrepared() const; void GetStmtAttr(SQLINTEGER statement_attribute, SQLPOINTER output, diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc index cf1e5930a827..3749c276d4f3 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/parse_table_types_test.cc @@ -18,7 +18,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/flight_sql_statement_get_tables.h" #include "arrow/flight/sql/odbc/odbc_impl/platform.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h index 539583aac29f..15548b52c63d 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer.h @@ -17,9 +17,9 @@ #pragma once -#include -#include #include +#include "arrow/flight/client.h" +#include "arrow/type.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc index 9727167a500c..a5e094317ead 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/record_batch_transformer_test.cc @@ -20,7 +20,8 @@ #include "arrow/flight/sql/odbc/odbc_impl/platform.h" #include "arrow/record_batch.h" #include "arrow/testing/builder.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { namespace { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h index f4855812bf93..e9cf18dc55a3 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/scalar_function_reporter.h @@ -17,7 +17,7 @@ #pragma once -#include +#include "arrow/type.h" namespace arrow::flight::sql::odbc { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h index 42dc4d8edb15..3e4c08c9cdd2 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/connection.h @@ -19,11 +19,11 @@ #define BOOST_NO_CXX98_FUNCTION_BASE // ARROW-17805 #include -#include #include #include #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -67,8 +67,8 @@ class Connection { PACKET_SIZE, // uint32_t - The Packet Size }; - typedef boost::variant Attribute; - typedef boost::variant Info; + typedef std::variant Attribute; + typedef std::variant Info; typedef PropertyMap ConnPropertyMap; /// \brief Establish the connection. diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h index bdfeea3b79da..f5157b00bc2c 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/spi/statement.h @@ -17,9 +17,9 @@ #pragma once -#include #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/diagnostics.h" @@ -51,7 +51,7 @@ class Statement { QUERY_TIMEOUT, }; - typedef boost::variant Attribute; + typedef std::variant Attribute; /// \brief Set a statement attribute (may be called at any time) /// diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc index 47149a33a560..ff8416a43a86 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/custom_window.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include "arrow/flight/sql/odbc/odbc_impl/exceptions.h" diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc index 0432836a16f8..be6b3fe4799b 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/dsn_configuration_window.cc @@ -44,9 +44,9 @@ std::string TestConnection(const config::Configuration& config) { // This should have been checked before enabling the Test button. assert(missing_properties.empty()); std::string server_name = - boost::get(flight_sql_conn->GetInfo(SQL_SERVER_NAME)); + std::get(flight_sql_conn->GetInfo(SQL_SERVER_NAME)); std::string server_version = - boost::get(flight_sql_conn->GetInfo(SQL_DBMS_VER)); + std::get(flight_sql_conn->GetInfo(SQL_DBMS_VER)); return "Server Name: " + server_name + "\n" + "Server Version: " + server_version; } } // namespace @@ -565,7 +565,7 @@ bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wparam, LPARAM lparam) { open_file_name.lpstrFile = file_name; open_file_name.lpstrFile[0] = '\0'; open_file_name.nMaxFile = FILENAME_MAX; - // TODO: What type should this be? + // GH-47851 TODO: Update `lpstrFilter` to correct value open_file_name.lpstrFilter = L"All\0*.*"; open_file_name.nFilterIndex = 1; open_file_name.lpstrFileTitle = NULL; diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc index f21329977ba2..ce10ddd3bf9e 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/ui/window.cc @@ -36,7 +36,6 @@ HINSTANCE GetHInstance() { TCHAR sz_file_name[MAX_PATH]; GetModuleFileName(NULL, sz_file_name, MAX_PATH); - // TODO: This needs to be the module name. HINSTANCE h_instance = GetModuleHandle(sz_file_name); if (h_instance == NULL) { diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc index fe6a2d4d7c38..6792f7f7f52a 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.cc @@ -117,12 +117,13 @@ SqlDataType GetDataTypeFromArrowFieldV3(const std::shared_ptr& field, case Type::TIME64: return SqlDataType_TYPE_TIME; case Type::INTERVAL_MONTHS: - return SqlDataType_INTERVAL_MONTH; // TODO: maybe - // SqlDataType_INTERVAL_YEAR_TO_MONTH + return SqlDataType_INTERVAL_MONTH; // GH-47873 TODO: check and update to + // SqlDataType_INTERVAL_YEAR_TO_MONTH if it is + // more appropriate case Type::INTERVAL_DAY_TIME: return SqlDataType_INTERVAL_DAY; - // TODO: Handle remaining types. + // GH-47873 TODO: Handle remaining types. case Type::INTERVAL_MONTH_DAY_NANO: case Type::LIST: case Type::STRUCT: @@ -671,7 +672,7 @@ optional GetDisplaySize(SqlDataType data_type, case SqlDataType_INTERVAL_HOUR_TO_MINUTE: case SqlDataType_INTERVAL_HOUR_TO_SECOND: case SqlDataType_INTERVAL_MINUTE_TO_SECOND: - return nullopt; // TODO: Implement for INTERVAL types + return nullopt; // GH-47874 TODO: Implement for INTERVAL types case SqlDataType_GUID: return 36; default: @@ -938,9 +939,9 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type auto seconds_from_epoch = GetTodayTimeFromEpoch(); - auto third_converted_array = CheckConversion( - arrow::compute::Add(second_converted_array, - std::make_shared(seconds_from_epoch * 1000))); + auto third_converted_array = CheckConversion(arrow::compute::Add( + second_converted_array, + std::make_shared(seconds_from_epoch * 1000))); arrow::compute::CastOptions cast_options_2; cast_options_2.to_type = arrow::timestamp(TimeUnit::MILLI); @@ -959,7 +960,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type auto second_converted_array = CheckConversion(arrow::compute::Add( first_converted_array, - std::make_shared(seconds_from_epoch * 1000000000))); + std::make_shared(seconds_from_epoch * 1000000000))); arrow::compute::CastOptions cast_options_2; cast_options_2.to_type = arrow::timestamp(TimeUnit::NANO); @@ -983,7 +984,7 @@ ArrayConvertTask GetConverter(Type::type original_type_id, CDataType target_type } else if (original_type_id == Type::DECIMAL128 && (target_type == CDataType_CHAR || target_type == CDataType_WCHAR)) { return [=](const std::shared_ptr& original_array) { - StringBuilder builder; + arrow::StringBuilder builder; int64_t length = original_array->length(); ThrowIfNotOK(builder.ReserveData(length)); diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h index 63ce6d6549d6..b6165d1f5161 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util.h @@ -73,7 +73,7 @@ inline void ThrowIfNotOK(const Status& status) { template inline bool CheckIfSetToOnlyValidValue(const AttributeTypeT& value, T allowed_value) { - return boost::get(value) == allowed_value; + return std::get(value) == allowed_value; } template diff --git a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc index bfcec15b4dac..c5f4ac5c2c47 100644 --- a/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/odbc_impl/util_test.cc @@ -23,7 +23,8 @@ #include "arrow/testing/builder.h" #include "arrow/testing/gtest_util.h" #include "arrow/testing/util.h" -#include "gtest/gtest.h" + +#include namespace arrow::flight::sql::odbc { @@ -48,7 +49,7 @@ void AssertConvertedArray(const std::shared_ptr& expected_array, ASSERT_EQ(expected_array->ToString(), converted_array->ToString()); } -std::shared_ptr convertArray(const std::shared_ptr& original_array, +std::shared_ptr ConvertArray(const std::shared_ptr& original_array, CDataType c_type) { auto converter = util::GetConverter(original_array->type_id(), c_type); return converter(original_array); @@ -60,7 +61,7 @@ void TestArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } @@ -71,7 +72,7 @@ void TestTime32ArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(time32(TimeUnit::MILLI), input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } @@ -82,7 +83,7 @@ void TestTime64ArrayConversion(const std::vector& input, std::shared_ptr original_array; ArrayFromVector(time64(TimeUnit::NANO), input, &original_array); - auto converted_array = convertArray(original_array, c_type); + auto converted_array = ConvertArray(original_array, c_type); AssertConvertedArray(expected_array, converted_array, input.size(), arrow_type); } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/README b/cpp/src/arrow/flight/sql/odbc/tests/README new file mode 100644 index 000000000000..fe74c98b72f1 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/tests/README @@ -0,0 +1,23 @@ + + +Prior to running the tests, set environment variable `ARROW_FLIGHT_SQL_ODBC_CONN` +to a valid connection string. +A valid connection string looks like: +driver={Apache Arrow Flight SQL ODBC Driver};HOST=localhost;port=32010;pwd=myPassword;uid=myName;useEncryption=false; diff --git a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc index d88a569c8ffc..abe6d8e6994a 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/columns_test.cc @@ -46,6 +46,9 @@ TYPED_TEST_SUITE(ColumnsOdbcV2Test, TestTypesOdbcV2); namespace { // Helper functions + +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ void CheckSQLColumns( SQLHSTMT stmt, const std::wstring& expected_table, const std::wstring& expected_column, const SQLINTEGER& expected_data_type, @@ -125,6 +128,7 @@ void CheckRemoteSQLColumns( expected_octet_char_length, expected_ordinal_position, expected_is_nullable); } +#endif // __linux__ void CheckSQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT idx, const std::string& expected_column_name, @@ -364,7 +368,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 +382,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,54 +389,57 @@ 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, - sizeof(schema_name), table_name, sizeof(table_name), - column_name, sizeof(column_name))); - ValidateFetch(stmt, SQL_NO_DATA); + EXPECT_EQ(SQL_SUCCESS, + SQLColumns(this->stmt, catalog_name, sizeof(catalog_name), schema_name, + sizeof(schema_name), table_name, sizeof(table_name), column_name, + sizeof(column_name))); + ValidateFetch(this->stmt, SQL_NO_DATA); // Sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLColumns(stmt, catalog_name, 0, schema_name, 0, table_name, 0, - column_name, 0)); - ValidateFetch(stmt, SQL_NO_DATA); + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, catalog_name, 0, schema_name, 0, + table_name, 0, column_name, 0)); + ValidateFetch(this->stmt, SQL_NO_DATA); // Names are nulls - EXPECT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, sizeof(catalog_name), nullptr, sizeof(schema_name), - nullptr, sizeof(table_name), nullptr, sizeof(column_name))); - ValidateFetch(stmt, SQL_SUCCESS); + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, sizeof(catalog_name), nullptr, + sizeof(schema_name), nullptr, sizeof(table_name), + nullptr, sizeof(column_name))); + ValidateFetch(this->stmt, SQL_SUCCESS); // Close statement cursor to avoid leaving in an invalid state - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Names are nulls and sizes are zeros EXPECT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); - ValidateFetch(stmt, SQL_SUCCESS); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + ValidateFetch(this->stmt, SQL_SUCCESS); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // mock limitation: SQLite mock server returns 10 for bigint size when spec indicates // should be 19 // DECIMAL_DIGITS should be 0 for bigint type since it is exact // mock limitation: SQLite mock server returns 10 for bigint decimal digits when spec // indicates should be 0 - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -446,15 +451,15 @@ 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 // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"foreignName"), // expected_column @@ -467,15 +472,15 @@ 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 // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"value"), // expected_column @@ -487,15 +492,15 @@ 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 // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"id"), // expected_column @@ -507,15 +512,15 @@ 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 // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"keyName"), // expected_column @@ -528,15 +533,15 @@ 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 // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"value"), // expected_column @@ -548,15 +553,15 @@ 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 // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"foreignId"), // expected_column @@ -568,7 +573,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,16 +588,16 @@ 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Fetch SQLColumn data for 1st column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"bigint_col"), // expected_column @@ -606,15 +611,15 @@ 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 // Check SQLColumn data for 2nd column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"char_col"), // expected_column @@ -627,15 +632,15 @@ 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 // Check SQLColumn data for 3rd column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"varbinary_col"), // expected_column @@ -648,15 +653,15 @@ 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 // Check SQLColumn data for 4th column in AllTypesTable - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"AllTypesTable"), // expected_table std::wstring(L"double_col"), // expected_column @@ -668,13 +673,13 @@ 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 // There should be no more column data - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); DropAllDataTypeTable(); } @@ -686,16 +691,16 @@ 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check SQLColumn data for 1st column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"数据"), // expected_table std::wstring(L"资料"), // expected_column @@ -708,13 +713,13 @@ 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 // There should be no more column data - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); DropUnicodeTable(); } @@ -723,17 +728,17 @@ 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sinteger_max"), // expected_column @@ -745,16 +750,16 @@ 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 // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sbigint_max"), // expected_column @@ -766,15 +771,15 @@ 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 // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"decimal_positive"), // expected_column @@ -786,15 +791,15 @@ 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 // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"float_max"), // expected_column @@ -806,15 +811,15 @@ 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 // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"double_max"), // expected_column @@ -826,15 +831,15 @@ 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 // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"bit_true"), // expected_column @@ -847,7 +852,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 @@ -856,10 +861,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { // DATA_TYPE field // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"date_max"), // expected_column @@ -877,10 +882,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 8th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"time_max"), // expected_column @@ -898,10 +903,10 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // Check 9th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"timestamp_max"), // expected_column @@ -919,24 +924,24 @@ TEST_F(ColumnsRemoteTest, TestSQLColumnsAllTypes) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { // 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sinteger_max"), // expected_column @@ -948,16 +953,16 @@ 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 // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"sbigint_max"), // expected_column @@ -969,15 +974,15 @@ 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 // Check 3rd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"decimal_positive"), // expected_column @@ -989,15 +994,15 @@ 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 // Check 4th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"float_max"), // expected_column @@ -1009,15 +1014,15 @@ 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 // Check 5th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"double_max"), // expected_column @@ -1029,15 +1034,15 @@ 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 // Check 6th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckRemoteSQLColumns(stmt, + CheckRemoteSQLColumns(this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"bit_true"), // expected_column @@ -1050,7 +1055,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 @@ -1058,10 +1063,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { // ODBC ver 2 returns SQL_DATE, SQL_TIME, and SQL_TIMESTAMP in the DATA_TYPE field // Check 7th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"date_max"), // expected_column @@ -1079,10 +1084,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 8th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"time_max"), // expected_column @@ -1100,10 +1105,10 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // Check 9th Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); CheckRemoteSQLColumns( - stmt, + this->stmt, std::wstring(L"$scratch"), // expected_schema std::wstring(L"ODBCTest"), // expected_table std::wstring(L"timestamp_max"), // expected_column @@ -1121,23 +1126,23 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColumnsAllTypesODBCVer2) { std::wstring(L"YES")); // expected_is_nullable // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TEST_F(ColumnsMockTest, TestSQLColumnsColumnPattern) { // 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, + EXPECT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1149,15 +1154,15 @@ 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 // Check 2nd Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"intTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1169,29 +1174,29 @@ 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 // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // Check 1st Column - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckMockSQLColumns(stmt, + CheckMockSQLColumns(this->stmt, std::wstring(L"main"), // expected_catalog std::wstring(L"foreignTable"), // expected_table std::wstring(L"id"), // expected_column @@ -1203,34 +1208,33 @@ 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 // There is no more column - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } +#endif // __linux__ 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, + ASSERT_EQ(SQL_SUCCESS, SQLColumns(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_pattern, SQL_NTS, column_pattern, SQL_NTS)); // There is no column from filter - EXPECT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + EXPECT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(ColumnsTest, SQLColAttributeTestInputData) { - 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); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT idx = 1; SQLWCHAR character_attr[kOdbcBufferSize]; @@ -1238,89 +1242,82 @@ 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(this->stmt, idx, SQL_DESC_NAME, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // All numeric values populated - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, &numeric_attr)); + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, + &numeric_attr)); // Pass null values, driver should not throw error - EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_COLUMN_TABLE_NAME, 0, 0, nullptr, nullptr)); + EXPECT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, idx, SQL_COLUMN_TABLE_NAME, 0, 0, + nullptr, nullptr)); EXPECT_EQ(SQL_SUCCESS, - SQLColAttribute(stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, nullptr)); + SQLColAttribute(this->stmt, idx, SQL_DESC_COUNT, 0, 0, nullptr, nullptr)); } TYPED_TEST(ColumnsTest, SQLColAttributeGetCharacterLen) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLSMALLINT character_attr_len = 0; // Check length of character attribute - ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(stmt, 1, SQL_DESC_BASE_COLUMN_NAME, 0, 0, + ASSERT_EQ(SQL_SUCCESS, SQLColAttribute(this->stmt, 1, SQL_DESC_BASE_COLUMN_NAME, 0, 0, &character_attr_len, nullptr)); EXPECT_EQ(4 * GetSqlWCharSize(), character_attr_len); } 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT invalid_field_id = -100; SQLUSMALLINT idx = 1; SQLWCHAR character_attr[kOdbcBufferSize]; SQLSMALLINT character_attr_len = 0; - 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(this->stmt, idx, invalid_field_id, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor field identifier error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY091); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY091); } TYPED_TEST(ColumnsTest, SQLColAttributeInvalidColId) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLUSMALLINT invalid_col_id = 2; SQLWCHAR character_attr[kOdbcBufferSize]; SQLSMALLINT character_attr_len = 0; - ASSERT_EQ(SQL_ERROR, SQLColAttribute(stmt, invalid_col_id, SQL_DESC_BASE_COLUMN_NAME, - character_attr, std::wcslen(character_attr), - &character_attr_len, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLColAttribute(this->stmt, invalid_col_id, + SQL_DESC_BASE_COLUMN_NAME, character_attr, + kOdbcBufferSize, &character_attr_len, nullptr)); // Verify invalid descriptor index error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); } TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "bigint_col", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1337,7 +1334,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "char_col", // expected_column_name SQL_WVARCHAR, // expected_data_type SQL_WVARCHAR, // expected_concise_type @@ -1354,7 +1351,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "varbinary_col", // expected_column_name SQL_BINARY, // expected_data_type SQL_BINARY, // expected_concise_type @@ -1371,7 +1368,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "double_col", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1397,13 +1394,12 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); - CheckSQLColAttributes(stmt, 1, + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); + CheckSQLColAttributes(this->stmt, 1, "bigint_col", // expected_column_name SQL_BIGINT, // expected_data_type 20, // expected_display_size @@ -1415,7 +1411,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 2, + CheckSQLColAttributes(this->stmt, 2, "char_col", // expected_column_name SQL_WVARCHAR, // expected_data_type 0, // expected_display_size @@ -1427,7 +1423,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 3, + CheckSQLColAttributes(this->stmt, 3, "varbinary_col", // expected_column_name SQL_BINARY, // expected_data_type 0, // expected_display_size @@ -1439,7 +1435,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAllTypes) { SQL_PRED_NONE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 4, + CheckSQLColAttributes(this->stmt, 4, "double_col", // expected_column_name SQL_DOUBLE, // expected_data_type 24, // expected_display_size @@ -1458,14 +1454,13 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type SQL_INTEGER, // expected_concise_type @@ -1482,7 +1477,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1499,7 +1494,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type SQL_DECIMAL, // expected_concise_type @@ -1516,7 +1511,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type SQL_FLOAT, // expected_concise_type @@ -1533,7 +1528,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 5, + CheckSQLColAttribute(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1550,7 +1545,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 6, + CheckSQLColAttribute(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type SQL_BIT, // expected_concise_type @@ -1567,7 +1562,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 7, + CheckSQLColAttribute(this->stmt, 7, "date_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_DATE, // expected_concise_type @@ -1584,7 +1579,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 8, + CheckSQLColAttribute(this->stmt, 8, "time_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_TIME, // expected_concise_type @@ -1601,7 +1596,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 9, + CheckSQLColAttribute(this->stmt, 9, "timestamp_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TYPE_TIMESTAMP, // expected_concise_type @@ -1623,14 +1618,13 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttribute(stmt, 1, + CheckSQLColAttribute(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type SQL_INTEGER, // expected_concise_type @@ -1647,7 +1641,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 2, + CheckSQLColAttribute(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type SQL_BIGINT, // expected_concise_type @@ -1664,7 +1658,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 3, + CheckSQLColAttribute(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type SQL_DECIMAL, // expected_concise_type @@ -1681,7 +1675,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 4, + CheckSQLColAttribute(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type SQL_FLOAT, // expected_concise_type @@ -1698,7 +1692,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 5, + CheckSQLColAttribute(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type SQL_DOUBLE, // expected_concise_type @@ -1715,7 +1709,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 6, + CheckSQLColAttribute(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type SQL_BIT, // expected_concise_type @@ -1732,7 +1726,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 7, + CheckSQLColAttribute(this->stmt, 7, "date_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_DATE, // expected_concise_type @@ -1749,7 +1743,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 8, + CheckSQLColAttribute(this->stmt, 8, "time_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TIME, // expected_concise_type @@ -1766,7 +1760,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributeAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttribute(stmt, 9, + CheckSQLColAttribute(this->stmt, 9, "timestamp_max", // expected_column_name SQL_DATETIME, // expected_data_type SQL_TIMESTAMP, // expected_concise_type @@ -1788,14 +1782,13 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckSQLColAttributes(stmt, 1, + CheckSQLColAttributes(this->stmt, 1, "sinteger_max", // expected_column_name SQL_INTEGER, // expected_data_type 11, // expected_display_size @@ -1807,7 +1800,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 2, + CheckSQLColAttributes(this->stmt, 2, "sbigint_max", // expected_column_name SQL_BIGINT, // expected_data_type 20, // expected_display_size @@ -1819,7 +1812,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 3, + CheckSQLColAttributes(this->stmt, 3, "decimal_positive", // expected_column_name SQL_DECIMAL, // expected_data_type 40, // expected_display_size @@ -1831,7 +1824,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 4, + CheckSQLColAttributes(this->stmt, 4, "float_max", // expected_column_name SQL_FLOAT, // expected_data_type 24, // expected_display_size @@ -1843,7 +1836,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 5, + CheckSQLColAttributes(this->stmt, 5, "double_max", // expected_column_name SQL_DOUBLE, // expected_data_type 24, // expected_display_size @@ -1855,7 +1848,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_FALSE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 6, + CheckSQLColAttributes(this->stmt, 6, "bit_true", // expected_column_name SQL_BIT, // expected_data_type 1, // expected_display_size @@ -1867,7 +1860,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 7, + CheckSQLColAttributes(this->stmt, 7, "date_max", // expected_column_name SQL_DATE, // expected_data_type 10, // expected_display_size @@ -1879,7 +1872,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 8, + CheckSQLColAttributes(this->stmt, 8, "time_max", // expected_column_name SQL_TIME, // expected_data_type 12, // expected_display_size @@ -1891,7 +1884,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesAllTypes) { SQL_SEARCHABLE, // expected_searchable SQL_TRUE); // expected_unsigned_column - CheckSQLColAttributes(stmt, 9, + CheckSQLColAttributes(this->stmt, 9, "timestamp_max", // expected_column_name SQL_TIMESTAMP, // expected_data_type 23, // expected_display_size @@ -1911,11 +1904,11 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeCaseSensitive) { std::wstring wsql = this->GetQueryAllDataTypes(); // Int column SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_CASE_SENSITIVE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Varchar column - GetSQLColAttributeNumeric(stmt, wsql, 28, SQL_DESC_CASE_SENSITIVE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 28, SQL_DESC_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); } @@ -1928,11 +1921,11 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesCaseSensitive) { std::wstring wsql = this->GetQueryAllDataTypes(); // Int column SQLLEN value; - GetSQLColAttributesNumeric(stmt, wsql, 1, SQL_COLUMN_CASE_SENSITIVE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Varchar column - GetSQLColAttributesNumeric(stmt, wsql, 28, SQL_COLUMN_CASE_SENSITIVE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 28, SQL_COLUMN_CASE_SENSITIVE, &value); ASSERT_EQ(SQL_FALSE, value); } #endif // __APPLE__ @@ -1943,7 +1936,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeUniqueValue) { std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_AUTO_UNIQUE_VALUE, &value); ASSERT_EQ(SQL_FALSE, value); DropAllDataTypeTable(); @@ -1958,7 +1951,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesAutoIncrement) { std::wstring wsql = L"SELECT * from AllTypesTable;"; SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_COLUMN_AUTO_INCREMENT, &value); ASSERT_EQ(SQL_FALSE, value); DropAllDataTypeTable(); @@ -1970,7 +1963,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeBaseTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_BASE_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -1984,7 +1977,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -1998,7 +1991,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeCatalogName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2009,7 +2002,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeCatalogName) { std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_CATALOG_NAME, value); ASSERT_EQ(std::wstring(L""), value); } @@ -2023,7 +2016,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesQualifierName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2034,7 +2027,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesQualifierName) { // Tests ODBC 2.0 API SQLColAttributes std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_COLUMN_QUALIFIER_NAME, value); ASSERT_EQ(std::wstring(L""), value); } #endif // __APPLE__ @@ -2043,7 +2036,7 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeCount) { std::wstring wsql = this->GetQueryAllDataTypes(); // Pass 0 as column number, driver should ignore it SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 0, SQL_DESC_COUNT, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 0, SQL_DESC_COUNT, &value); ASSERT_EQ(32, value); } @@ -2051,14 +2044,14 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeLocalTypeName) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server doesn't have local type name std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); ASSERT_EQ(std::wstring(L""), value); } TEST_F(ColumnsRemoteTest, TestSQLColAttributeLocalTypeName) { std::wstring wsql = this->GetQueryAllDataTypes(); std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_DESC_LOCAL_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); } @@ -2068,7 +2061,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeSchemaName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2081,7 +2074,7 @@ TEST_F(ColumnsRemoteTest, TestSQLColAttributeSchemaName) { // Remote server limitation: doesn't return schema name, expected schema name is // $scratch std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_SCHEMA_NAME, value); ASSERT_EQ(std::wstring(L""), value); } @@ -2094,7 +2087,7 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesOwnerName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't have schemas std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); ASSERT_EQ(std::wstring(L""), value); DropAllDataTypeTable(); @@ -2107,7 +2100,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesOwnerName) { // Remote server limitation: doesn't return schema name, expected schema name is // $scratch std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_OWNER_NAME, value); ASSERT_EQ(std::wstring(L""), value); } #endif // __APPLE__ @@ -2117,7 +2110,7 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTableName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TABLE_NAME, value); ASSERT_EQ(std::wstring(L"AllTypesTable"), value); DropAllDataTypeTable(); @@ -2128,13 +2121,13 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(stmt, L"", 2, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributeString(stmt, L"", 3, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributeString(stmt, L"", 4, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); DropAllDataTypeTable(); @@ -2143,23 +2136,23 @@ TEST_F(ColumnsMockTest, TestSQLColAttributeTypeName) { TEST_F(ColumnsRemoteTest, TestSQLColAttributeTypeName) { std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributeString(stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, wsql, 1, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributeString(stmt, L"", 2, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 2, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributeString(stmt, L"", 3, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 3, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributeString(stmt, L"", 4, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 4, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributeString(stmt, L"", 5, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 5, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributeString(stmt, L"", 6, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 6, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributeString(stmt, L"", 7, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 7, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributeString(stmt, L"", 8, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 8, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributeString(stmt, L"", 9, SQL_DESC_TYPE_NAME, value); + GetSQLColAttributeString(this->stmt, L"", 9, SQL_DESC_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); } @@ -2172,13 +2165,13 @@ TEST_F(ColumnsOdbcV2MockTest, TestSQLColAttributesTypeName) { std::wstring wsql = L"SELECT * from AllTypesTable;"; // Mock server doesn't return data source-dependent data type name std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"WVARCHAR"), value); - GetSQLColAttributesString(stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BINARY"), value); - GetSQLColAttributesString(stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); DropAllDataTypeTable(); @@ -2188,23 +2181,23 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { // Tests ODBC 2.0 API SQLColAttributes std::wstring wsql = L"SELECT * from $scratch.ODBCTest;"; std::wstring value; - GetSQLColAttributesString(stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, wsql, 1, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"INTEGER"), value); - GetSQLColAttributesString(stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 2, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BIGINT"), value); - GetSQLColAttributesString(stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 3, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DECIMAL"), value); - GetSQLColAttributesString(stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 4, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"FLOAT"), value); - GetSQLColAttributesString(stmt, L"", 5, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 5, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DOUBLE"), value); - GetSQLColAttributesString(stmt, L"", 6, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 6, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"BOOLEAN"), value); - GetSQLColAttributesString(stmt, L"", 7, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 7, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"DATE"), value); - GetSQLColAttributesString(stmt, L"", 8, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 8, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIME"), value); - GetSQLColAttributesString(stmt, L"", 9, SQL_COLUMN_TYPE_NAME, value); + GetSQLColAttributesString(this->stmt, L"", 9, SQL_COLUMN_TYPE_NAME, value); ASSERT_EQ(std::wstring(L"TIMESTAMP"), value); } #endif // __APPLE__ @@ -2212,7 +2205,7 @@ TEST_F(ColumnsOdbcV2RemoteTest, TestSQLColAttributesTypeName) { TYPED_TEST(ColumnsTest, TestSQLColAttributeUnnamed) { std::wstring wsql = this->GetQueryAllDataTypes(); SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_UNNAMED, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UNNAMED, &value); ASSERT_EQ(SQL_NAMED, value); } @@ -2220,7 +2213,7 @@ TYPED_TEST(ColumnsTest, TestSQLColAttributeUpdatable) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server and remote server do not return updatable information SQLLEN value; - GetSQLColAttributeNumeric(stmt, wsql, 1, SQL_DESC_UPDATABLE, &value); + GetSQLColAttributeNumeric(this->stmt, wsql, 1, SQL_DESC_UPDATABLE, &value); ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); } @@ -2231,7 +2224,7 @@ TYPED_TEST(ColumnsOdbcV2Test, TestSQLColAttributesUpdatable) { std::wstring wsql = this->GetQueryAllDataTypes(); // Mock server and remote server do not return updatable information SQLLEN value; - GetSQLColAttributesNumeric(stmt, wsql, 1, SQL_COLUMN_UPDATABLE, &value); + GetSQLColAttributesNumeric(this->stmt, wsql, 1, SQL_COLUMN_UPDATABLE, &value); ASSERT_EQ(SQL_ATTR_READWRITE_UNKNOWN, value); } #endif // __APPLE__ @@ -2239,47 +2232,45 @@ 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Invalid descriptor index - Bookmarks are not supported - EXPECT_EQ(SQL_ERROR, - SQLDescribeCol(stmt, bookmark_column, column_name, buf_char_len, &name_length, - &data_type, &column_size, &decimal_digits, &nullable)); + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, bookmark_column, column_name, + buf_char_len, &name_length, &data_type, + &column_size, &decimal_digits, &nullable)); #ifdef __APPLE__ // non-standard odbc error code for invalid column index - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1002); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); #endif // __APPLE__ // Invalid descriptor index - index out of range - EXPECT_EQ(SQL_ERROR, SQLDescribeCol(stmt, out_of_range_column, column_name, + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, out_of_range_column, column_name, buf_char_len, &name_length, &data_type, &column_size, &decimal_digits, &nullable)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); // Invalid descriptor index - index out of range - EXPECT_EQ(SQL_ERROR, - SQLDescribeCol(stmt, negative_column, column_name, buf_char_len, &name_length, - &data_type, &column_size, &decimal_digits, &nullable)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState07009); + EXPECT_EQ(SQL_ERROR, SQLDescribeCol(this->stmt, negative_column, column_name, + buf_char_len, &name_length, &data_type, + &column_size, &decimal_digits, &nullable)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState07009); DropTestTable(); } @@ -2289,8 +2280,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 +2291,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, @@ -2342,17 +2309,17 @@ TEST_F(ColumnsMockTest, SQLDescribeColQueryAllDataTypesMetadata) { SQL_WVARCHAR, SQL_WVARCHAR}; ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2338,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 +2349,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, @@ -2430,18 +2373,18 @@ TEST_F(ColumnsRemoteTest, SQLDescribeColQueryAllDataTypesMetadata) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 23, 23}; ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2405,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,36 +2413,30 @@ 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2456,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,36 +2464,30 @@ 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2508,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,28 +2516,25 @@ 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2557,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,27 +2565,24 @@ 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)); - - SQLWCHAR expected_column_name[] = L"资料"; - SQLSMALLINT expected_column_data_type = SQL_WVARCHAR; - SQLULEN expected_column_size = 0; + ASSIGN_SQLWCHAR_ARR_AND_LEN(sql_query, L"SELECT * from 数据 LIMIT 1;"); - ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(stmt, sql_query, query_length)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, - SQLDescribeCol(stmt, column_index, column_name, buf_char_len, &name_length, - &column_data_type, &column_size, &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(name_length, wcslen(expected_column_name)); + std::wstring expected_column_name_wstr = std::wstring(L"资料"); + size_t expected_column_name_len = expected_column_name_wstr.length(); std::wstring returned(column_name, column_name + name_length); - EXPECT_EQ(returned, expected_column_name); - EXPECT_EQ(column_data_type, expected_column_data_type); - EXPECT_EQ(column_size, expected_column_size); + EXPECT_EQ(expected_column_name_wstr, returned); + EXPECT_EQ(expected_column_name_len, name_length); + EXPECT_EQ(SQL_WVARCHAR, column_data_type); + EXPECT_EQ(0, column_size); EXPECT_EQ(0, decimal_digits); EXPECT_EQ(SQL_NULLABLE, nullable); @@ -2670,8 +2591,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 +2599,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, @@ -2705,16 +2613,16 @@ TYPED_TEST(ColumnsTest, SQLColumnsGetMetadataBySQLDescribeCol) { 2, 2, 1024, 1024, 2, 2, 4, 4, 1024}; ASSERT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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 +2641,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 +2649,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, @@ -2768,16 +2675,16 @@ TYPED_TEST(ColumnsOdbcV2Test, SQLColumnsGetMetadataBySQLDescribeColODBCVer2) { 2, 2, 1024, 1024, 2, 2, 4, 4, 1024}; ASSERT_EQ(SQL_SUCCESS, - SQLColumns(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + SQLColumns(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc index dbf2fbb74f8f..c2391f071424 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_attr_test.cc @@ -33,75 +33,85 @@ using TestTypes = ::testing::Types; TYPED_TEST_SUITE(ConnectionAttributeTest, TestTypes); +template +class ConnectionAttributePreConnectTest : public T {}; + +using TestTypesHandle = ::testing::Types; +TYPED_TEST_SUITE(ConnectionAttributePreConnectTest, TestTypesHandle); + #ifdef SQL_ATTR_ASYNC_DBC_EVENT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAsyncDbcEventUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, 0, 0)); // Driver Manager on Windows returns error code HY118 - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY118); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY118); } #endif #ifdef SQL_ATTR_ASYNC_ENABLE TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncEnableUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCALLBACK TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcCallbackUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_DBC_PCONTEXT TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAyncDbcPcContextUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAutoIpdReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_AUTO_IPD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionDeadReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_DEAD, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #ifdef SQL_ATTR_DBC_INFO_TOKEN TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrDbcInfoTokenUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #endif TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrEnlistInDtcUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } -TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { - this->AllocEnvConnHandles(); +TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrOdbcCursorsDMOnly) { + SQLHENV test_env = SQL_NULL_HENV; + SQLHDBC test_conn = SQL_NULL_HDBC; + this->AllocEnvConnHandles(test_env, test_conn); // Verify DM-only attribute is settable via Driver Manager ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_ODBC_CURSORS, + SQLSetConnectAttr(test_conn, SQL_ATTR_ODBC_CURSORS, reinterpret_cast(SQL_CUR_USE_DRIVER), 0)); std::string connect_str = this->GetConnectionString(); - this->ConnectWithString(connect_str); + this->ConnectWithString(connect_str, test_conn); + this->Disconnect(test_env, test_conn); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { // Verify read-only attribute cannot be set - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_QUIET_MODE, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } // iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACE @@ -109,83 +119,86 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrQuietModeReadOnly) { TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTraceDMOnly) { // Verify DM-only attribute is settable via Driver Manager ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_TRACE, + SQLSetConnectAttr(this->conn, SQL_ATTR_TRACE, reinterpret_cast(SQL_OPT_TRACE_OFF), 0)); } #endif // __APPLE__ -TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTracefileDMOnly) { +TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrTracefileDMOnly) { // Verify DM-only attribute is handled by Driver Manager // Use placeholder value as we want the call to fail, or else // the driver manager will produce a trace file. std::wstring trace_file = L"invalid/file/path"; std::vector trace_file0(trace_file.begin(), trace_file.end()); - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + +#ifdef _WIN32 + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], static_cast(trace_file0.size()))); -#ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); -#else - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY000); -#endif // __APPLE__ + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY000); +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, + SQLSetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, &trace_file0[0], + static_cast(trace_file0.size()))); +#endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateLabDMOnly) { // Verify DM-only attribute is handled by Driver Manager - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, 0, 0)); // Checks for invalid argument return error -#ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); -#else - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY024); -#endif // __APPLE__ +#ifdef _WIN32 + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY024); +#else // Mac & Linux + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); +#endif } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTranslateOptionUnsupported) { - ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLSetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrTxnIsolationUnsupported) { ASSERT_EQ(SQL_ERROR, - SQLSetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, + SQLSetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, reinterpret_cast(SQL_TXN_READ_UNCOMMITTED), 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_DBC_INFO_TOKEN TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrDbcInfoTokenSetOnly) { // Verify that set-only attribute cannot be read SQLPOINTER ptr = NULL; - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY092); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_DBC_INFO_TOKEN, ptr, 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY092); } #endif -// iODBC does not treat SQL_ATTR_ODBC_CURSORS as DM-only -#ifndef __APPLE__ +// Driver Manager behavior tests for Windows only. +#ifdef _WIN32 TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrOdbcCursorsDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLULEN cursor_attr; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ODBC_CURSORS, &cursor_attr, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_ODBC_CURSORS, + &cursor_attr, 0, nullptr)); EXPECT_EQ(SQL_CUR_USE_DRIVER, cursor_attr); } -// iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACE TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLUINTEGER trace; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_TRACE, &trace, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_TRACE, &trace, 0, nullptr)); EXPECT_EQ(SQL_OPT_TRACE_OFF, trace); } -// iODBC needs to be compiled with tracing enabled to handle SQL_ATTR_TRACEFILE TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { // Verify that DM-only attribute is handled by driver manager SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_TRACEFILE, out_str, + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_TRACEFILE, out_str, kOdbcBufferSize, &out_str_len)); // Length is returned in bytes for SQLGetConnectAttr, // we want the number of characters @@ -194,38 +207,44 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTraceFileDMOnly) { ODBC::SqlWcharToString(out_str, static_cast(out_str_len)); EXPECT_FALSE(out_connection_string.empty()); } -#endif // __APPLE__ +#endif // _WIN32 TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateLibUnsupported) { SQLWCHAR out_str[kOdbcBufferSize]; SQLINTEGER out_str_len; - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TRANSLATE_LIB, out_str, + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_LIB, out_str, kOdbcBufferSize, &out_str_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTranslateOptionUnsupported) { SQLINTEGER option; - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_TRANSLATE_OPTION, &option, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TRANSLATE_OPTION, &option, + 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrTxnIsolationUnsupported) { SQLINTEGER isolation; - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, &isolation, 0, nullptr)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHYC00); + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, &isolation, + 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHYC00); } #ifdef SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcFunctionsEnableUnsupported) { - // Verifies that the Windows driver manager returns HY114 for unsupported functionality SQLUINTEGER enable; - ASSERT_EQ(SQL_ERROR, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY114); +# ifdef _WIN32 + // Verifies that the Windows driver manager returns HY114 for unsupported functionality + ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, + &enable, 0, 0)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY114); +# else // Mac & Linux + ASSERT_EQ( + SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, &enable, 0, 0)); +# endif } #endif @@ -235,7 +254,7 @@ TYPED_TEST(ConnectionAttributeTest, TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcEventDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_EVENT, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -244,7 +263,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcEventDefault) { TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcallbackDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCALLBACK, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -253,7 +272,7 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcallbackDefaul TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcontextDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_DBC_PCONTEXT, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } #endif @@ -261,33 +280,35 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncDbcPcontextDefault TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAsyncEnableDefault) { SQLULEN enable; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ASYNC_ENABLE, &enable, 0, nullptr)); EXPECT_EQ(SQL_ASYNC_ENABLE_OFF, enable); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutoIpdDefault) { SQLUINTEGER ipd; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_AUTO_IPD, &ipd, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_AUTO_IPD, &ipd, 0, nullptr)); EXPECT_EQ(static_cast(SQL_FALSE), ipd); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrAutocommitDefault) { SQLUINTEGER auto_commit; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_AUTOCOMMIT, &auto_commit, 0, nullptr)); EXPECT_EQ(SQL_AUTOCOMMIT_ON, auto_commit); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrEnlistInDtcDefault) { SQLPOINTER ptr = NULL; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ENLIST_IN_DTC, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } TYPED_TEST(ConnectionAttributeTest, TestSQLGetConnectAttrQuietModeDefault) { HWND ptr = NULL; - ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(conn, SQL_ATTR_QUIET_MODE, ptr, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetConnectAttr(this->conn, SQL_ATTR_QUIET_MODE, ptr, 0, nullptr)); EXPECT_EQ(reinterpret_cast(NULL), ptr); } @@ -297,40 +318,40 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrAccessModeValid) { // Check default value first SQLUINTEGER mode = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); ASSERT_EQ(SQL_SUCCESS, - SQLSetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, reinterpret_cast(SQL_MODE_READ_WRITE), 0)); mode = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, &mode, 0, nullptr)); EXPECT_EQ(SQL_MODE_READ_WRITE, mode); // Attempt to set to SQL_MODE_READ_ONLY, driver should return warning and not error EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLSetConnectAttr(conn, SQL_ATTR_ACCESS_MODE, + SQLSetConnectAttr(this->conn, SQL_ATTR_ACCESS_MODE, reinterpret_cast(SQL_MODE_READ_ONLY), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); } TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrConnectionTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + &timeout, 0, nullptr)); EXPECT_EQ(0, timeout); - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, reinterpret_cast(42), 0)); timeout = -1; - ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_CONNECTION_TIMEOUT, &timeout, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetConnectAttr(this->conn, SQL_ATTR_CONNECTION_TIMEOUT, + &timeout, 0, nullptr)); EXPECT_EQ(42, timeout); } @@ -338,41 +359,57 @@ TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrLoginTimeoutValid) { // Check default value first SQLUINTEGER timeout = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); EXPECT_EQ(0, timeout); - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast(42), 0)); timeout = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_LOGIN_TIMEOUT, &timeout, 0, nullptr)); EXPECT_EQ(42, timeout); } +#ifdef __linux__ +// On Linux, SQL_ATTR_PACKET_SIZE can only be set before connection +// which is why use a different test fixture for Linux. +TYPED_TEST(ConnectionAttributePreConnectTest, TestSQLSetConnectAttrPacketSizeValid) { +#else // Windows & Mac TYPED_TEST(ConnectionAttributeTest, TestSQLSetConnectAttrPacketSizeValid) { - // The driver always returns 0. PACKET_SIZE value is unused by the driver. - +#endif // Check default value first SQLUINTEGER size = -1; +#ifdef __linux__ + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState08003); +#else // Windows & Mac ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); EXPECT_EQ(0, size); +#endif - ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, + ASSERT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(0), 0)); size = -1; ASSERT_EQ(SQL_SUCCESS, - SQLGetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); + SQLGetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, &size, 0, nullptr)); EXPECT_EQ(0, size); - // Attempt to set to non-zero value, driver should return warning and not error - EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(conn, SQL_ATTR_PACKET_SIZE, + // Attempt to set to non-zero value, +#ifdef __linux__ + EXPECT_EQ(SQL_SUCCESS, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, + reinterpret_cast(2), 0)); +#else // Windows & Mac + // driver should return warning and not error + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, SQLSetConnectAttr(this->conn, SQL_ATTR_PACKET_SIZE, reinterpret_cast(2), 0)); // Verify warning status - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01S02); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01S02); +#endif } } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc index e39433fa979f..a1116bb1c47e 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_info_test.cc @@ -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,14 +75,14 @@ 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, - SQLGetInfo(conn, SQL_INTEGRITY, value, info_len, &message_length)); + SQLGetInfo(this->conn, SQL_INTEGRITY, value, info_len, &message_length)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01004); EXPECT_GT(message_length, 0); } @@ -90,7 +90,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTruncation) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoActiveEnvironments) { SQLUSMALLINT value; - GetInfo(conn, SQL_ACTIVE_ENVIRONMENTS, &value); + GetInfo(this->conn, SQL_ACTIVE_ENVIRONMENTS, &value); EXPECT_EQ(static_cast(0), value); } @@ -98,7 +98,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoActiveEnvironments) { #ifdef SQL_ASYNC_DBC_FUNCTIONS TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncDbcFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_DBC_FUNCTIONS, &value); + GetInfo(this->conn, SQL_ASYNC_DBC_FUNCTIONS, &value); EXPECT_EQ(static_cast(SQL_ASYNC_DBC_NOT_CAPABLE), value); } @@ -106,7 +106,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncDbcFunctions) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncMode) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_MODE, &value); + GetInfo(this->conn, SQL_ASYNC_MODE, &value); EXPECT_EQ(static_cast(SQL_AM_NONE), value); } @@ -114,7 +114,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncMode) { #ifdef SQL_ASYNC_NOTIFICATION TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncNotification) { SQLUINTEGER value; - GetInfo(conn, SQL_ASYNC_NOTIFICATION, &value); + GetInfo(this->conn, SQL_ASYNC_NOTIFICATION, &value); EXPECT_EQ(static_cast(SQL_ASYNC_NOTIFICATION_NOT_CAPABLE), value); } @@ -122,43 +122,48 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAsyncNotification) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchRowCount) { SQLUINTEGER value; - GetInfo(conn, SQL_BATCH_ROW_COUNT, &value); + GetInfo(this->conn, SQL_BATCH_ROW_COUNT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoBatchSupport) { SQLUINTEGER value; - GetInfo(conn, SQL_BATCH_SUPPORT, &value); + GetInfo(this->conn, SQL_BATCH_SUPPORT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DATA_SOURCE_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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 +// GH-49782: TODO Disabled on Linux until SQL_DRIVER_AWARE_POOLING_SUPPORTED is +// implemented in the driver. +# ifndef __linux__ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverAwarePoolingSupported) { // According to Microsoft documentation, ODBC driver does not need to implement // SQL_DRIVER_AWARE_POOLING_SUPPORTED and the Driver Manager will ignore the // driver's return value for it. SQLUINTEGER value; - GetInfo(conn, SQL_DRIVER_AWARE_POOLING_SUPPORTED, &value); + GetInfo(this->conn, SQL_DRIVER_AWARE_POOLING_SUPPORTED, &value); EXPECT_EQ(static_cast(SQL_DRIVER_AWARE_POOLING_NOT_CAPABLE), value); } -#endif +# endif // __linux__ +#endif // SQL_DRIVER_AWARE_POOLING_SUPPORTED // These information types are implemented by the Driver Manager alone. TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdbc) { // Value returned from driver manager is the connection address SQLULEN value; - GetInfo(conn, SQL_DRIVER_HDBC, &value); + GetInfo(this->conn, SQL_DRIVER_HDBC, &value); EXPECT_GT(value, static_cast(0)); } @@ -168,11 +173,12 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdesc) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); // Value returned from driver manager is the desc address SQLHDESC local_desc = descriptor; - ASSERT_EQ(SQL_SUCCESS, SQLGetInfo(conn, SQL_HANDLE_DESC, &local_desc, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetInfo(this->conn, SQL_HANDLE_DESC, &local_desc, 0, nullptr)); EXPECT_GT(local_desc, static_cast(0)); // Free descriptor handle @@ -183,7 +189,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHdesc) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHenv) { // Value returned from driver manager is the env address SQLULEN value; - GetInfo(conn, SQL_DRIVER_HENV, &value); + GetInfo(this->conn, SQL_DRIVER_HENV, &value); EXPECT_GT(value, static_cast(0)); } @@ -191,7 +197,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHenv) { // These information types are implemented by the Driver Manager alone. TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHlib) { SQLULEN value; - GetInfo(conn, SQL_DRIVER_HLIB, &value); + GetInfo(this->conn, SQL_DRIVER_HLIB, &value); EXPECT_GT(value, static_cast(0)); } @@ -199,77 +205,81 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHlib) { // These information types are implemented by the Driver Manager alone. TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverHstmt) { // Value returned from driver manager is the stmt address - SQLHSTMT local_stmt = stmt; - ASSERT_EQ(SQL_SUCCESS, SQLGetInfo(conn, SQL_DRIVER_HSTMT, &local_stmt, 0, nullptr)); + SQLHSTMT local_stmt = this->stmt; + ASSERT_EQ(SQL_SUCCESS, + SQLGetInfo(this->conn, SQL_DRIVER_HSTMT, &local_stmt, 0, nullptr)); EXPECT_GT(local_stmt, static_cast(0)); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDriverName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DRIVER_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDynamicCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_DYNAMIC_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoForwardOnlyCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(SQL_CA1_NEXT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoForwardOnlyCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(SQL_CA2_READ_ONLY_CONCURRENCY), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoFileUsage) { SQLUSMALLINT value; - GetInfo(conn, SQL_FILE_USAGE, &value); + GetInfo(this->conn, SQL_FILE_USAGE, &value); EXPECT_EQ(static_cast(SQL_FILE_NOT_SUPPORTED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoGetDataExtensions) { SQLUINTEGER value; - GetInfo(conn, SQL_GETDATA_EXTENSIONS, &value); + GetInfo(this->conn, SQL_GETDATA_EXTENSIONS, &value); EXPECT_EQ(static_cast(SQL_GD_ANY_COLUMN | SQL_GD_ANY_ORDER), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaViews) { SQLUINTEGER value; - GetInfo(conn, SQL_INFO_SCHEMA_VIEWS, &value); + GetInfo(this->conn, SQL_INFO_SCHEMA_VIEWS, &value); EXPECT_EQ(static_cast(SQL_ISV_TABLES | SQL_ISV_COLUMNS | SQL_ISV_VIEWS), value); @@ -277,42 +287,42 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSchemaViews) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeysetCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_KEYSET_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_KEYSET_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoKeysetCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_KEYSET_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_KEYSET_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxAsyncConcurrentStatements) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_ASYNC_CONCURRENT_STATEMENTS, &value); + GetInfo(this->conn, SQL_MAX_ASYNC_CONCURRENT_STATEMENTS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxConcurrentActivities) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CONCURRENT_ACTIVITIES, &value); + GetInfo(this->conn, SQL_MAX_CONCURRENT_ACTIVITIES, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxDriverConnections) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_DRIVER_CONNECTIONS, &value); + GetInfo(this->conn, SQL_MAX_DRIVER_CONNECTIONS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoOdbcInterfaceConformance) { SQLUINTEGER value; - GetInfo(conn, SQL_ODBC_INTERFACE_CONFORMANCE, &value); + GetInfo(this->conn, SQL_ODBC_INTERFACE_CONFORMANCE, &value); EXPECT_EQ(static_cast(SQL_OIC_CORE), value); } @@ -320,61 +330,68 @@ 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(this->conn, SQL_ODBC_VER, value); + + std::wstring result = ConvertToWString(value); -#ifdef __APPLE__ - EXPECT_STREQ(static_cast(L"03.52.0000"), value); -#else - EXPECT_STREQ(static_cast(L"03.80.0000"), value); +#if defined(__APPLE__) + EXPECT_EQ(std::wstring(L"03.52.0000"), result); +#elif defined(__linux__) + EXPECT_EQ(std::wstring(L"03.52"), result); +#else // WINDOWS + EXPECT_EQ(std::wstring(L"03.80.0000"), result); #endif // __APPLE__ } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArrayRowCounts) { SQLUINTEGER value; - GetInfo(conn, SQL_PARAM_ARRAY_ROW_COUNTS, &value); + GetInfo(this->conn, SQL_PARAM_ARRAY_ROW_COUNTS, &value); EXPECT_EQ(static_cast(SQL_PARC_NO_BATCH), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoParamArraySelects) { SQLUINTEGER value; - GetInfo(conn, SQL_PARAM_ARRAY_SELECTS, &value); + GetInfo(this->conn, SQL_PARAM_ARRAY_SELECTS, &value); EXPECT_EQ(static_cast(SQL_PAS_NO_SELECT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoRowUpdates) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ROW_UPDATES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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(this->conn, SQL_SERVER_NAME, value); - EXPECT_GT(wcslen(value), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes1) { SQLUINTEGER value; - GetInfo(conn, SQL_STATIC_CURSOR_ATTRIBUTES1, &value); + GetInfo(this->conn, SQL_STATIC_CURSOR_ATTRIBUTES1, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoStaticCursorAttributes2) { SQLUINTEGER value; - GetInfo(conn, SQL_STATIC_CURSOR_ATTRIBUTES2, &value); + GetInfo(this->conn, SQL_STATIC_CURSOR_ATTRIBUTES2, &value); EXPECT_EQ(static_cast(0), value); } @@ -382,193 +399,209 @@ 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(this->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(this->conn, SQL_DBMS_NAME, value); - EXPECT_GT(wcslen(value), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDbmsVer) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DBMS_VER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->conn, SQL_DBMS_VER, value); - EXPECT_GT(wcslen(value), 0); + std::wstring result = ConvertToWString(value); + EXPECT_GT(result.length(), 0); } // Data Source Information TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAccessibleProcedures) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ACCESSIBLE_PROCEDURES, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_BOOKMARK_PERSISTENCE, &value); + GetInfo(this->conn, SQL_BOOKMARK_PERSISTENCE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_CATALOG_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_CONCAT_NULL_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CONCAT_NULL_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_NULL), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorCommitBehavior) { SQLUSMALLINT value; - GetInfo(conn, SQL_CURSOR_COMMIT_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CURSOR_COMMIT_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_CLOSE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorRollbackBehavior) { SQLUSMALLINT value; - GetInfo(conn, SQL_CURSOR_ROLLBACK_BEHAVIOR, &value); + GetInfo(this->conn, SQL_CURSOR_ROLLBACK_BEHAVIOR, &value); EXPECT_EQ(static_cast(SQL_CB_CLOSE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCursorSensitivity) { SQLUINTEGER value; - GetInfo(conn, SQL_CURSOR_SENSITIVITY, &value); + GetInfo(this->conn, SQL_CURSOR_SENSITIVITY, &value); EXPECT_EQ(static_cast(SQL_UNSPECIFIED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDataSourceReadOnly) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DATA_SOURCE_READ_ONLY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_DEFAULT_TXN_ISOLATION, &value); + GetInfo(this->conn, SQL_DEFAULT_TXN_ISOLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDescribeParameter) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_DESCRIBE_PARAMETER, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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(this->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(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_NULL_COLLATION, &value); + GetInfo(this->conn, SQL_NULL_COLLATION, &value); EXPECT_EQ(static_cast(SQL_NC_START), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoProcedureTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_PROCEDURE_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_SCROLL_OPTIONS, &value); + GetInfo(this->conn, SQL_SCROLL_OPTIONS, &value); EXPECT_EQ(static_cast(SQL_SO_FORWARD_ONLY), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTableTerm) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_TABLE_TERM, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_TXN_CAPABLE, &value); + GetInfo(this->conn, SQL_TXN_CAPABLE, &value); EXPECT_EQ(static_cast(SQL_TC_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTxnIsolationOption) { SQLUINTEGER value; - GetInfo(conn, SQL_TXN_ISOLATION_OPTION, &value); + GetInfo(this->conn, SQL_TXN_ISOLATION_OPTION, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoUserName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_USER_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->conn, SQL_USER_NAME, value); - EXPECT_STREQ(static_cast(L""), value); + std::wstring result = ConvertToWString(value); + EXPECT_EQ(std::wstring(L""), result); } // Supported SQL TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAggregateFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_AGGREGATE_FUNCTIONS, &value); + GetInfo(this->conn, SQL_AGGREGATE_FUNCTIONS, &value); EXPECT_EQ(value, static_cast(SQL_AF_ALL | SQL_AF_AVG | SQL_AF_COUNT | SQL_AF_DISTINCT | SQL_AF_MAX | SQL_AF_MIN | @@ -577,14 +610,14 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAggregateFunctions) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_ALTER_DOMAIN, &value); + GetInfo(this->conn, SQL_ALTER_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { SQLUINTEGER value; - GetInfo(conn, SQL_ALTER_TABLE, &value); + GetInfo(this->conn, SQL_ALTER_TABLE, &value); EXPECT_EQ(static_cast(0), value); } @@ -592,132 +625,135 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoAlterTable) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoCatalogLocation) { // GH-49482 TODO: resolve inconsitent return value for SQL_CATALOG_LOCATION and change // test type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUSMALLINT value; - GetInfo(conn, SQL_CATALOG_LOCATION, &value); + GetInfo(this->conn, SQL_CATALOG_LOCATION, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCatalogName) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_CATALOG_NAME, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_CATALOG_USAGE, &value); + GetInfo(this->conn, SQL_CATALOG_USAGE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoColumnAlias) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_COLUMN_ALIAS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_CORRELATION_NAME, &value); + GetInfo(this->conn, SQL_CORRELATION_NAME, &value); EXPECT_EQ(static_cast(SQL_CN_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateAssertion) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_ASSERTION, &value); + GetInfo(this->conn, SQL_CREATE_ASSERTION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateCharacterSet) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_CHARACTER_SET, &value); + GetInfo(this->conn, SQL_CREATE_CHARACTER_SET, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateCollation) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_COLLATION, &value); + GetInfo(this->conn, SQL_CREATE_COLLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_DOMAIN, &value); + GetInfo(this->conn, SQL_CREATE_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCreateSchema) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_SCHEMA, &value); + GetInfo(this->conn, SQL_CREATE_SCHEMA, &value); EXPECT_EQ(static_cast(1), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoCreateTable) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_TABLE, &value); + GetInfo(this->conn, SQL_CREATE_TABLE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoCreateTranslation) { SQLUINTEGER value; - GetInfo(conn, SQL_CREATE_TRANSLATION, &value); + GetInfo(this->conn, SQL_CREATE_TRANSLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDdlIndex) { SQLUINTEGER value; - GetInfo(conn, SQL_DDL_INDEX, &value); + GetInfo(this->conn, SQL_DDL_INDEX, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropAssertion) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_ASSERTION, &value); + GetInfo(this->conn, SQL_DROP_ASSERTION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropCharacterSet) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_CHARACTER_SET, &value); + GetInfo(this->conn, SQL_DROP_CHARACTER_SET, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropCollation) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_COLLATION, &value); + GetInfo(this->conn, SQL_DROP_COLLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_DOMAIN, &value); + GetInfo(this->conn, SQL_DROP_DOMAIN, &value); EXPECT_EQ(static_cast(0), value); } @@ -725,177 +761,186 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropDomain) { TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropSchema) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_SCHEMA and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUINTEGER value; - GetInfo(conn, SQL_DROP_SCHEMA, &value); + GetInfo(this->conn, SQL_DROP_SCHEMA, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoHandleTest, TestSQLGetInfoDropTable) { // GH-49482 TODO: resolve inconsitent return value for SQL_DROP_TABLE and change test // type to `ConnectionInfoTest` - this->ConnectWithString(this->GetConnectionString()); + this->ConnectWithString(this->GetConnectionString(), this->conn); SQLUINTEGER value; - GetInfo(conn, SQL_DROP_TABLE, &value); + GetInfo(this->conn, SQL_DROP_TABLE, &value); EXPECT_EQ(static_cast(0), value); - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropTranslation) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_TRANSLATION, &value); + GetInfo(this->conn, SQL_DROP_TRANSLATION, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoDropView) { SQLUINTEGER value; - GetInfo(conn, SQL_DROP_VIEW, &value); + GetInfo(this->conn, SQL_DROP_VIEW, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoExpressionsInOrderby) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_EXPRESSIONS_IN_ORDERBY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_GROUP_BY, &value); + GetInfo(this->conn, SQL_GROUP_BY, &value); EXPECT_EQ(static_cast(SQL_GB_GROUP_BY_CONTAINS_SELECT), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierCase) { SQLUSMALLINT value; - GetInfo(conn, SQL_IDENTIFIER_CASE, &value); + GetInfo(this->conn, SQL_IDENTIFIER_CASE, &value); EXPECT_EQ(static_cast(SQL_IC_MIXED), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIdentifierQuoteChar) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_IDENTIFIER_QUOTE_CHAR, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_INDEX_KEYWORDS, &value); + GetInfo(this->conn, SQL_INDEX_KEYWORDS, &value); EXPECT_EQ(static_cast(SQL_IK_NONE), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoInsertStatement) { SQLUINTEGER value; - GetInfo(conn, SQL_INSERT_STATEMENT, &value); + GetInfo(this->conn, SQL_INSERT_STATEMENT, &value); EXPECT_EQ(value, static_cast(SQL_IS_INSERT_LITERALS | SQL_IS_INSERT_SEARCHED | SQL_IS_SELECT_INTO)); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoIntegrity) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_INTEGRITY, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->conn, SQL_KEYWORDS, value, info_len); - EXPECT_GT(wcslen(value), 0); + std::wstring result = ConvertToWString(value, -1, info_len); + EXPECT_GT(result.length(), 0); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoLikeEscapeClause) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_LIKE_ESCAPE_CLAUSE, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_NON_NULLABLE_COLUMNS, &value); + GetInfo(this->conn, SQL_NON_NULLABLE_COLUMNS, &value); EXPECT_EQ(static_cast(SQL_NNC_NULL), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOjCapabilities) { SQLUINTEGER value; - GetInfo(conn, SQL_OJ_CAPABILITIES, &value); + GetInfo(this->conn, SQL_OJ_CAPABILITIES, &value); EXPECT_EQ(static_cast(SQL_OJ_LEFT | SQL_OJ_RIGHT | SQL_OJ_FULL), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoOrderByColumnsInSelect) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_ORDER_BY_COLUMNS_IN_SELECT, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_QUOTED_IDENTIFIER_CASE, &value); + GetInfo(this->conn, SQL_QUOTED_IDENTIFIER_CASE, &value); EXPECT_EQ(static_cast(SQL_IC_MIXED), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSchemaUsage) { SQLUINTEGER value; - GetInfo(conn, SQL_SCHEMA_USAGE, &value); + GetInfo(this->conn, SQL_SCHEMA_USAGE, &value); EXPECT_EQ(static_cast(SQL_SU_DML_STATEMENTS), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoSpecialCharacters) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_SPECIAL_CHARACTERS, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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) { SQLUINTEGER value; - GetInfo(conn, SQL_SQL_CONFORMANCE, &value); + GetInfo(this->conn, SQL_SQL_CONFORMANCE, &value); EXPECT_EQ(static_cast(SQL_SC_SQL92_ENTRY), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSubqueries) { SQLUINTEGER value; - GetInfo(conn, SQL_SUBQUERIES, &value); + GetInfo(this->conn, SQL_SUBQUERIES, &value); EXPECT_EQ(value, static_cast(SQL_SQ_CORRELATED_SUBQUERIES | SQL_SQ_COMPARISON | @@ -904,7 +949,7 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSubqueries) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoUnion) { SQLUINTEGER value; - GetInfo(conn, SQL_UNION, &value); + GetInfo(this->conn, SQL_UNION, &value); EXPECT_EQ(static_cast(SQL_U_UNION | SQL_U_UNION_ALL), value); } @@ -913,140 +958,142 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoUnion) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxBinaryLiteralLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_BINARY_LITERAL_LEN, &value); + GetInfo(this->conn, SQL_MAX_BINARY_LITERAL_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxCatalogNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CATALOG_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_CATALOG_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxCharLiteralLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_CHAR_LITERAL_LEN, &value); + GetInfo(this->conn, SQL_MAX_CHAR_LITERAL_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxColumnNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMN_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_COLUMN_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInGroupBy) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_GROUP_BY, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_GROUP_BY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInIndex) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_INDEX, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_INDEX, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInOrderBy) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_ORDER_BY, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_ORDER_BY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInSelect) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_SELECT, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_SELECT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxColumnsInTable) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_COLUMNS_IN_TABLE, &value); + GetInfo(this->conn, SQL_MAX_COLUMNS_IN_TABLE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxCursorNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_CURSOR_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_CURSOR_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxIdentifierLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_IDENTIFIER_LEN, &value); + GetInfo(this->conn, SQL_MAX_IDENTIFIER_LEN, &value); EXPECT_EQ(static_cast(65535), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxIndexSize) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_INDEX_SIZE, &value); + GetInfo(this->conn, SQL_MAX_INDEX_SIZE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxProcedureNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_PROCEDURE_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_PROCEDURE_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxRowSize) { - SQLWCHAR value[kOdbcBufferSize] = L""; - GetInfo(conn, SQL_MAX_ROW_SIZE, value); + SQLWCHAR value[kOdbcBufferSize] = {}; + GetInfoSQLWCHAR(this->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(this->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) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_SCHEMA_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_SCHEMA_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxStatementLen) { SQLUINTEGER value; - GetInfo(conn, SQL_MAX_STATEMENT_LEN, &value); + GetInfo(this->conn, SQL_MAX_STATEMENT_LEN, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxTableNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_TABLE_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_TABLE_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoMaxTablesInSelect) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_TABLES_IN_SELECT, &value); + GetInfo(this->conn, SQL_MAX_TABLES_IN_SELECT, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxUserNameLen) { SQLUSMALLINT value; - GetInfo(conn, SQL_MAX_USER_NAME_LEN, &value); + GetInfo(this->conn, SQL_MAX_USER_NAME_LEN, &value); EXPECT_EQ(static_cast(0), value); } @@ -1055,21 +1102,21 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoMaxUserNameLen) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_FUNCTIONS, &value); + GetInfo(this->conn, SQL_CONVERT_FUNCTIONS, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoNumericFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_NUMERIC_FUNCTIONS, &value); + GetInfo(this->conn, SQL_NUMERIC_FUNCTIONS, &value); EXPECT_EQ(static_cast(4058942), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoStringFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_STRING_FUNCTIONS, &value); + GetInfo(this->conn, SQL_STRING_FUNCTIONS, &value); EXPECT_EQ(value, static_cast(SQL_FN_STR_LTRIM | SQL_FN_STR_LENGTH | SQL_FN_STR_REPLACE | SQL_FN_STR_RTRIM)); @@ -1077,14 +1124,14 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoStringFunctions) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoSystemFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_SYSTEM_FUNCTIONS, &value); + GetInfo(this->conn, SQL_SYSTEM_FUNCTIONS, &value); EXPECT_EQ(static_cast(SQL_FN_SYS_IFNULL | SQL_FN_SYS_USERNAME), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateAddIntervals) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_ADD_INTERVALS, &value); + GetInfo(this->conn, SQL_TIMEDATE_ADD_INTERVALS, &value); EXPECT_EQ(value, static_cast( SQL_FN_TSI_FRAC_SECOND | SQL_FN_TSI_SECOND | SQL_FN_TSI_MINUTE | @@ -1094,7 +1141,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateAddIntervals) { TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateDiffIntervals) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_DIFF_INTERVALS, &value); + GetInfo(this->conn, SQL_TIMEDATE_DIFF_INTERVALS, &value); EXPECT_EQ(value, static_cast( SQL_FN_TSI_FRAC_SECOND | SQL_FN_TSI_SECOND | SQL_FN_TSI_MINUTE | @@ -1104,7 +1151,7 @@ TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoTimedateDiffIntervals) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoTimedateFunctions) { SQLUINTEGER value; - GetInfo(conn, SQL_TIMEDATE_FUNCTIONS, &value); + GetInfo(this->conn, SQL_TIMEDATE_FUNCTIONS, &value); EXPECT_EQ(value, static_cast( @@ -1121,147 +1168,147 @@ TEST_F(ConnectionInfoMockTest, TestSQLGetInfoTimedateFunctions) { TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertBigint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BIGINT, &value); + GetInfo(this->conn, SQL_CONVERT_BIGINT, &value); EXPECT_EQ(static_cast(8), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertBinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BINARY, &value); + GetInfo(this->conn, SQL_CONVERT_BINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertBit) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_BIT, &value); + GetInfo(this->conn, SQL_CONVERT_BIT, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertChar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_CHAR, &value); + GetInfo(this->conn, SQL_CONVERT_CHAR, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertDate) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DATE, &value); + GetInfo(this->conn, SQL_CONVERT_DATE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertDecimal) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DECIMAL, &value); + GetInfo(this->conn, SQL_CONVERT_DECIMAL, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertDouble) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_DOUBLE, &value); + GetInfo(this->conn, SQL_CONVERT_DOUBLE, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertFloat) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_FLOAT, &value); + GetInfo(this->conn, SQL_CONVERT_FLOAT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertInteger) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTEGER, &value); + GetInfo(this->conn, SQL_CONVERT_INTEGER, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertIntervalDayTime) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTERVAL_DAY_TIME, &value); + GetInfo(this->conn, SQL_CONVERT_INTERVAL_DAY_TIME, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertIntervalYearMonth) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_INTERVAL_YEAR_MONTH, &value); + GetInfo(this->conn, SQL_CONVERT_INTERVAL_YEAR_MONTH, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertLongvarbinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_LONGVARBINARY, &value); + GetInfo(this->conn, SQL_CONVERT_LONGVARBINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertLongvarchar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_LONGVARCHAR, &value); + GetInfo(this->conn, SQL_CONVERT_LONGVARCHAR, &value); EXPECT_EQ(static_cast(0), value); } TEST_F(ConnectionInfoMockTest, TestSQLGetInfoConvertNumeric) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_NUMERIC, &value); + GetInfo(this->conn, SQL_CONVERT_NUMERIC, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertReal) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_REAL, &value); + GetInfo(this->conn, SQL_CONVERT_REAL, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertSmallint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_SMALLINT, &value); + GetInfo(this->conn, SQL_CONVERT_SMALLINT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTime) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TIME, &value); + GetInfo(this->conn, SQL_CONVERT_TIME, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTimestamp) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TIMESTAMP, &value); + GetInfo(this->conn, SQL_CONVERT_TIMESTAMP, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertTinyint) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_TINYINT, &value); + GetInfo(this->conn, SQL_CONVERT_TINYINT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertVarbinary) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_VARBINARY, &value); + GetInfo(this->conn, SQL_CONVERT_VARBINARY, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(ConnectionInfoTest, TestSQLGetInfoConvertVarchar) { SQLUINTEGER value; - GetInfo(conn, SQL_CONVERT_VARCHAR, &value); + GetInfo(this->conn, SQL_CONVERT_VARCHAR, &value); EXPECT_EQ(static_cast(0), value); } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc index 78ca031e2e8f..837c18c9cbdf 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/connection_test.cc @@ -155,7 +155,7 @@ TYPED_TEST(ConnectionTest, TestSQLGetEnvAttrOutputNTS) { SQLINTEGER output_nts; ASSERT_EQ(SQL_SUCCESS, - SQLGetEnvAttr(env, SQL_ATTR_OUTPUT_NTS, &output_nts, 0, nullptr)); + SQLGetEnvAttr(this->env, SQL_ATTR_OUTPUT_NTS, &output_nts, 0, nullptr)); ASSERT_EQ(SQL_TRUE, output_nts); } @@ -165,7 +165,8 @@ TYPED_TEST(ConnectionTest, DISABLED_TestSQLGetEnvAttrGetLength) { // Windows. Windows driver manager ignores the length pointer. // This test case can be potentially used on macOS/Linux SQLINTEGER length; - ASSERT_EQ(SQL_SUCCESS, SQLGetEnvAttr(env, SQL_ATTR_ODBC_VERSION, nullptr, 0, &length)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, nullptr, 0, &length)); EXPECT_EQ(sizeof(SQLINTEGER), length); } @@ -174,7 +175,8 @@ TYPED_TEST(ConnectionTest, DISABLED_TestSQLGetEnvAttrNullValuePointer) { // Test is disabled because call to SQLGetEnvAttr is handled by the driver manager on // Windows. The Windows driver manager doesn't error out when null pointer is passed. // This test case can be potentially used on macOS/Linux - ASSERT_EQ(SQL_ERROR, SQLGetEnvAttr(env, SQL_ATTR_ODBC_VERSION, nullptr, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, nullptr, 0, nullptr)); } TEST(SQLSetEnvAttr, TestSQLSetEnvAttrOutputNTSValid) { @@ -222,15 +224,15 @@ 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. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Check that out_str has same content as connect_str std::string out_connection_string = ODBC::SqlWcharToString(out_str, out_str_len); @@ -242,8 +244,8 @@ TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnect) { ASSERT_TRUE(CompareConnPropertyMap(out_properties, in_properties)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionHandleTest, TestSQLDriverConnectDsn) { @@ -264,22 +266,22 @@ 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. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TYPED_TEST(ConnectionHandleTest, TestSQLConnect) { @@ -301,17 +303,17 @@ TYPED_TEST(ConnectionHandleTest, TestSQLConnect) { // Connecting to ODBC server. Empty uid and pwd should be ignored. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { @@ -342,17 +344,17 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectInputUidPwd) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { @@ -384,11 +386,11 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectInvalidUid) { // UID specified in DSN will take precedence, // so connection still fails despite passing valid uid in SQLConnect call ASSERT_EQ(SQL_ERROR, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState28000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState28000); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); @@ -416,17 +418,17 @@ TEST_F(ConnectionRemoteTest, TestSQLConnectDSNPrecedence) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLConnect(conn, dsn0.data(), static_cast(dsn0.size()), + SQLConnect(this->conn, dsn0.data(), static_cast(dsn0.size()), uid0.data(), static_cast(uid0.size()), pwd0.data(), static_cast(pwd0.size()))) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Remove DSN ASSERT_TRUE(UnregisterDsn(wdsn)); // Disconnect from ODBC - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); } TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { @@ -442,11 +444,11 @@ TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState28000); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState28000); std::string out_connection_string = ODBC::SqlWcharToString(out_str, out_str_len); ASSERT_TRUE(out_connection_string.empty()); @@ -454,17 +456,17 @@ TEST_F(ConnectionRemoteTest, TestSQLDriverConnectInvalidUid) { TYPED_TEST(ConnectionHandleTest, TestSQLDisconnectWithoutConnection) { // Attempt to disconnect without a connection, expect to fail - ASSERT_EQ(SQL_ERROR, SQLDisconnect(conn)); + ASSERT_EQ(SQL_ERROR, SQLDisconnect(this->conn)); // Expect ODBC driver manager to return error state - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState08003); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState08003); } TYPED_TEST(ConnectionTest, TestSQLAllocFreeStmt) { SQLHSTMT statement; // Allocate a statement using alloc statement - ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(conn, &statement)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement)); // Close statement handle ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(statement, SQL_CLOSE)); @@ -482,28 +484,28 @@ 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. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, this->conn); // Allocate a statement using alloc statement - ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(conn, &statement)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocStmt(this->conn, &statement)); // Disconnect from ODBC without closing the statement first - ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(conn)); + ASSERT_EQ(SQL_SUCCESS, SQLDisconnect(this->conn)); } TYPED_TEST(ConnectionTest, TestSQLAllocFreeDesc) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); // Free descriptor handle ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DESC, descriptor)); @@ -513,37 +515,37 @@ TYPED_TEST(ConnectionTest, TestSQLSetStmtAttrDescriptor) { SQLHDESC apd_descriptor, ard_descriptor; // Allocate an APD descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &apd_descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &apd_descriptor)); // Allocate an ARD descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &ard_descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &ard_descriptor)); // Save implicitly allocated internal APD and ARD descriptor pointers SQLPOINTER internal_apd, internal_ard = nullptr; - EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &internal_apd, - sizeof(internal_apd), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, + &internal_apd, sizeof(internal_apd), 0)); - EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &internal_ard, + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &internal_ard, sizeof(internal_ard), 0)); // Set APD descriptor to explicitly allocated handle - EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, + EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, reinterpret_cast(apd_descriptor), 0)); // Set ARD descriptor to explicitly allocated handle - EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, + EXPECT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, reinterpret_cast(ard_descriptor), 0)); // Verify APD and ARD descriptors are set to explicitly allocated pointers SQLPOINTER value = nullptr; - EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value, sizeof(value), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value, + sizeof(value), 0)); EXPECT_EQ(apd_descriptor, value); EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); EXPECT_EQ(ard_descriptor, value); @@ -555,13 +557,13 @@ TYPED_TEST(ConnectionTest, TestSQLSetStmtAttrDescriptor) { // Verify APD and ARD descriptors has been reverted to implicit descriptors value = nullptr; - EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value, sizeof(value), 0)); + EXPECT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value, + sizeof(value), 0)); EXPECT_EQ(internal_apd, value); EXPECT_EQ(SQL_SUCCESS, - SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value, sizeof(value), 0)); EXPECT_EQ(internal_ard, value); } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/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..7e734accb8d5 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/errors_test.cc @@ -62,7 +62,7 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -75,7 +75,7 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT diag_number_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, HEADER_LEVEL, SQL_DIAG_NUMBER, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, HEADER_LEVEL, SQL_DIAG_NUMBER, &diag_number, sizeof(SQLINTEGER), &diag_number_length)); EXPECT_EQ(1, diag_number); @@ -85,15 +85,16 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT server_name_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_SERVER_NAME, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_SERVER_NAME, server_name, kOdbcBufferSize, &server_name_length)); // SQL_DIAG_MESSAGE_TEXT SQLWCHAR message_text[kOdbcBufferSize]; SQLSMALLINT message_text_length; - SQLRETURN ret = SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, - message_text, kOdbcBufferSize, &message_text_length); + SQLRETURN ret = + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, + message_text, kOdbcBufferSize, &message_text_length); // dependent on the size of the message it could output SQL_SUCCESS_WITH_INFO EXPECT_TRUE(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO); @@ -105,8 +106,8 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { SQLSMALLINT diag_native_length; EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_NATIVE, &diag_native, - sizeof(diag_native), &diag_native_length)); + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_NATIVE, + &diag_native, sizeof(diag_native), &diag_native_length)); EXPECT_EQ(200, diag_native); @@ -115,9 +116,10 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagFieldWForConnectFailure) { SQLWCHAR sql_state[sql_state_size]; SQLSMALLINT sql_state_length; - EXPECT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_SQLSTATE, sql_state, - sql_state_size * GetSqlWCharSize(), &sql_state_length)); + EXPECT_EQ( + SQL_SUCCESS, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_SQLSTATE, sql_state, + sql_state_size * GetSqlWCharSize(), &sql_state_length)); EXPECT_EQ(kErrorState28000, SqlWcharToString(sql_state)); } @@ -138,7 +140,7 @@ TYPED_TEST(ErrorsHandleTest, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -152,7 +154,7 @@ TYPED_TEST(ErrorsHandleTest, DISABLED_TestSQLGetDiagFieldWForConnectFailureNTS) message_text[kOdbcBufferSize - 1] = '\0'; ASSERT_EQ(SQL_SUCCESS, - SQLGetDiagField(SQL_HANDLE_DBC, conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, + SQLGetDiagField(SQL_HANDLE_DBC, this->conn, RECORD_1, SQL_DIAG_MESSAGE_TEXT, message_text, SQL_NTS, &message_text_length)); EXPECT_GT(message_text_length, 100); @@ -164,7 +166,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagFieldWForDescriptorFailureFromDriverManager SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); EXPECT_EQ(SQL_ERROR, SQLGetDescField(descriptor, 1, SQL_DESC_DATETIME_INTERVAL_CODE, 0, 0, nullptr)); @@ -230,7 +232,7 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecForDescriptorFailureFromDriverManager) { SQLHDESC descriptor; // Allocate a descriptor using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, conn, &descriptor)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DESC, this->conn, &descriptor)); EXPECT_EQ(SQL_ERROR, SQLGetDescField(descriptor, 1, SQL_DESC_DATETIME_INTERVAL_CODE, 0, 0, nullptr)); @@ -251,7 +253,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)); @@ -271,7 +274,7 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagRecForConnectFailure) { // Connecting to ODBC server. ASSERT_EQ(SQL_ERROR, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(this->conn, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)); @@ -279,8 +282,9 @@ TYPED_TEST(ErrorsHandleTest, TestSQLGetDiagRecForConnectFailure) { SQLINTEGER native_error; SQLWCHAR message[kOdbcBufferSize]; SQLSMALLINT message_length; - ASSERT_EQ(SQL_SUCCESS, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 1, sql_state, &native_error, - message, kOdbcBufferSize, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 1, sql_state, &native_error, + message, kOdbcBufferSize, &message_length)); EXPECT_GT(message_length, 120); @@ -288,7 +292,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) { @@ -300,22 +305,28 @@ TYPED_TEST(ErrorsTest, TestSQLGetDiagRecInputData) { SQLSMALLINT message_length; // Pass invalid record number - EXPECT_EQ(SQL_ERROR, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 0, sql_state, &native_error, - message, kOdbcBufferSize, &message_length)); + EXPECT_EQ(SQL_ERROR, + SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 0, sql_state, &native_error, + message, kOdbcBufferSize, &message_length)); // Pass valid record number with null inputs - EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, conn, 1, nullptr, nullptr, nullptr, - 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLGetDiagRec(SQL_HANDLE_DBC, this->conn, 1, nullptr, nullptr, + nullptr, 0, nullptr)); - // Invalid handle #ifdef __APPLE__ // MacOS ODBC driver manager requires connection handle EXPECT_EQ(SQL_INVALID_HANDLE, - SQLGetDiagRec(0, conn, 1, nullptr, nullptr, nullptr, 0, nullptr)); + SQLGetDiagRec(0, this->conn, 1, nullptr, nullptr, nullptr, 0, nullptr)); #else - EXPECT_EQ(SQL_INVALID_HANDLE, + // Linux & Windows driver managers have different expected return values +# ifdef __linux__ + SQLRETURN expected_rc = SQL_ERROR; +# else // Windows + SQLRETURN expected_rc = SQL_INVALID_HANDLE; +# endif + EXPECT_EQ(expected_rc, SQLGetDiagRec(0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr)); -#endif // __APPLE__ +#endif } TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorInputData) { @@ -324,17 +335,17 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorInputData) { // Pass valid handles with null inputs EXPECT_EQ(SQL_NO_DATA, - SQLError(env, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); + SQLError(this->env, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); - EXPECT_EQ(SQL_NO_DATA, - SQLError(nullptr, conn, nullptr, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(nullptr, this->conn, nullptr, nullptr, nullptr, nullptr, + 0, nullptr)); #ifdef __APPLE__ - EXPECT_EQ(SQL_NO_DATA, - SQLError(SQL_NULL_HENV, conn, stmt, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(SQL_NULL_HENV, this->conn, this->stmt, nullptr, nullptr, + nullptr, 0, nullptr)); #else - EXPECT_EQ(SQL_NO_DATA, - SQLError(nullptr, nullptr, stmt, nullptr, nullptr, nullptr, 0, nullptr)); + EXPECT_EQ(SQL_NO_DATA, SQLError(nullptr, nullptr, this->stmt, nullptr, nullptr, nullptr, + 0, nullptr)); #endif // __APPLE__ // Invalid handle @@ -349,14 +360,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorEnvErrorFromDriverManager) { // DM passes 512 as buffer length to SQLError. // Attempt to set environment attribute after connection handle allocation - ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC2), 0)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(env, nullptr, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(this->env, nullptr, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 40); @@ -366,7 +377,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) { @@ -376,13 +388,14 @@ TYPED_TEST(ErrorsTest, TestSQLErrorConnError) { // DM passes 512 as buffer length to SQLError. // Attempt to set unsupported attribute - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, conn, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, this->conn, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 60); @@ -392,7 +405,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,17 +415,16 @@ 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)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - SQLRETURN ret = SQLError(nullptr, conn, stmt, sql_state, &native_error, message, - SQL_MAX_MESSAGE_LENGTH, &message_length); + SQLRETURN ret = SQLError(nullptr, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length); EXPECT_TRUE(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO); @@ -421,18 +434,18 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; @@ -440,14 +453,15 @@ TYPED_TEST(ErrorsTest, TestSQLErrorStmtWarning) { SQLLEN ind; EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 50); @@ -456,7 +470,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) { @@ -466,14 +481,14 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) { // DM passes 512 as buffer length to SQLError. // Attempt to set environment attribute after connection handle allocation - ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + ASSERT_EQ(SQL_ERROR, SQLSetEnvAttr(this->env, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC2), 0)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(env, nullptr, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(this->env, nullptr, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 40); @@ -481,15 +496,16 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorEnvErrorFromDriverManager) { EXPECT_EQ(0, native_error); // Function sequence error state from driver manager -#ifdef _WIN32 - // Windows Driver Manager returns S1010 - EXPECT_EQ(kErrorStateS1010, SqlWcharToString(sql_state)); -#else - // unix Driver Manager returns HY010 +#ifdef __APPLE__ + // MacOS Driver Manager returns HY010 EXPECT_EQ(kErrorStateHY010, SqlWcharToString(sql_state)); -#endif // _WIN32 +#else // Linux & Windows + // Linux & Windows Driver Managers returns S1010 + EXPECT_EQ(kErrorStateS1010, SqlWcharToString(sql_state)); +#endif - EXPECT_FALSE(std::wstring(message).empty()); + std::string msg = SqlWcharToString(message); + EXPECT_FALSE(msg.empty()); } #ifndef __APPLE__ @@ -505,13 +521,14 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorConnError) { // macOS Excel. // Attempt to set unsupported attribute - ASSERT_EQ(SQL_ERROR, SQLGetConnectAttr(conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, + SQLGetConnectAttr(this->conn, SQL_ATTR_TXN_ISOLATION, 0, 0, nullptr)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, conn, nullptr, sql_state, &native_error, + ASSERT_EQ(SQL_SUCCESS, SQLError(nullptr, this->conn, nullptr, sql_state, &native_error, message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 60); @@ -521,7 +538,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,17 +549,17 @@ 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)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLSMALLINT message_length = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 70); EXPECT_EQ(100, native_error); @@ -549,18 +567,18 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; @@ -568,14 +586,15 @@ TYPED_TEST(ErrorsOdbcV2Test, TestSQLErrorStmtWarning) { SQLLEN ind; EXPECT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR sql_state[6] = {0}; SQLINTEGER native_error = 0; SQLWCHAR message[SQL_MAX_MESSAGE_LENGTH] = {0}; SQLSMALLINT message_length = 0; - ASSERT_EQ(SQL_SUCCESS, SQLError(SQL_NULL_HENV, conn, stmt, sql_state, &native_error, - message, SQL_MAX_MESSAGE_LENGTH, &message_length)); + ASSERT_EQ(SQL_SUCCESS, + SQLError(SQL_NULL_HENV, this->conn, this->stmt, sql_state, &native_error, + message, SQL_MAX_MESSAGE_LENGTH, &message_length)); EXPECT_GT(message_length, 50); @@ -584,7 +603,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/get_functions_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc index 6ae1178e5d28..b01b0d71d5e4 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/get_functions_test.cc @@ -40,8 +40,9 @@ using TestTypesOdbcV2 = ::testing::Types; TYPED_TEST_SUITE(GetFunctionsOdbcV2Test, TestTypesOdbcV2); -// MacOS driver manager iODBC does not support SQLGetFunctions for ODBC 3.x or 2.x driver -#ifndef __APPLE__ +// Unix driver managers iODBC and Unix-ODBC do not support SQLGetFunctions +// for ODBC 3.x or 2.x driver +#ifdef _WIN32 TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsAllFunctions) { // Verify driver manager return values for SQLGetFunctions @@ -77,7 +78,8 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsAllFunctions) { SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, SQL_API_SQLTABLEPRIVILEGES}; - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetFunctions(this->conn, SQL_API_ODBC3_ALL_FUNCTIONS, api_exists)); for (int api : supported_functions) { EXPECT_EQ(SQL_TRUE, SQL_FUNC_EXISTS(api_exists, api)); @@ -113,7 +115,7 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsAllFunctions) { SQL_API_SQLBULKOPERATIONS, SQL_API_SQLCOLUMNPRIVILEGES, SQL_API_SQLPROCEDURECOLUMNS, SQL_API_SQLDESCRIBEPARAM, SQL_API_SQLPROCEDURES, SQL_API_SQLSETPOS, SQL_API_SQLTABLEPRIVILEGES}; - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, SQL_API_ALL_FUNCTIONS, api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, SQL_API_ALL_FUNCTIONS, api_exists)); for (int api : supported_functions) { EXPECT_EQ(SQL_TRUE, api_exists[api]); @@ -148,7 +150,7 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsSupportedSingleAPI) { SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : supported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_TRUE, api_exists); @@ -168,7 +170,7 @@ TYPED_TEST(GetFunctionsTest, TestSQLGetFunctionsUnsupportedSingleAPI) { SQL_API_SQLTABLEPRIVILEGES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : unsupported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_FALSE, api_exists); @@ -192,7 +194,7 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsSupportedSingleAPI) { SQL_API_SQLGETFUNCTIONS, SQL_API_SQLDRIVERS, SQL_API_SQLDATASOURCES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : supported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_TRUE, api_exists); @@ -210,13 +212,13 @@ TYPED_TEST(GetFunctionsOdbcV2Test, TestSQLGetFunctionsUnsupportedSingleAPI) { SQL_API_SQLTABLEPRIVILEGES}; SQLUSMALLINT api_exists; for (SQLUSMALLINT api : unsupported_functions) { - ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(conn, api, &api_exists)); + ASSERT_EQ(SQL_SUCCESS, SQLGetFunctions(this->conn, api, &api_exists)); EXPECT_EQ(SQL_FALSE, api_exists); api_exists = -1; } } -#endif // __APPLE__ +#endif // _WIN32 } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc index 3fc48c263ec8..f803e135765d 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.cc @@ -19,6 +19,7 @@ // with windows.h #include "arrow/flight/sql/odbc/odbc_impl/flight_sql_connection.h" +#include "arrow/compute/api.h" #include "arrow/flight/sql/odbc/tests/odbc_test_suite.h" // For DSN registration @@ -51,28 +52,79 @@ class MockServerEnvironment : public ::testing::Environment { } }; -::testing::Environment* mock_env = +bool RunningRemoteTests() { return !remote_test_connect_str.empty(); } + +class OdbcTestEnvironment : public ::testing::Environment { + public: + void SetUp() override { + remote_test_connect_str = ODBCTestBase::GetConnectionString(); + if (RunningRemoteTests()) { + ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv3_handles.env, + remote_odbcv3_handles.conn, SQL_OV_ODBC3); + ODBCTestBase::Connect(remote_test_connect_str, remote_odbcv2_handles.env, + remote_odbcv2_handles.conn, SQL_OV_ODBC2); + } + + std::string mock_test_connect_str = ODBCMockTestBase::GetConnectionString(); + ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv3_handles.env, + mock_odbcv3_handles.conn, SQL_OV_ODBC3); + ODBCMockTestBase::Connect(mock_test_connect_str, mock_odbcv2_handles.env, + mock_odbcv2_handles.conn, SQL_OV_ODBC2); + } + + void TearDown() override { + if (RunningRemoteTests()) { + ODBCTestBase::Disconnect(remote_odbcv3_handles.env, remote_odbcv3_handles.conn); + ODBCTestBase::Disconnect(remote_odbcv2_handles.env, remote_odbcv2_handles.conn); + } + + ODBCTestBase::Disconnect(mock_odbcv3_handles.env, mock_odbcv3_handles.conn); + ODBCTestBase::Disconnect(mock_odbcv2_handles.env, mock_odbcv2_handles.conn); + } +}; + +#ifdef _WIN32 +// A global test "environment", to ensure Arrow compute kernel functions are registered +class ComputeKernelEnvironment : public ::testing::Environment { + public: + void SetUp() override { ASSERT_OK(arrow::compute::Initialize()); } +}; + +::testing::Environment* compute_kernel_env = + ::testing::AddGlobalTestEnvironment(new ComputeKernelEnvironment); +#endif // _WIN32 + +::testing::Environment* mock_server_env = ::testing::AddGlobalTestEnvironment(new MockServerEnvironment); -void ODBCTestBase::AllocEnvConnHandles(SQLINTEGER odbc_ver) { +::testing::Environment* odbc_test_env = + ::testing::AddGlobalTestEnvironment(new OdbcTestEnvironment); + +SQLHENV ODBCTestBase::env = SQL_NULL_HENV; +SQLHDBC ODBCTestBase::conn = SQL_NULL_HDBC; +SQLHSTMT ODBCTestBase::stmt = SQL_NULL_HSTMT; + +void ODBCTestBase::AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver) { // Allocate an environment handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocEnv(&env_handle)); ASSERT_EQ( SQL_SUCCESS, - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + SQLSetEnvAttr(env_handle, SQL_ATTR_ODBC_VERSION, reinterpret_cast(static_cast(odbc_ver)), 0)); // Allocate a connection using alloc handle - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env, &conn)); + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_DBC, env_handle, &conn_handle)); } -void ODBCTestBase::Connect(std::string connect_str, SQLINTEGER odbc_ver) { - ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(odbc_ver)); - ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str)); +void ODBCTestBase::Connect(std::string connect_str, SQLHENV& env_handle, + SQLHDBC& conn_handle, SQLINTEGER odbc_ver) { + ASSERT_NO_FATAL_FAILURE(AllocEnvConnHandles(env_handle, conn_handle, odbc_ver)); + ASSERT_NO_FATAL_FAILURE(ConnectWithString(connect_str, conn_handle)); } -void ODBCTestBase::ConnectWithString(std::string connect_str) { +void ODBCTestBase::ConnectWithString(std::string connect_str, SQLHDBC& conn_handle) { // Connect string std::vector connect_str0(connect_str.begin(), connect_str.end()); @@ -81,31 +133,39 @@ void ODBCTestBase::ConnectWithString(std::string connect_str) { // Connecting to ODBC server. ASSERT_EQ(SQL_SUCCESS, - SQLDriverConnect(conn, NULL, &connect_str0[0], + SQLDriverConnect(conn_handle, NULL, &connect_str0[0], static_cast(connect_str0.size()), out_str, kOdbcBufferSize, &out_str_len, SQL_DRIVER_NOPROMPT)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn_handle); } -void ODBCTestBase::Disconnect() { +void ODBCTestBase::Disconnect(SQLHENV& env_handle, SQLHDBC& conn_handle) { // Disconnect from ODBC - EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn)) - << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn); + if (conn_handle != SQL_NULL_HDBC) { + EXPECT_EQ(SQL_SUCCESS, SQLDisconnect(conn_handle)) + << GetOdbcErrorMessage(SQL_HANDLE_DBC, conn_handle); + } - FreeEnvConnHandles(); + FreeEnvConnHandles(env_handle, conn_handle); } -void ODBCTestBase::FreeEnvConnHandles() { +void ODBCTestBase::FreeEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle) { // Free connection handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn)); + if (conn_handle != SQL_NULL_HDBC) { + EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_DBC, conn_handle)); + conn_handle = SQL_NULL_HDBC; + } // Free environment handle - EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env)); + if (env_handle != SQL_NULL_HENV) { + EXPECT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_ENV, env_handle)); + env_handle = SQL_NULL_HENV; + } } std::string ODBCTestBase::GetConnectionString() { std::string connect_str = - arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOrDie(); + arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr(""); return connect_str; } @@ -168,68 +228,53 @@ std::wstring ODBCTestBase::GetQueryAllDataTypes() { } void ODBCTestBase::SetUp() { - if (connected) { - ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); - } + ASSERT_EQ(SQL_SUCCESS, SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt)); } void ODBCTestBase::TearDown() { - if (connected) { - ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt)); - } -} - -void ODBCTestBase::TearDownTestSuite() { - if (connected) { - Disconnect(); - connected = false; - } -} - -void FlightSQLODBCRemoteTestBase::CheckForRemoteTest() { - if (arrow::internal::GetEnvVar(kTestConnectStr.data()).ValueOr("").empty()) { - skipping_test = true; - GTEST_SKIP() << "Skipping test: kTestConnectStr not set"; - } + ASSERT_EQ(SQL_SUCCESS, SQLFreeHandle(SQL_HANDLE_STMT, stmt)); } void FlightSQLODBCRemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC3); - connected = true; + env = remote_odbcv3_handles.env; + conn = remote_odbcv3_handles.conn; + stmt = remote_odbcv3_handles.stmt; } void FlightSQLOdbcV2RemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC2); - connected = true; + env = remote_odbcv2_handles.env; + conn = remote_odbcv2_handles.conn; + stmt = remote_odbcv2_handles.stmt; } void FlightSQLOdbcEnvConnHandleRemoteTestBase::SetUpTestSuite() { - CheckForRemoteTest(); - if (skipping_test) { + if (!RunningRemoteTests()) { + GTEST_SKIP() << "Skipping Test Suite: Environment Variable " << kTestConnectStr.data() + << " is not set"; return; } - AllocEnvConnHandles(); + AllocEnvConnHandles(env, conn); } void FlightSQLOdbcEnvConnHandleRemoteTestBase::TearDownTestSuite() { - if (skipping_test) { + if (!RunningRemoteTests()) { return; } - FreeEnvConnHandles(); + FreeEnvConnHandles(env, conn); } std::string FindTokenInCallHeaders(const CallHeaders& incoming_headers) { @@ -400,20 +445,24 @@ void ODBCMockTestBase::DropUnicodeTable() { } void FlightSQLODBCMockTestBase::SetUpTestSuite() { - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC3); - connected = true; + env = mock_odbcv3_handles.env; + conn = mock_odbcv3_handles.conn; + stmt = mock_odbcv3_handles.stmt; } void FlightSQLOdbcV2MockTestBase::SetUpTestSuite() { - std::string connect_str = GetConnectionString(); - Connect(connect_str, SQL_OV_ODBC2); - connected = true; + env = mock_odbcv2_handles.env; + conn = mock_odbcv2_handles.conn; + stmt = mock_odbcv2_handles.stmt; } -void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { AllocEnvConnHandles(); } +void FlightSQLOdbcEnvConnHandleMockTestBase::SetUpTestSuite() { + AllocEnvConnHandles(env, conn); +} -void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { FreeEnvConnHandles(); } +void FlightSQLOdbcEnvConnHandleMockTestBase::TearDownTestSuite() { + FreeEnvConnHandles(env, conn); +} bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, Connection::ConnPropertyMap map2) { @@ -490,8 +539,8 @@ 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()); + CONVERT_SQLWCHAR_STR(w_driver, driver); + return RegisterDsn(config, reinterpret_cast(w_driver.c_str())); } std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id) { @@ -510,13 +559,45 @@ std::wstring GetStringColumnW(SQLHSTMT stmt, int col_id) { return std::wstring(buf, buf + char_count); } -std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len) { +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, SQLSMALLINT str_len, + SQLSMALLINT buffer_size) { + if (str_len == -1) { +#ifdef __linux__ + str_len = SqlWCharArrLen(str_val); +#else // Windows & Mac + str_len = std::wcslen(str_val); +#endif + } + std::wstring attr_str; + if (str_len == 0) { + attr_str = L""; + } else { + assert(str_val != nullptr); + assert(str_len > 0 && str_len <= buffer_size); + attr_str.assign(str_val, str_val + str_len); + } + return attr_str; +} + +std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len, + SQLSMALLINT buffer_size) { 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)); + EXPECT_LE(str_len, buffer_size); attr_str = std::wstring(str_val.begin(), str_val.begin() + str_len / GetSqlWCharSize()); } diff --git a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h index a4e8665c9732..1b9ac212f848 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h +++ b/cpp/src/arrow/flight/sql/odbc/tests/odbc_test_suite.h @@ -38,15 +38,38 @@ // For DSN registration #include "arrow/flight/sql/odbc/odbc_impl/system_dsn.h" +#ifdef __linux__ +# define ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + auto name##_vec = ODBC::ToSqlWCharVector(std::wstring(wstring_literal)); \ + if (name##_vec.empty() || name##_vec.back() != static_cast(0)) { \ + name##_vec.push_back(static_cast(0)); \ + } \ + SQLWCHAR* name = name##_vec.data(); +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_literal) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + SQLSMALLINT name##_len = static_cast(name##_vec.size() - 1); +#else // Windows & Mac +# define ASSIGN_SQLWCHAR_ARR(name, wstring_literal) SQLWCHAR name[] = wstring_literal; +# define ASSIGN_SQLWCHAR_ARR_AND_LEN(name, wstring_literal) \ + ASSIGN_SQLWCHAR_ARR(name, wstring_literal) \ + SQLSMALLINT name##_len = static_cast(std::wcslen(name)); +#endif + static constexpr std::string_view kTestConnectStr = "ARROW_FLIGHT_SQL_ODBC_CONN"; static constexpr std::string_view kTestDsn = "Apache Arrow Flight SQL Test DSN"; -inline SQLHENV env = 0; -inline SQLHDBC conn = 0; -inline SQLHSTMT stmt = 0; +inline std::string remote_test_connect_str = ""; + +struct OdbcHandles { + SQLHENV env = SQL_NULL_HENV; + SQLHDBC conn = SQL_NULL_HDBC; + SQLHSTMT stmt = SQL_NULL_HSTMT; +}; -inline bool skipping_test = false; -inline bool connected = false; +inline OdbcHandles remote_odbcv3_handles; +inline OdbcHandles remote_odbcv2_handles; +inline OdbcHandles mock_odbcv3_handles; +inline OdbcHandles mock_odbcv2_handles; inline std::shared_ptr mock_server; inline int mock_server_port = 0; @@ -61,17 +84,19 @@ namespace arrow::flight::sql::odbc { class ODBCTestBase : public ::testing::Test { public: /// \brief Allocate environment and connection handles - static void AllocEnvConnHandles(SQLINTEGER odbc_ver = SQL_OV_ODBC3); + static void AllocEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver = SQL_OV_ODBC3); /// \brief Free environment and connection handles - static void FreeEnvConnHandles(); + static void FreeEnvConnHandles(SQLHENV& env_handle, SQLHDBC& conn_handle); /// \brief Connect to Arrow Flight SQL server using connection string defined in /// environment variable "ARROW_FLIGHT_SQL_ODBC_CONN", allocate statement handle. /// Connects using ODBC Ver 3 by default - static void Connect(std::string connect_str, SQLINTEGER odbc_ver = SQL_OV_ODBC3); + static void Connect(std::string connect_str, SQLHENV& env_handle, SQLHDBC& conn_handle, + SQLINTEGER odbc_ver = SQL_OV_ODBC3); /// \brief Connect to Arrow Flight SQL server using connection string - static void ConnectWithString(std::string connection_str); + static void ConnectWithString(std::string connect_str, SQLHDBC& conn_handle); /// \brief Disconnect from server - static void Disconnect(); + static void Disconnect(SQLHENV& env_handle, SQLHDBC& conn_handle); /// \brief Get connection string from environment variable "ARROW_FLIGHT_SQL_ODBC_CONN" static std::string GetConnectionString(); /// \brief Get invalid connection string based on connection string defined in @@ -83,7 +108,10 @@ class ODBCTestBase : public ::testing::Test { protected: void SetUp() override; void TearDown() override; - static void TearDownTestSuite(); + + static SQLHENV env; + static SQLHDBC conn; + static SQLHSTMT stmt; }; /// \brief Base test fixture for running tests against a remote server. @@ -92,9 +120,6 @@ class ODBCTestBase : public ::testing::Test { /// The connection string for connecting to this server is defined /// in the ARROW_FLIGHT_SQL_ODBC_CONN environment variable. class FlightSQLODBCRemoteTestBase : public ODBCTestBase { - public: - static void CheckForRemoteTest(); - protected: static void SetUpTestSuite(); }; @@ -111,6 +136,8 @@ class FlightSQLOdbcEnvConnHandleRemoteTestBase : public FlightSQLODBCRemoteTestB protected: static void SetUpTestSuite(); static void TearDownTestSuite(); + void SetUp() override {} + void TearDown() override {} }; static constexpr std::string_view kAuthorizationHeader = "authorization"; @@ -200,6 +227,8 @@ class FlightSQLOdbcEnvConnHandleMockTestBase : public FlightSQLODBCMockTestBase protected: static void SetUpTestSuite(); static void TearDownTestSuite(); + void SetUp() override {} + void TearDown() override {} }; /** ODBC read buffer size. */ @@ -218,6 +247,7 @@ bool CompareConnPropertyMap(Connection::ConnPropertyMap map1, /// Get error message from ODBC driver using SQLGetDiagRec std::string GetOdbcErrorMessage(SQLSMALLINT handle_type, SQLHANDLE handle); +static constexpr std::string_view kErrorState00000 = "00000"; static constexpr std::string_view kErrorState01004 = "01004"; static constexpr std::string_view kErrorState01S02 = "01S02"; static constexpr std::string_view kErrorState01S07 = "01S07"; @@ -267,11 +297,26 @@ 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. +/// \param[in] str_len length of string, in number of characters. +/// \param[in] buffer_size size of underlying buffer, in number of characters. +/// \return wstring +std::wstring ConvertToWString(const SQLWCHAR* str_val, SQLSMALLINT str_len = -1, + SQLSMALLINT buffer_size = kOdbcBufferSize); + /// \brief Check wide char vector and convert into wstring /// \param[in] str_val Vector of SQLWCHAR. /// \param[in] str_len length of string, in bytes. +/// \param[in] buffer_size size of underlying buffer, in number of characters. /// \return wstring -std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len); +std::wstring ConvertToWString(const std::vector& str_val, SQLSMALLINT str_len, + SQLSMALLINT buffer_size = kOdbcBufferSize); /// \brief Check wide string column. /// \param[in] stmt Statement. diff --git a/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc index 1bbd3c1b74e0..fc5c5f9d1e64 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_attr_test.cc @@ -123,21 +123,21 @@ void ValidateSetStmtAttrErrorCode(SQLHSTMT statement, SQLINTEGER attribute, TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAppParamDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAppRowDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncEnable) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ASYNC_ENABLE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ASYNC_ENABLE, &value); EXPECT_EQ(static_cast(SQL_ASYNC_ENABLE_OFF), value); } @@ -145,237 +145,238 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncEnable) { #ifdef SQL_ATTR_ASYNC_STMT_EVENT TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtEventUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_EVENT, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_EVENT, kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_STMT_PCALLBACK TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtPCCallbackUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, + kErrorStateHYC00); } #endif #ifdef SQL_ATTR_ASYNC_STMT_PCONTEXT TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrAsyncStmtPCContextUnsupported) { // Optional feature not implemented - ValidateGetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, kErrorStateHYC00); + ValidateGetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, + kErrorStateHYC00); } #endif TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrConcurrency) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CONCURRENCY, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CONCURRENCY, &value); EXPECT_EQ(static_cast(SQL_CONCUR_READ_ONLY), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorScrollable) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_SCROLLABLE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SCROLLABLE, &value); EXPECT_EQ(static_cast(SQL_NONSCROLLABLE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorSensitivity) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_SENSITIVITY, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SENSITIVITY, &value); EXPECT_EQ(static_cast(SQL_UNSPECIFIED), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrCursorType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_CURSOR_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_CURSOR_TYPE, &value); EXPECT_EQ(static_cast(SQL_CURSOR_FORWARD_ONLY), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrEnableAutoIPD) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ENABLE_AUTO_IPD, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ENABLE_AUTO_IPD, &value); EXPECT_EQ(static_cast(SQL_FALSE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrFetchBookmarkPointer) { SQLLEN value; - GetStmtAttr(stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, &value); EXPECT_EQ(static_cast(NULL), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrIMPParamDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_IMP_PARAM_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_IMP_PARAM_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrIMPRowDesc) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_IMP_ROW_DESC, &value); + GetStmtAttr(this->stmt, SQL_ATTR_IMP_ROW_DESC, &value); EXPECT_GT(value, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrKeysetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_KEYSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_KEYSET_SIZE, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMaxLength) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_MAX_LENGTH, &value); + GetStmtAttr(this->stmt, SQL_ATTR_MAX_LENGTH, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMaxRows) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_MAX_ROWS, &value); + GetStmtAttr(this->stmt, SQL_ATTR_MAX_ROWS, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrMetadataID) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_METADATA_ID, &value); + GetStmtAttr(this->stmt, SQL_ATTR_METADATA_ID, &value); EXPECT_EQ(static_cast(SQL_FALSE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrNoscan) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_NOSCAN, &value); + GetStmtAttr(this->stmt, SQL_ATTR_NOSCAN, &value); EXPECT_EQ(static_cast(SQL_NOSCAN_OFF), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamBindOffsetPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamBindType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_TYPE, &value); EXPECT_EQ(static_cast(SQL_PARAM_BIND_BY_COLUMN), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamOperationPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamStatusPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamsProcessedPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrParamsetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMSET_SIZE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrQueryTimeout) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, &value); + GetStmtAttr(this->stmt, SQL_ATTR_QUERY_TIMEOUT, &value); EXPECT_EQ(static_cast(0), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRetrieveData) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_RETRIEVE_DATA, &value); + GetStmtAttr(this->stmt, SQL_ATTR_RETRIEVE_DATA, &value); EXPECT_EQ(static_cast(SQL_RD_ON), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowArraySize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindOffsetPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowBindType) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_TYPE, &value); EXPECT_EQ(static_cast(0), value); } 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_ROW_NUMBER, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_NUMBER, &value); EXPECT_EQ(static_cast(1), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowOperationPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowStatusPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowsFetchedPtr) { SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); EXPECT_EQ(static_cast(nullptr), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrSimulateCursor) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_SIMULATE_CURSOR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_SIMULATE_CURSOR, &value); EXPECT_EQ(static_cast(SQL_SC_UNIQUE), value); } TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrUseBookmarks) { SQLULEN value; - GetStmtAttr(stmt, SQL_ATTR_USE_BOOKMARKS, &value); + GetStmtAttr(this->stmt, SQL_ATTR_USE_BOOKMARKS, &value); EXPECT_EQ(static_cast(SQL_UB_OFF), value); } @@ -383,7 +384,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrUseBookmarks) { // This is a pre ODBC 3 attribute TYPED_TEST(StatementAttributeTest, TestSQLGetStmtAttrRowsetSize) { SQLULEN value; - GetStmtAttr(stmt, SQL_ROWSET_SIZE, &value); + GetStmtAttr(this->stmt, SQL_ROWSET_SIZE, &value); EXPECT_EQ(static_cast(1), value); } @@ -392,12 +393,12 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAppParamDesc) { SQLULEN app_param_desc = 0; SQLINTEGER string_length_ptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, &app_param_desc, 0, - &string_length_ptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, + &app_param_desc, 0, &string_length_ptr)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(0)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_PARAM_DESC, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_PARAM_DESC, static_cast(app_param_desc)); } @@ -405,18 +406,19 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAppRowDesc) { SQLULEN app_row_desc = 0; SQLINTEGER string_length_ptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &app_row_desc, 0, - &string_length_ptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &app_row_desc, + 0, &string_length_ptr)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, static_cast(0)); - ValidateSetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, static_cast(app_row_desc)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, + static_cast(app_row_desc)); } #ifdef SQL_ATTR_ASYNC_ENABLE TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) { // Optional feature not implemented - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF, SQL_ERROR, kErrorStateHYC00); } #endif @@ -424,14 +426,18 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncEnableUnsupported) { #ifdef SQL_ATTR_ASYNC_STMT_EVENT TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtEventUnsupported) { // Driver does not support asynchronous notification - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_EVENT, 0, SQL_ERROR, +# ifdef __linux__ + kErrorStateHYC00); +# else // Windows & Mac kErrorStateHY118); +# endif } #endif #ifdef SQL_ATTR_ASYNC_STMT_PCALLBACK TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCCallbackUnsupported) { - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCALLBACK, 0, SQL_ERROR, kErrorStateHYC00); } #endif @@ -439,43 +445,44 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCCallbackUnsuppor #ifdef SQL_ATTR_ASYNC_STMT_PCONTEXT TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrAsyncStmtPCContextUnsupported) { // Optional feature not implemented - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, 0, SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ASYNC_STMT_PCONTEXT, 0, SQL_ERROR, kErrorStateHYC00); } #endif TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrConcurrency) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CONCURRENCY, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CONCURRENCY, static_cast(SQL_CONCUR_READ_ONLY)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorScrollable) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_SCROLLABLE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SCROLLABLE, static_cast(SQL_NONSCROLLABLE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorSensitivity) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_SENSITIVITY, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_SENSITIVITY, static_cast(SQL_UNSPECIFIED)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrCursorType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_CURSOR_TYPE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_CURSOR_TYPE, static_cast(SQL_CURSOR_FORWARD_ONLY)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrEnableAutoIPD) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ENABLE_AUTO_IPD, static_cast(SQL_FALSE)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ENABLE_AUTO_IPD, + static_cast(SQL_FALSE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrFetchBookmarkPointer) { - ValidateSetStmtAttr(stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, static_cast(NULL)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_FETCH_BOOKMARK_PTR, static_cast(NULL)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPParamDesc) { // Invalid use of an automatically allocated descriptor handle - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_IMP_PARAM_DESC, static_cast(0), - SQL_ERROR, + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_IMP_PARAM_DESC, + static_cast(0), SQL_ERROR, #ifdef __APPLE__ // static iODBC on MacOS returns IM001 for this case kErrorStateIM001); @@ -486,7 +493,7 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPParamDesc) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPRowDesc) { // Invalid use of an automatically allocated descriptor handle - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_IMP_ROW_DESC, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_IMP_ROW_DESC, static_cast(0), SQL_ERROR, #ifdef __APPLE__ // static iODBC on MacOS returns IM001 for this case @@ -497,41 +504,41 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrIMPRowDesc) { } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrKeysetSizeUnsupported) { - ValidateSetStmtAttr(stmt, SQL_ATTR_KEYSET_SIZE, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_KEYSET_SIZE, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMaxLength) { - ValidateSetStmtAttr(stmt, SQL_ATTR_MAX_LENGTH, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_MAX_LENGTH, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMaxRows) { // Cannot set read-only attribute - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_MAX_ROWS, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_MAX_ROWS, static_cast(0), SQL_ERROR, kErrorStateHY092); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrMetadataID) { - ValidateSetStmtAttr(stmt, SQL_ATTR_METADATA_ID, static_cast(SQL_FALSE)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_METADATA_ID, static_cast(SQL_FALSE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrNoscan) { - ValidateSetStmtAttr(stmt, SQL_ATTR_NOSCAN, static_cast(SQL_NOSCAN_OFF)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_NOSCAN, static_cast(SQL_NOSCAN_OFF)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamBindOffsetPtr) { SQLULEN offset = 1000; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, static_cast(&offset)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(&offset), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamBindType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_TYPE, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_BIND_TYPE, static_cast(SQL_PARAM_BIND_BY_COLUMN)); } @@ -540,11 +547,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamOperationPtr) { SQLUSMALLINT param_operations[param_set_size] = {SQL_PARAM_PROCEED, SQL_PARAM_IGNORE, SQL_PARAM_PROCEED, SQL_PARAM_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, static_cast(param_operations)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_OPERATION_PTR, &value); EXPECT_EQ(static_cast(param_operations), value); } @@ -555,11 +562,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamStatusPtr) { SQLUSMALLINT param_status[param_status_size] = {SQL_PARAM_PROCEED, SQL_PARAM_IGNORE, SQL_PARAM_PROCEED, SQL_PARAM_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, static_cast(param_status)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAM_STATUS_PTR, &value); EXPECT_EQ(static_cast(param_status), value); } @@ -567,50 +574,51 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamStatusPtr) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamsProcessedPtr) { SQLULEN processed_count = 0; - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, static_cast(&processed_count)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &value); EXPECT_EQ(static_cast(&processed_count), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrParamsetSize) { - ValidateSetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_PARAMSET_SIZE, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrQueryTimeout) { - ValidateSetStmtAttr(stmt, SQL_ATTR_QUERY_TIMEOUT, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_QUERY_TIMEOUT, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRetrieveData) { - ValidateSetStmtAttr(stmt, SQL_ATTR_RETRIEVE_DATA, static_cast(SQL_RD_ON)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_RETRIEVE_DATA, + static_cast(SQL_RD_ON)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowArraySize) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, static_cast(1)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowBindOffsetPtr) { SQLULEN offset = 1000; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, static_cast(&offset)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, &value); EXPECT_EQ(static_cast(&offset), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowBindType) { - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, static_cast(0)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_BIND_TYPE, static_cast(0)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowNumber) { // Cannot set read-only attribute - ValidateSetStmtAttrErrorCode(stmt, SQL_ATTR_ROW_NUMBER, static_cast(0), + ValidateSetStmtAttrErrorCode(this->stmt, SQL_ATTR_ROW_NUMBER, static_cast(0), SQL_ERROR, kErrorStateHY092); } @@ -619,11 +627,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowOperationPtr) { SQLUSMALLINT row_operations[param_set_size] = {SQL_ROW_PROCEED, SQL_ROW_IGNORE, SQL_ROW_PROCEED, SQL_ROW_IGNORE}; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, static_cast(row_operations)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_OPERATION_PTR, &value); EXPECT_EQ(static_cast(row_operations), value); } @@ -632,10 +640,11 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowStatusPtr) { constexpr SQLULEN row_status_size = 4; SQLUSMALLINT values[row_status_size] = {0, 0, 0, 0}; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, static_cast(values)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, + static_cast(values)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROW_STATUS_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROW_STATUS_PTR, &value); EXPECT_EQ(static_cast(values), value); } @@ -643,27 +652,28 @@ TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowStatusPtr) { TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowsFetchedPtr) { SQLULEN rows_fetched = 1; - ValidateSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, static_cast(&rows_fetched)); SQLPOINTER value = nullptr; - GetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); + GetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &value); EXPECT_EQ(static_cast(&rows_fetched), value); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrSimulateCursor) { - ValidateSetStmtAttr(stmt, SQL_ATTR_SIMULATE_CURSOR, + ValidateSetStmtAttr(this->stmt, SQL_ATTR_SIMULATE_CURSOR, static_cast(SQL_SC_UNIQUE)); } TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrUseBookmarks) { - ValidateSetStmtAttr(stmt, SQL_ATTR_USE_BOOKMARKS, static_cast(SQL_UB_OFF)); + ValidateSetStmtAttr(this->stmt, SQL_ATTR_USE_BOOKMARKS, + static_cast(SQL_UB_OFF)); } // This is a pre ODBC 3 attribute TYPED_TEST(StatementAttributeTest, TestSQLSetStmtAttrRowsetSize) { - ValidateSetStmtAttr(stmt, SQL_ROWSET_SIZE, static_cast(1)); + ValidateSetStmtAttr(this->stmt, SQL_ROWSET_SIZE, static_cast(1)); } } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc index dd33ce9ae973..3e80bfab110a 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/statement_test.cc @@ -38,85 +38,81 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned EXPECT_EQ(1, val); - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(1, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLExecDirectInvalidQuery) { - 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)); + ASSERT_EQ(SQL_ERROR, SQLExecDirect(this->stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); } TYPED_TEST(StatementTest, TestSQLExecuteSimpleQuery) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLPrepare(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLExecute(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLExecute(this->stmt)); // Fetch data - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned EXPECT_EQ(1, val); - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(1, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLPrepareInvalidQuery) { - 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)); + ASSERT_EQ(SQL_ERROR, SQLPrepare(this->stmt, wsql, wsql_len)); // ODBC provides generic error code HY000 to all statement errors - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); - ASSERT_EQ(SQL_ERROR, SQLExecute(stmt)); + ASSERT_EQ(SQL_ERROR, SQLExecute(this->stmt)); // Verify function sequence error state is returned #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ } @@ -125,9 +121,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types @@ -137,84 +133,88 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), stiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 2, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), stiny_int_val); // Unsigned Tiny Int uint8_t utiny_int_val; buf_len = sizeof(utiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 3, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), utiny_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 4, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), utiny_int_val); // Signed Small Int int16_t ssmall_int_val; buf_len = sizeof(ssmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 5, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ssmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 6, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ssmall_int_val); // Unsigned Small Int uint16_t usmall_int_val; buf_len = sizeof(usmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 7, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 7, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), usmall_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 8, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 8, SQL_C_USHORT, &usmall_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), usmall_int_val); // Signed Integer SQLINTEGER slong_val; buf_len = sizeof(slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 9, SQL_C_SLONG, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 9, SQL_C_SLONG, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 10, SQL_C_SLONG, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 10, SQL_C_SLONG, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Unsigned Integer SQLUINTEGER ulong_val; buf_len = sizeof(ulong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 11, SQL_C_ULONG, &ulong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 11, SQL_C_ULONG, &ulong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ulong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 12, SQL_C_ULONG, &ulong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 12, SQL_C_ULONG, &ulong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ulong_val); // Signed Big Int SQLBIGINT sbig_int_val; buf_len = sizeof(sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Unsigned Big Int SQLUBIGINT ubig_int_val; buf_len = sizeof(ubig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 15, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ubig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 16, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ubig_int_val); // Decimal @@ -222,7 +222,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { memset(&decimal_val, 0, sizeof(decimal_val)); buf_len = sizeof(SQL_NUMERIC_STRUCT); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 17, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -232,7 +232,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { memset(&decimal_val, 0, sizeof(decimal_val)); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 18, SQL_C_NUMERIC, &decimal_val, buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -243,30 +243,34 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Float float float_val; buf_len = sizeof(float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 19, SQL_C_FLOAT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 19, SQL_C_FLOAT, &float_val, buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 20, SQL_C_FLOAT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 20, SQL_C_FLOAT, &float_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; buf_len = sizeof(double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 21, SQL_C_DOUBLE, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 21, SQL_C_DOUBLE, &double_val, buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 22, SQL_C_DOUBLE, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 22, SQL_C_DOUBLE, &double_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; buf_len = sizeof(bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 23, SQL_C_BIT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 23, SQL_C_BIT, &bit_val, buf_len, &ind)); EXPECT_EQ(false, bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 24, SQL_C_BIT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 24, SQL_C_BIT, &bit_val, buf_len, &ind)); EXPECT_EQ(true, bit_val); // Characters @@ -274,27 +278,31 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Char SQLCHAR char_val[2]; buf_len = sizeof(SQLCHAR) * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); EXPECT_EQ('Z', char_val[0]); // WChar SQLWCHAR wchar_val[2]; size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wchar_val[0]); // WVarchar SQLWCHAR wvarchar_val[3]; buf_len = wchar_size * 3; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wvarchar_val[0]); EXPECT_EQ(L'好', wvarchar_val[1]); // varchar SQLCHAR varchar_val[4]; buf_len = sizeof(SQLCHAR) * 4; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); EXPECT_EQ('X', varchar_val[0]); EXPECT_EQ('Y', varchar_val[1]); EXPECT_EQ('Z', varchar_val[2]); @@ -304,13 +312,15 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Date SQL_DATE_STRUCT date_var{}; buf_len = sizeof(date_var); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 29, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 29, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 30, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 30, SQL_C_TYPE_DATE, &date_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -319,8 +329,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { // Timestamp SQL_TIMESTAMP_STRUCT timestamp_var{}; buf_len = sizeof(timestamp_var); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); EXPECT_EQ(1, timestamp_var.month); @@ -330,8 +340,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectDataQuery) { EXPECT_EQ(0, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); EXPECT_EQ(12, timestamp_var.month); @@ -346,28 +356,29 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQL_TIME_STRUCT time_var{}; SQLLEN buf_len = sizeof(time_var); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); // Check min values for time. EXPECT_EQ(0, time_var.hour); EXPECT_EQ(0, time_var.minute); EXPECT_EQ(0, time_var.second); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 2, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 2, SQL_C_TYPE_TIME, &time_var, buf_len, &ind)); // Check max values for time. EXPECT_EQ(23, time_var.hour); EXPECT_EQ(59, time_var.minute); @@ -378,22 +389,21 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } // Tests with SQL_C_DEFAULT as the target type @@ -405,9 +415,9 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types // Signed Integer @@ -415,10 +425,12 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { SQLLEN buf_len = sizeof(slong_val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 9, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 9, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 10, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 10, SQL_C_DEFAULT, &slong_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Signed Big Int @@ -426,11 +438,11 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 13, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); + SQLGetData(this->stmt, 14, SQL_C_DEFAULT, &sbig_int_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Decimal @@ -439,7 +451,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(SQL_NUMERIC_STRUCT); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 17, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -449,7 +461,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { memset(&decimal_val, 0, sizeof(decimal_val)); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); + SQLGetData(this->stmt, 18, SQL_C_DEFAULT, &decimal_val, buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -461,32 +473,38 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { float float_val; buf_len = sizeof(float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 19, SQL_C_DEFAULT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 19, SQL_C_DEFAULT, &float_val, buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 20, SQL_C_DEFAULT, &float_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 20, SQL_C_DEFAULT, &float_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; buf_len = sizeof(double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 21, SQL_C_DEFAULT, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 21, SQL_C_DEFAULT, &double_val, buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 22, SQL_C_DEFAULT, &double_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 22, SQL_C_DEFAULT, &double_val, buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; buf_len = sizeof(bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 23, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 23, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); EXPECT_EQ(false, bit_val); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 24, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 24, SQL_C_DEFAULT, &bit_val, buf_len, &ind)); EXPECT_EQ(true, bit_val); // Characters @@ -496,13 +514,15 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 25, SQL_C_DEFAULT, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 25, SQL_C_DEFAULT, &wchar_val, buf_len, &ind)); EXPECT_EQ(L'Z', wchar_val[0]); // WChar SQLWCHAR wchar_val2[2]; buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 26, SQL_C_DEFAULT, &wchar_val2, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 26, SQL_C_DEFAULT, &wchar_val2, buf_len, &ind)); EXPECT_EQ(L'你', wchar_val2[0]); // WVarchar @@ -510,7 +530,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = wchar_size * 3; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 27, SQL_C_DEFAULT, &wvarchar_val, buf_len, &ind)); + SQLGetData(this->stmt, 27, SQL_C_DEFAULT, &wvarchar_val, buf_len, &ind)); EXPECT_EQ(L'你', wvarchar_val[0]); EXPECT_EQ(L'好', wvarchar_val[1]); @@ -519,7 +539,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = wchar_size * 4; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 28, SQL_C_DEFAULT, &wvarchar_val2, buf_len, &ind)); + SQLGetData(this->stmt, 28, SQL_C_DEFAULT, &wvarchar_val2, buf_len, &ind)); EXPECT_EQ(L'X', wvarchar_val2[0]); EXPECT_EQ(L'Y', wvarchar_val2[1]); EXPECT_EQ(L'Z', wvarchar_val2[2]); @@ -530,13 +550,15 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { SQL_DATE_STRUCT date_var{}; buf_len = sizeof(date_var); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 29, SQL_C_DEFAULT, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 29, SQL_C_DEFAULT, &date_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 30, SQL_C_DEFAULT, &date_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 30, SQL_C_DEFAULT, &date_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -547,7 +569,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { buf_len = sizeof(timestamp_var); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 31, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); + SQLGetData(this->stmt, 31, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); EXPECT_EQ(1, timestamp_var.month); @@ -558,7 +580,7 @@ TEST_F(StatementRemoteTest, TestSQLExecDirectDataQueryDefaultType) { EXPECT_EQ(0, timestamp_var.fraction); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 32, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); + SQLGetData(this->stmt, 32, SQL_C_DEFAULT, ×tamp_var, buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); EXPECT_EQ(12, timestamp_var.month); @@ -573,28 +595,29 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQL_TIME_STRUCT time_var{}; SQLLEN buf_len = sizeof(time_var); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &time_var, buf_len, &ind)); // Check min values for time. EXPECT_EQ(0, time_var.hour); EXPECT_EQ(0, time_var.minute); EXPECT_EQ(0, time_var.second); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 2, SQL_C_DEFAULT, &time_var, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 2, SQL_C_DEFAULT, &time_var, buf_len, &ind)); // Check max values for time. EXPECT_EQ(23, time_var.hour); EXPECT_EQ(59, time_var.minute); @@ -606,39 +629,38 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_DEFAULT, &varbinary_val[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &varbinary_val[0], buf_len, &ind)); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } // 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Get precision and scale from IRD SQLLEN ird_precision = 0; SQLLEN ird_scale = 0; SQLHDESC ird = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_IMP_ROW_DESC, &ird, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_IMP_ROW_DESC, &ird, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLGetDescField(ird, 1, SQL_DESC_PRECISION, &ird_precision, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLGetDescField(ird, 1, SQL_DESC_SCALE, &ird_scale, 0, nullptr)); @@ -647,7 +669,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { SQL_NUMERIC_STRUCT numeric_val; memset(&numeric_val, 0, sizeof(numeric_val)); SQLLEN indicator; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_NUMERIC, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_NUMERIC, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(static_cast(ird_precision), numeric_val.precision); EXPECT_EQ(static_cast(ird_scale), numeric_val.scale); @@ -655,14 +677,15 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesIRDAsDefault) { // Test with SQL_C_DEFAULT when ARD is unset (0) - should fall back to IRD // precision/scale SQLHDESC ard = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); ASSERT_EQ(SQL_SUCCESS, SQLSetDescField(ard, 1, SQL_DESC_PRECISION, reinterpret_cast(0), 0)); ASSERT_EQ(SQL_SUCCESS, SQLSetDescField(ard, 1, SQL_DESC_SCALE, reinterpret_cast(0), 0)); memset(&numeric_val, 0, sizeof(numeric_val)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(static_cast(ird_precision), numeric_val.precision); EXPECT_EQ(static_cast(ird_scale), numeric_val.scale); @@ -672,15 +695,15 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLHDESC ard = nullptr; - ASSERT_EQ(SQL_SUCCESS, SQLGetStmtAttr(stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetStmtAttr(this->stmt, SQL_ATTR_APP_ROW_DESC, &ard, 0, nullptr)); // Test with SQL_ARD_TYPE SQLSMALLINT ard_precision = 15; @@ -695,7 +718,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { SQL_NUMERIC_STRUCT numeric_val; memset(&numeric_val, 0, sizeof(numeric_val)); SQLLEN indicator; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_ARD_TYPE, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_ARD_TYPE, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(ard_precision, numeric_val.precision); EXPECT_EQ(ard_scale, numeric_val.scale); @@ -709,7 +732,7 @@ TYPED_TEST(StatementTest, DISABLED_TestGetDataPrecisionScaleUsesARDWhenSet) { reinterpret_cast(ard_scale), 0)); memset(&numeric_val, 0, sizeof(numeric_val)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_DEFAULT, &numeric_val, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_DEFAULT, &numeric_val, sizeof(SQL_NUMERIC_STRUCT), &indicator)); EXPECT_EQ(ard_precision, numeric_val.precision); EXPECT_EQ(ard_scale, numeric_val.scale); @@ -717,109 +740,107 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLGUID guid_var; SQLLEN buf_len = sizeof(guid_var); SQLLEN ind; - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_GUID, &guid_var, buf_len, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_GUID, &guid_var, buf_len, &ind)); // GUID is not supported by ODBC - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY000); } TYPED_TEST(StatementTest, TestSQLExecDirectRowFetching) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; SQLLEN buf_len = sizeof(val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 1 is returned EXPECT_EQ(1, val); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 2 is returned EXPECT_EQ(2, val); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 3 is returned EXPECT_EQ(3, val); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(3, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { SQLLEN rows_fetched; - SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0); + SQLSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); SQLINTEGER val; SQLLEN buf_len = sizeof(val); SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 1 is returned EXPECT_EQ(1, val); // Verify 1 row is fetched EXPECT_EQ(1, rows_fetched); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 2 is returned EXPECT_EQ(2, val); @@ -827,9 +848,9 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { EXPECT_EQ(1, rows_fetched); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); // Verify 3 is returned EXPECT_EQ(3, val); @@ -837,74 +858,72 @@ TYPED_TEST(StatementTest, TestSQLFetchScrollRowFetching) { EXPECT_EQ(1, rows_fetched); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0)); + ASSERT_EQ(SQL_NO_DATA, SQLFetchScroll(this->stmt, SQL_FETCH_NEXT, 0)); #ifdef __APPLE__ // With iODBC we expect SQL_SUCCESS and the buffer unchanged in this situation. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); EXPECT_EQ(3, val); #else - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Invalid cursor state - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); #endif } 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_PRIOR, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_PRIOR, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); SQLLEN fetch_offset = 1; - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_RELATIVE, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_RELATIVE, fetch_offset)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_ABSOLUTE, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_ABSOLUTE, fetch_offset)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_FIRST, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_FIRST, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_LAST, 0)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_LAST, 0)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); - ASSERT_EQ(SQL_ERROR, SQLFetchScroll(stmt, SQL_FETCH_BOOKMARK, fetch_offset)); + ASSERT_EQ(SQL_ERROR, SQLFetchScroll(this->stmt, SQL_FETCH_BOOKMARK, fetch_offset)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHYC00); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHYC00); #else // Windows DM returns state HY106 for SQL_FETCH_BOOKMARK - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY106); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY106); #endif // __APPLE__ } TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 17; SQLCHAR char_val[len]; SQLLEN buf_len = sizeof(SQLCHAR) * len; SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); EXPECT_EQ(std::string("VERY LONG STRING"), ODBC::SqlStringToString(char_val)); EXPECT_EQ(21, ind); @@ -914,9 +933,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { SQLCHAR char_val2[len2]; buf_len = sizeof(SQLCHAR) * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_CHAR, &char_val2, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val2, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); EXPECT_EQ(std::string(" "), ODBC::SqlStringToString(char_val2)); EXPECT_EQ(5, ind); @@ -927,7 +946,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { buf_len = sizeof(SQLCHAR) * len3; // Verify that there is no more truncation reports. The full string has been fetched. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_CHAR, &char_val3, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val3, buf_len, &ind)); EXPECT_EQ(std::string("here"), ODBC::SqlStringToString(char_val3)); EXPECT_EQ(4, ind); @@ -935,16 +955,16 @@ TYPED_TEST(StatementTest, TestSQLExecDirectVarcharTruncation) { // Attempt to fetch data 4th time SQLCHAR char_val4[len]; // Verify SQL_NO_DATA is returned - ASSERT_EQ(SQL_NO_DATA, SQLGetData(stmt, 1, SQL_C_CHAR, &char_val4, 0, &ind)); + ASSERT_EQ(SQL_NO_DATA, SQLGetData(this->stmt, 1, SQL_C_CHAR, &char_val4, 0, &ind)); } TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); const int len = 28; SQLWCHAR wchar_val[len]; @@ -952,11 +972,12 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { SQLLEN buf_len = wchar_size * len; SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); - 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 @@ -964,11 +985,12 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { SQLWCHAR wchar_val2[len2]; buf_len = wchar_size * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val2, buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val2, buf_len, &ind)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); - 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 @@ -977,39 +999,40 @@ TYPED_TEST(StatementTest, TestSQLExecDirectWVarcharTruncation) { buf_len = wchar_size * len3; // Verify that there is no more truncation reports. The full string has been fetched. - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val3, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val3, buf_len, &ind)); - 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 SQLWCHAR wchar_val4[len]; // Verify SQL_NO_DATA is returned - ASSERT_EQ(SQL_NO_DATA, SQLGetData(stmt, 1, SQL_C_WCHAR, &wchar_val4, 0, &ind)); + ASSERT_EQ(SQL_NO_DATA, SQLGetData(this->stmt, 1, SQL_C_WCHAR, &wchar_val4, 0, &ind)); } TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { // 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // varbinary std::vector varbinary_val(3); SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); // Verify binary truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); EXPECT_EQ(4, ind); // Fetch same column 2nd time @@ -1018,9 +1041,9 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { // Verify that there is no more truncation reports. The full binary has been fetched. ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val2[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val2[0], buf_len, &ind)); - EXPECT_EQ('\xAB', varbinary_val[0]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); EXPECT_EQ(1, ind); // Attempt to fetch data 3rd time @@ -1028,7 +1051,7 @@ TEST_F(StatementMockTest, TestSQLExecDirectVarbinaryTruncation) { buf_len = varbinary_val3.size(); // Verify SQL_NO_DATA is returned ASSERT_EQ(SQL_NO_DATA, - SQLGetData(stmt, 1, SQL_C_BINARY, &varbinary_val3[0], buf_len, &ind)); + SQLGetData(this->stmt, 1, SQL_C_BINARY, &varbinary_val3[0], buf_len, &ind)); } TYPED_TEST(StatementTest, DISABLED_TestSQLExecDirectFloatTruncation) { @@ -1043,16 +1066,16 @@ TYPED_TEST(StatementTest, DISABLED_TestSQLExecDirectFloatTruncation) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); int16_t ssmall_int_val; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 1, SQL_C_SSHORT, &ssmall_int_val, 0, nullptr)); + SQLGetData(this->stmt, 1, SQL_C_SSHORT, &ssmall_int_val, 0, nullptr)); // Verify float truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01S07); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01S07); EXPECT_EQ(1, ssmall_int_val); } @@ -1061,17 +1084,16 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); // Verify SQL_NULL_DATA is returned for indicator EXPECT_EQ(SQL_NULL_DATA, ind); @@ -1082,21 +1104,20 @@ 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify 1 is returned for non-truncation case. EXPECT_EQ(1, val); @@ -1105,9 +1126,9 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { SQLCHAR char_val[len]; SQLLEN buf_len = sizeof(SQLCHAR) * len; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 2, SQL_C_CHAR, &char_val, buf_len, nullptr)); + SQLGetData(this->stmt, 2, SQL_C_CHAR, &char_val, buf_len, nullptr)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); // WChar const int len2 = 28; @@ -1115,40 +1136,39 @@ TEST_F(StatementMockTest, TestSQLExecDirectTruncationQueryNullIndicator) { size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * len2; ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 3, SQL_C_WCHAR, &wchar_val, buf_len, nullptr)); + SQLGetData(this->stmt, 3, SQL_C_WCHAR, &wchar_val, buf_len, nullptr)); // Verify string truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); // varbinary std::vector varbinary_val(3); buf_len = varbinary_val.size(); ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLGetData(stmt, 4, SQL_C_BINARY, &varbinary_val[0], buf_len, nullptr)); + SQLGetData(this->stmt, 4, SQL_C_BINARY, &varbinary_val[0], buf_len, nullptr)); // Verify binary truncation is reported - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState01004); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState01004); } TEST_F(StatementRemoteTest, TestSQLExecDirectNullQueryNullIndicator) { // 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); SQLINTEGER val; - ASSERT_EQ(SQL_ERROR, SQLGetData(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_ERROR, SQLGetData(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); // Verify invalid null indicator is reported, as it is required - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } -// MacOS Driver Manager iODBC returns SQL_ERROR when invalid buffer length is provided to -// SQLGetData -#ifndef __APPLE__ +// The MacOS and Linux Driver Managers return SQL_ERROR when invalid buffer length is +// provided to SQLGetData +#ifdef _WIN32 TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { // Verify the driver ignores invalid buffer length for fixed data types @@ -1156,9 +1176,9 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Numeric Types @@ -1167,91 +1187,91 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { SQLLEN invalid_buf_len = -1; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 1, SQL_C_STINYINT, &stiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), stiny_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 2, SQL_C_STINYINT, &stiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), stiny_int_val); // Unsigned Tiny Int uint8_t utiny_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 3, SQL_C_UTINYINT, &utiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), utiny_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 4, SQL_C_UTINYINT, &utiny_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), utiny_int_val); // Signed Small Int int16_t ssmall_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 5, SQL_C_SSHORT, &ssmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ssmall_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 6, SQL_C_SSHORT, &ssmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ssmall_int_val); // Unsigned Small Int uint16_t usmall_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 7, SQL_C_USHORT, &usmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 7, SQL_C_USHORT, &usmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), usmall_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 8, SQL_C_USHORT, &usmall_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 8, SQL_C_USHORT, &usmall_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), usmall_int_val); // Signed Integer SQLINTEGER slong_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 9, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 9, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), slong_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 10, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 10, SQL_C_SLONG, &slong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), slong_val); // Unsigned Integer SQLUINTEGER ulong_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 11, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 11, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ulong_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 12, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 12, SQL_C_ULONG, &ulong_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ulong_val); // Signed Big Int SQLBIGINT sbig_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 13, SQL_C_SBIGINT, &sbig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), sbig_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 14, SQL_C_SBIGINT, &sbig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), sbig_int_val); // Unsigned Big Int SQLUBIGINT ubig_int_val; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 15, SQL_C_UBIGINT, &ubig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::min(), ubig_int_val); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 16, SQL_C_UBIGINT, &ubig_int_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val, + invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), ubig_int_val); // Decimal SQL_NUMERIC_STRUCT decimal_val; memset(&decimal_val, 0, sizeof(decimal_val)); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 17, SQL_C_NUMERIC, &decimal_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 17, SQL_C_NUMERIC, &decimal_val, + invalid_buf_len, &ind)); // Check for negative decimal_val value EXPECT_EQ(0, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -1261,8 +1281,8 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { memset(&decimal_val, 0, sizeof(decimal_val)); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 18, SQL_C_NUMERIC, &decimal_val, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 18, SQL_C_NUMERIC, &decimal_val, + invalid_buf_len, &ind)); // Check for positive decimal_val value EXPECT_EQ(1, decimal_val.sign); EXPECT_EQ(0, decimal_val.scale); @@ -1274,48 +1294,48 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { float float_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 19, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 19, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); // Get minimum negative float value EXPECT_EQ(-std::numeric_limits::max(), float_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 20, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 20, SQL_C_FLOAT, &float_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), float_val); // Double SQLDOUBLE double_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 21, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 21, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); // Get minimum negative double value EXPECT_EQ(-std::numeric_limits::max(), double_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 22, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 22, SQL_C_DOUBLE, &double_val, invalid_buf_len, &ind)); EXPECT_EQ(std::numeric_limits::max(), double_val); // Bit bool bit_val; ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 23, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 23, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); EXPECT_EQ(false, bit_val); ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 24, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); + SQLGetData(this->stmt, 24, SQL_C_BIT, &bit_val, invalid_buf_len, &ind)); EXPECT_EQ(true, bit_val); // Date and Timestamp // Date SQL_DATE_STRUCT date_var{}; - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 29, SQL_C_TYPE_DATE, &date_var, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 29, SQL_C_TYPE_DATE, &date_var, + invalid_buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, date_var.day); EXPECT_EQ(1, date_var.month); EXPECT_EQ(1400, date_var.year); - ASSERT_EQ(SQL_SUCCESS, - SQLGetData(stmt, 30, SQL_C_TYPE_DATE, &date_var, invalid_buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 30, SQL_C_TYPE_DATE, &date_var, + invalid_buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, date_var.day); EXPECT_EQ(12, date_var.month); @@ -1324,7 +1344,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { // Timestamp SQL_TIMESTAMP_STRUCT timestamp_var{}; - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_var, invalid_buf_len, &ind)); // Check min values for date. Min valid year is 1400. EXPECT_EQ(1, timestamp_var.day); @@ -1335,7 +1355,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { EXPECT_EQ(0, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); - ASSERT_EQ(SQL_SUCCESS, SQLGetData(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, + ASSERT_EQ(SQL_SUCCESS, SQLGetData(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_var, invalid_buf_len, &ind)); // Check max values for date. Max valid year is 9999. EXPECT_EQ(31, timestamp_var.day); @@ -1346,7 +1366,7 @@ TYPED_TEST(StatementTest, TestSQLExecDirectIgnoreInvalidBufLen) { EXPECT_EQ(59, timestamp_var.second); EXPECT_EQ(0, timestamp_var.fraction); } -#endif // __APPLE__ +#endif // _WIN32 TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { // Numeric Types @@ -1358,79 +1378,80 @@ TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_STINYINT, &stiny_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 2, SQL_C_STINYINT, &stiny_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 2, SQL_C_STINYINT, &stiny_int_val_max, buf_len, &ind)); // Unsigned Tiny Int uint8_t utiny_int_val_min; uint8_t utiny_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 3, SQL_C_UTINYINT, &utiny_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 3, SQL_C_UTINYINT, &utiny_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 4, SQL_C_UTINYINT, &utiny_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 4, SQL_C_UTINYINT, &utiny_int_val_max, buf_len, &ind)); // Signed Small Int int16_t ssmall_int_val_min; int16_t ssmall_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 5, SQL_C_SSHORT, &ssmall_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 5, SQL_C_SSHORT, &ssmall_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 6, SQL_C_SSHORT, &ssmall_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 6, SQL_C_SSHORT, &ssmall_int_val_max, buf_len, &ind)); // Unsigned Small Int uint16_t usmall_int_val_min; uint16_t usmall_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 7, SQL_C_USHORT, &usmall_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 7, SQL_C_USHORT, &usmall_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 8, SQL_C_USHORT, &usmall_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 8, SQL_C_USHORT, &usmall_int_val_max, buf_len, &ind)); // Signed Integer SQLINTEGER slong_val_min; SQLINTEGER slong_val_max; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 9, SQL_C_SLONG, &slong_val_min, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 9, SQL_C_SLONG, &slong_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 10, SQL_C_SLONG, &slong_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 10, SQL_C_SLONG, &slong_val_max, buf_len, &ind)); // Unsigned Integer SQLUINTEGER ulong_val_min; SQLUINTEGER ulong_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 11, SQL_C_ULONG, &ulong_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 11, SQL_C_ULONG, &ulong_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 12, SQL_C_ULONG, &ulong_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 12, SQL_C_ULONG, &ulong_val_max, buf_len, &ind)); // Signed Big Int SQLBIGINT sbig_int_val_min; SQLBIGINT sbig_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 13, SQL_C_SBIGINT, &sbig_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 13, SQL_C_SBIGINT, &sbig_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 14, SQL_C_SBIGINT, &sbig_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 14, SQL_C_SBIGINT, &sbig_int_val_max, buf_len, &ind)); // Unsigned Big Int SQLUBIGINT ubig_int_val_min; SQLUBIGINT ubig_int_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 15, SQL_C_UBIGINT, &ubig_int_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 15, SQL_C_UBIGINT, &ubig_int_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 16, SQL_C_UBIGINT, &ubig_int_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 16, SQL_C_UBIGINT, &ubig_int_val_max, buf_len, &ind)); // Decimal SQL_NUMERIC_STRUCT decimal_val_neg; @@ -1439,87 +1460,93 @@ TYPED_TEST(StatementTest, TestSQLBindColDataQuery) { memset(&decimal_val_pos, 0, sizeof(decimal_val_pos)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 17, SQL_C_NUMERIC, &decimal_val_neg, buf_len, &ind)); + SQLBindCol(this->stmt, 17, SQL_C_NUMERIC, &decimal_val_neg, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 18, SQL_C_NUMERIC, &decimal_val_pos, buf_len, &ind)); + SQLBindCol(this->stmt, 18, SQL_C_NUMERIC, &decimal_val_pos, buf_len, &ind)); // Float float float_val_min; float float_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 19, SQL_C_FLOAT, &float_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 19, SQL_C_FLOAT, &float_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 20, SQL_C_FLOAT, &float_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 20, SQL_C_FLOAT, &float_val_max, buf_len, &ind)); // Double SQLDOUBLE double_val_min; SQLDOUBLE double_val_max; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 21, SQL_C_DOUBLE, &double_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 21, SQL_C_DOUBLE, &double_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 22, SQL_C_DOUBLE, &double_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 22, SQL_C_DOUBLE, &double_val_max, buf_len, &ind)); // Bit bool bit_val_false; bool bit_val_true; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 23, SQL_C_BIT, &bit_val_false, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 23, SQL_C_BIT, &bit_val_false, buf_len, &ind)); - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 24, SQL_C_BIT, &bit_val_true, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 24, SQL_C_BIT, &bit_val_true, buf_len, &ind)); // Characters SQLCHAR char_val[2]; buf_len = sizeof(SQLCHAR) * 2; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &ind)); SQLWCHAR wchar_val[2]; size_t wchar_size = GetSqlWCharSize(); buf_len = wchar_size * 2; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 26, SQL_C_WCHAR, &wchar_val, buf_len, &ind)); SQLWCHAR wvarchar_val[3]; buf_len = wchar_size * 3; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 27, SQL_C_WCHAR, &wvarchar_val, buf_len, &ind)); SQLCHAR varchar_val[4]; buf_len = sizeof(SQLCHAR) * 4; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 28, SQL_C_CHAR, &varchar_val, buf_len, &ind)); // Date and Timestamp SQL_DATE_STRUCT date_val_min{}, date_val_max{}; buf_len = 0; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 29, SQL_C_TYPE_DATE, &date_val_min, buf_len, &ind)); + SQLBindCol(this->stmt, 29, SQL_C_TYPE_DATE, &date_val_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 30, SQL_C_TYPE_DATE, &date_val_max, buf_len, &ind)); + SQLBindCol(this->stmt, 30, SQL_C_TYPE_DATE, &date_val_max, buf_len, &ind)); SQL_TIMESTAMP_STRUCT timestamp_val_min{}, timestamp_val_max{}; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 31, SQL_C_TYPE_TIMESTAMP, ×tamp_val_min, - buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 31, SQL_C_TYPE_TIMESTAMP, + ×tamp_val_min, buf_len, &ind)); - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 32, SQL_C_TYPE_TIMESTAMP, ×tamp_val_max, - buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 32, SQL_C_TYPE_TIMESTAMP, + ×tamp_val_max, buf_len, &ind)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Data verification @@ -1627,21 +1654,20 @@ TEST_F(StatementRemoteTest, TestSQLBindColTimeQuery) { SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_TYPE_TIME, &time_var_min, buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_TYPE_TIME, &time_var_min, buf_len, &ind)); ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 2, SQL_C_TYPE_TIME, &time_var_max, buf_len, &ind)); + SQLBindCol(this->stmt, 2, SQL_C_TYPE_TIME, &time_var_max, buf_len, &ind)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Check min values for time. EXPECT_EQ(0, time_var_min.hour); @@ -1663,19 +1689,18 @@ TEST_F(StatementMockTest, TestSQLBindColVarbinaryQuery) { SQLLEN buf_len = varbinary_val.size(); SQLLEN ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); + SQLBindCol(this->stmt, 1, SQL_C_BINARY, &varbinary_val[0], buf_len, &ind)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Check varbinary values - EXPECT_EQ('\xAB', varbinary_val[0]); - EXPECT_EQ('\xCD', varbinary_val[1]); - EXPECT_EQ('\xEF', varbinary_val[2]); + EXPECT_EQ(static_cast('\xAB'), static_cast(varbinary_val[0])); + EXPECT_EQ(static_cast('\xCD'), static_cast(varbinary_val[1])); + EXPECT_EQ(static_cast('\xEF'), static_cast(varbinary_val[2])); } TEST_F(StatementRemoteTest, TestSQLBindColNullQuery) { @@ -1685,14 +1710,13 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQuery) { SQLINTEGER val; SQLLEN ind; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, &ind)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify SQL_NULL_DATA is returned for indicator EXPECT_EQ(SQL_NULL_DATA, ind); @@ -1704,16 +1728,15 @@ TEST_F(StatementRemoteTest, TestSQLBindColNullQueryNullIndicator) { SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, 0)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, 0)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_ERROR, SQLFetch(stmt)); + ASSERT_EQ(SQL_ERROR, SQLFetch(this->stmt)); // Verify invalid null indicator is reported, as it is required - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { @@ -1723,40 +1746,39 @@ TYPED_TEST(StatementTest, TestSQLBindColRowFetching) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, buf_len, &ind)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 1 is returned EXPECT_EQ(1, val); // Fetch row 2 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 2 is returned EXPECT_EQ(2, val); // Fetch row 3 - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 3 is returned EXPECT_EQ(3, val); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { @@ -1769,29 +1791,28 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, val, buf_len, ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, val, buf_len, ind)); SQLLEN rows_fetched; ASSERT_EQ(SQL_SUCCESS, - SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0)); + SQLSetStmtAttr(this->stmt, SQL_ATTR_ROWS_FETCHED_PTR, &rows_fetched, 0)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, + ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ATTR_ROW_ARRAY_SIZE, reinterpret_cast(rows), 0)); // Fetch 3 rows at once - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify 3 rows are fetched EXPECT_EQ(3, rows_fetched); @@ -1804,7 +1825,7 @@ TYPED_TEST(StatementTest, TestSQLBindColRowArraySize) { EXPECT_EQ(3, val[2]); // Verify result set has no more data beyond row 3 - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } TYPED_TEST(StatementTest, DISABLED_TestSQLBindColIndicatorOnly) { @@ -1816,21 +1837,22 @@ TYPED_TEST(StatementTest, DISABLED_TestSQLBindColIndicatorOnly) { // Signed Tiny Int SQLLEN stiny_int_ind; - EXPECT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_STINYINT, 0, 0, &stiny_int_ind)); + EXPECT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_STINYINT, 0, 0, &stiny_int_ind)); // Characters SQLLEN buf_len = sizeof(SQLCHAR) * 2; SQLLEN char_val_ind; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 25, SQL_C_CHAR, 0, buf_len, &char_val_ind)); + ASSERT_EQ(SQL_SUCCESS, + SQLBindCol(this->stmt, 25, SQL_C_CHAR, 0, buf_len, &char_val_ind)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // Verify values for indicator pointer // Signed Tiny Int @@ -1849,26 +1871,26 @@ TYPED_TEST(StatementTest, TestSQLBindColIndicatorOnlySQLUnbind) { int8_t stiny_int_val; SQLLEN stiny_int_ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 1, SQL_C_STINYINT, &stiny_int_val, 0, &stiny_int_ind)); + SQLBindCol(this->stmt, 1, SQL_C_STINYINT, &stiny_int_val, 0, &stiny_int_ind)); // Characters SQLCHAR char_val[2]; SQLLEN buf_len = sizeof(SQLCHAR) * 2; SQLLEN char_val_ind; ASSERT_EQ(SQL_SUCCESS, - SQLBindCol(stmt, 25, SQL_C_CHAR, &char_val, buf_len, &char_val_ind)); + SQLBindCol(this->stmt, 25, SQL_C_CHAR, &char_val, buf_len, &char_val_ind)); // Driver should still be able to execute queries after unbinding columns - EXPECT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_UNBIND)); + EXPECT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_UNBIND)); // Execute query and fetch data once since there is only 1 row. std::wstring wsql = this->GetQueryAllDataTypes(); std::vector sql0(wsql.begin(), wsql.end()); ASSERT_EQ(SQL_SUCCESS, - SQLExecDirect(stmt, &sql0[0], static_cast(sql0.size()))); + SQLExecDirect(this->stmt, &sql0[0], static_cast(sql0.size()))); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); // GH-47021 TODO: implement driver to return indicator value when data pointer is null // and uncomment the checks Verify values for indicator pointer Signed Tiny Int @@ -1888,32 +1910,31 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { // Same variable will be used for column 1, the value of `val` // should be updated after every SQLFetch call. - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, val, buf_len, ind)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, val, buf_len, ind)); - ASSERT_EQ(SQL_SUCCESS, - SQLSetStmtAttr(stmt, SQL_ROWSET_SIZE, reinterpret_cast(rows), 0)); + ASSERT_EQ(SQL_SUCCESS, SQLSetStmtAttr(this->stmt, SQL_ROWSET_SIZE, + reinterpret_cast(rows), 0)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); // Fetch row 1-3. SQLULEN row_count; SQLUSMALLINT row_status[rows]; ASSERT_EQ(SQL_SUCCESS, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count, row_status)); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count, row_status)); EXPECT_EQ(3, row_count); - for (int i = 0; i < rows; i++) { + for (SQLULEN i = 0; i < rows; i++) { EXPECT_EQ(SQL_SUCCESS, row_status[i]); } @@ -1928,7 +1949,7 @@ TYPED_TEST(StatementTest, TestSQLExtendedFetchRowFetching) { SQLULEN row_count2; SQLUSMALLINT row_status2[rows]; EXPECT_EQ(SQL_NO_DATA, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count2, row_status2)); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count2, row_status2)); } TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { @@ -1937,117 +1958,115 @@ TEST_F(StatementRemoteTest, DISABLED_TestSQLExtendedFetchQueryNullIndicator) { // server instead. Mock server has type `DENSE_UNION` for null column data. SQLINTEGER val; - ASSERT_EQ(SQL_SUCCESS, SQLBindCol(stmt, 1, SQL_C_LONG, &val, 0, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLBindCol(this->stmt, 1, SQL_C_LONG, &val, 0, nullptr)); - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); SQLULEN row_count1; SQLUSMALLINT row_status1[1]; // SQLExtendedFetch should return SQL_SUCCESS_WITH_INFO for 22002 state ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &row_count1, row_status1)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState22002); + SQLExtendedFetch(this->stmt, SQL_FETCH_NEXT, 0, &row_count1, row_status1)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState22002); } TYPED_TEST(StatementTest, TestSQLMoreResultsNoData) { // 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(this->stmt)); } TYPED_TEST(StatementTest, TestSQLMoreResultsInvalidFunctionSequence) { // Verify function sequence error state is reported when SQLMoreResults is called // without executing any queries - ASSERT_EQ(SQL_ERROR, SQLMoreResults(stmt)); - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); +#ifdef __linux__ + ASSERT_EQ(SQL_NO_DATA, SQLMoreResults(this->stmt)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState00000); +#else // Windows & Mac + ASSERT_EQ(SQL_ERROR, SQLMoreResults(this->stmt)); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); +#endif } 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, - &output_char_len)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->conn, input_str, input_str_len, buf, + buf_char_len, &output_char_len)); - EXPECT_EQ(input_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, input_str_len); + 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)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->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, input_str_len); 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)); + ASSERT_EQ(SQL_SUCCESS, SQLNativeSql(this->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)); + SQLNativeSql(this->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); + std::copy(input_str, input_str + 10, expected_string_buf); expected_string_buf[10] = L'\0'; std::wstring expected_string(expected_string_buf, expected_string_buf + small_buf_size_in_char); ASSERT_EQ(SQL_SUCCESS_WITH_INFO, - SQLNativeSql(conn, input_str, input_char_len, small_buf, small_buf_char_len, - &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorState01004); + SQLNativeSql(this->conn, input_str, input_str_len, small_buf, + small_buf_char_len, &output_char_len)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorState01004); // Returned text length represents full string char length regardless of truncation - EXPECT_EQ(input_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,77 +2076,74 @@ 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(this->conn, nullptr, input_str_len, buf, buf_char_len, &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY009); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY009); - ASSERT_EQ(SQL_ERROR, - SQLNativeSql(conn, nullptr, SQL_NTS, buf, buf_char_len, &output_char_len)); - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY009); + ASSERT_EQ(SQL_ERROR, SQLNativeSql(this->conn, nullptr, SQL_NTS, buf, buf_char_len, + &output_char_len)); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY009); - ASSERT_EQ(SQL_ERROR, - SQLNativeSql(conn, input_str, -100, buf, buf_char_len, &output_char_len)); + ASSERT_EQ(SQL_ERROR, SQLNativeSql(this->conn, input_str, -100, buf, buf_char_len, + &output_char_len)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateS1090); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateS1090); #else - VerifyOdbcErrorState(SQL_HANDLE_DBC, conn, kErrorStateHY090); + VerifyOdbcErrorState(SQL_HANDLE_DBC, this->conn, kErrorStateHY090); #endif // __APPLE__ } 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(this->stmt, &column_count)); EXPECT_EQ(expected_value, column_count); } 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(stmt, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLNumResultCols(this->stmt, nullptr)); } TYPED_TEST(StatementTest, SQLNumResultColsFunctionSequenceErrorOnNoQuery) { SQLSMALLINT column_count = 0; SQLSMALLINT expected_value = 0; - ASSERT_EQ(SQL_ERROR, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_ERROR, SQLNumResultCols(this->stmt, &column_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ - ASSERT_EQ(SQL_ERROR, SQLNumResultCols(stmt, &column_count)); + ASSERT_EQ(SQL_ERROR, SQLNumResultCols(this->stmt, &column_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ ASSERT_EQ(expected_value, column_count); @@ -2136,80 +2152,80 @@ 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLRowCount(stmt, &row_count)); + ASSERT_EQ(SQL_SUCCESS, SQLRowCount(this->stmt, &row_count)); EXPECT_EQ(expected_value, row_count); } 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(this->stmt, sql_query, sql_query_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFetch(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLFetch(this->stmt)); - CheckIntColumn(stmt, 1, 1); - CheckStringColumnW(stmt, 2, L"One"); - CheckIntColumn(stmt, 3, 3); + CheckIntColumn(this->stmt, 1, 1); + CheckStringColumnW(this->stmt, 2, L"One"); + CheckIntColumn(this->stmt, 3, 3); - ASSERT_EQ(SQL_SUCCESS, SQLRowCount(stmt, nullptr)); + ASSERT_EQ(SQL_SUCCESS, SQLRowCount(this->stmt, nullptr)); } TYPED_TEST(StatementTest, SQLRowCountFunctionSequenceErrorOnNoQuery) { SQLLEN row_count = 0; +#ifdef __linux__ + SQLLEN expected_value = -1; +#else // Windows & Mac SQLLEN expected_value = 0; +#endif - ASSERT_EQ(SQL_ERROR, SQLRowCount(stmt, &row_count)); + ASSERT_EQ(SQL_ERROR, SQLRowCount(this->stmt, &row_count)); #ifdef __APPLE__ - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateS1010); #else - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateHY010); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorStateHY010); #endif // __APPLE__ EXPECT_EQ(expected_value, row_count); } 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_CLOSE)); + ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_CLOSE)); } TYPED_TEST(StatementTest, TestSQLCloseCursor) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLExecDirect(this->stmt, wsql, wsql_len)); - ASSERT_EQ(SQL_SUCCESS, SQLCloseCursor(stmt)); + ASSERT_EQ(SQL_SUCCESS, SQLCloseCursor(this->stmt)); } TYPED_TEST(StatementTest, TestSQLFreeStmtSQLCloseWithoutCursor) { // Verify SQLFreeStmt(SQL_CLOSE) does not throw error with invalid cursor - ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(stmt, SQL_CLOSE)); + ASSERT_EQ(SQL_SUCCESS, SQLFreeStmt(this->stmt, SQL_CLOSE)); } TYPED_TEST(StatementTest, TestSQLCloseCursorWithoutCursor) { - ASSERT_EQ(SQL_ERROR, SQLCloseCursor(stmt)); + ASSERT_EQ(SQL_ERROR, SQLCloseCursor(this->stmt)); // Verify invalid cursor error state is returned - VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorState24000); + VerifyOdbcErrorState(SQL_HANDLE_STMT, this->stmt, kErrorState24000); } } // namespace arrow::flight::sql::odbc diff --git a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc index 60887d216cf2..8d253ab3bcf2 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/tables_test.cc @@ -31,7 +31,7 @@ class TablesTest : public T {}; class TablesMockTest : public FlightSQLODBCMockTestBase {}; class TablesRemoteTest : public FlightSQLODBCRemoteTestBase {}; -using TestTypes = ::testing::Types; +using TestTypes = ::testing::Types; TYPED_TEST_SUITE(TablesTest, TestTypes); template @@ -44,123 +44,127 @@ 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, - sizeof(schema_name), table_name, sizeof(table_name), - table_type, sizeof(table_type))); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, sizeof(catalog_name), + schema_name, sizeof(schema_name), table_name, + sizeof(table_name), table_type, sizeof(table_type))); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, 0, schema_name, 0, table_name, 0, - table_type, 0)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, 0, schema_name, 0, + table_name, 0, table_type, 0)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Names are nulls - EXPECT_EQ(SQL_SUCCESS, - SQLTables(stmt, nullptr, sizeof(catalog_name), nullptr, sizeof(schema_name), - nullptr, sizeof(table_name), nullptr, sizeof(table_type))); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, sizeof(catalog_name), nullptr, + sizeof(schema_name), nullptr, sizeof(table_name), + nullptr, sizeof(table_type))); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); // Close statement cursor to avoid leaving in an invalid state - SQLFreeStmt(stmt, SQL_CLOSE); + SQLFreeStmt(this->stmt, SQL_CLOSE); // Names are nulls and sizes are zeros - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ 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 - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, SQL_ALL_CATALOGS_W, SQL_NTS, empty, SQL_NTS, - empty, SQL_NTS, empty, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, SQL_ALL_CATALOGS_W, SQL_NTS, empty, + SQL_NTS, empty, SQL_NTS, empty, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckNullColumnW(stmt, 4); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckNullColumnW(this->stmt, 4); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } +#endif // __linux__ 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 // type "table" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, catalog_name, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, catalog_name, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } 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, - nullptr, SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, + SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ 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"}; // Return is unordered and contains user specific schemas, so collect schema names for // comparison with a known list - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS)); while (true) { - SQLRETURN ret = SQLFetch(stmt); + SQLRETURN ret = SQLFetch(this->stmt); if (ret == SQL_NO_DATA) break; ASSERT_EQ(SQL_SUCCESS, ret); - CheckNullColumnW(stmt, 1); - std::wstring schema = GetStringColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckNullColumnW(stmt, 4); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + std::wstring schema = GetStringColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckNullColumnW(this->stmt, 4); + CheckNullColumnW(this->stmt, 5); // Skip user-specific schemas like "@UserName" if (!schema.empty() && schema[0] != L'@') { @@ -173,47 +177,47 @@ 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"); - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, SQL_NTS, - nullptr, SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, SQL_ALL_SCHEMAS_W, + SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(schema_names) / sizeof(*schema_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); const std::wstring& expected_table_type = (std::wstring(schema_names[i]).rfind(L"sys", 0) == 0 || @@ -221,65 +225,63 @@ TEST_F(TablesRemoteTest, SQLTablesTestFilterByAllSchema) { ? expected_system_table_type : expected_user_table_type; - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, schema_names[i]); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, schema_names[i]); // Ignore table name - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesRemoteTest, SQLTablesGetMetadataForNamedSchema) { // 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"); - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, schema_name, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, schema_name, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, expected_schema_name); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, expected_schema_name); // Ignore table name - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesMockTest, SQLTablesTestGetMetadataForAllTables) { 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"); // Get all Table metadata - Mock server returns the system table sqlite_sequence as type // "table" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, SQL_ALL_TABLES_W, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -287,11 +289,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}; @@ -300,19 +301,22 @@ TEST_F(TablesMockTest, SQLTablesTestGetMetadataForTableName) { for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { // Get specific Table metadata - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, table_names[i], SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + + std::wstring table_name = ConvertToWString(table_names[i]); + CheckStringColumnW(this->stmt, 3, table_name); + + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } DropTestTable(); @@ -321,39 +325,40 @@ 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 - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, unicodetable_name, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, expected_table_name); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, expected_table_name); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropUnicodeTable(); } +#endif // __linux__ 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, + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, invalid_table_name, SQL_NTS, nullptr, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } @@ -362,59 +367,61 @@ 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)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS, + table_type_table_uppercase, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, table_type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_table_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, table_type_table_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); // Returns user table as well as system tables, even though only type table requested - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, table_type_table_lowercase, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, + SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, SQL_NTS, + table_type_table_lowercase, SQL_NTS)); for (size_t i = 0; i < sizeof(table_names) / sizeof(*table_names); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckStringColumnW(stmt, 1, expected_catalog_name); + CheckStringColumnW(this->stmt, 1, expected_catalog_name); // Mock server does not support table schema - CheckNullColumnW(stmt, 2); - CheckStringColumnW(stmt, 3, table_names[i]); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 2); + CheckStringColumnW(this->stmt, 3, table_names[i]); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); DropTestTable(); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { // Requires creation of user table named ODBCTest using schema $scratch in remote server // 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}; @@ -423,78 +430,80 @@ TEST_F(TablesRemoteTest, SQLTablesGetMetadataForTableTypeTable) { std::wstring expected_table_type = std::wstring(L"TABLE"); for (size_t i = 0; i < sizeof(type_list) / sizeof(*type_list); ++i) { - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, type_list[i], SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, type_list[i], SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckStringColumnW(stmt, 2, expected_schema_name); - CheckStringColumnW(stmt, 3, expected_table_name); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckStringColumnW(this->stmt, 2, expected_schema_name); + CheckStringColumnW(this->stmt, 3, expected_table_name); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } } +#endif // __linux__ 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, + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, empty, SQL_NTS, type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); - EXPECT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, type_view, SQL_NTS)); + EXPECT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, type_view, SQL_NTS)); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } +// GH-49702: TODO Disabled on Linux due to BlockingQueue issue +#ifndef __linux__ 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" - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, empty, SQL_NTS, - SQL_ALL_TABLE_TYPES_W, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, empty, SQL_NTS, empty, + SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckStringColumnW(stmt, 4, expected_table_type); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckStringColumnW(this->stmt, 4, expected_table_type); + CheckNullColumnW(this->stmt, 5); - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } TEST_F(TablesRemoteTest, SQLTablesGetSupportedTableTypes) { - 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)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, empty, SQL_NTS, empty, SQL_NTS, empty, + SQL_NTS, SQL_ALL_TABLE_TYPES_W, SQL_NTS)); for (size_t i = 0; i < sizeof(type_lists) / sizeof(*type_lists); ++i) { - ValidateFetch(stmt, SQL_SUCCESS); + ValidateFetch(this->stmt, SQL_SUCCESS); - CheckNullColumnW(stmt, 1); - CheckNullColumnW(stmt, 2); - CheckNullColumnW(stmt, 3); - CheckStringColumnW(stmt, 4, type_lists[i]); - CheckNullColumnW(stmt, 5); + CheckNullColumnW(this->stmt, 1); + CheckNullColumnW(this->stmt, 2); + CheckNullColumnW(this->stmt, 3); + CheckStringColumnW(this->stmt, 4, type_lists[i]); + CheckNullColumnW(this->stmt, 5); } - ValidateFetch(stmt, SQL_NO_DATA); + ValidateFetch(this->stmt, SQL_NO_DATA); } +#endif // __linux__ TYPED_TEST(TablesTest, SQLTablesGetMetadataBySQLDescribeCol) { SQLWCHAR column_name[1024]; @@ -507,26 +516,23 @@ 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}; - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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,26 +560,23 @@ 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}; - ASSERT_EQ(SQL_SUCCESS, SQLTables(stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, nullptr, - SQL_NTS, nullptr, SQL_NTS)); + ASSERT_EQ(SQL_SUCCESS, SQLTables(this->stmt, nullptr, SQL_NTS, nullptr, SQL_NTS, + nullptr, SQL_NTS, nullptr, SQL_NTS)); for (size_t i = 0; i < sizeof(column_names) / sizeof(*column_names); ++i) { column_index = i + 1; - ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(stmt, column_index, column_name, buf_char_len, - &name_length, &column_data_type, &column_size, - &decimal_digits, &nullable)); + ASSERT_EQ(SQL_SUCCESS, SQLDescribeCol(this->stmt, column_index, column_name, + buf_char_len, &name_length, &column_data_type, + &column_size, &decimal_digits, &nullable)); - EXPECT_EQ(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..2458ea9974c0 100644 --- a/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc +++ b/cpp/src/arrow/flight/sql/odbc/tests/type_info_test.cc @@ -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); @@ -1656,15 +1649,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoDateODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeDate) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_DATE)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTime) { @@ -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); @@ -1768,15 +1762,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoTimeODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeTime) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIME)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoSQLTypeTimestamp) { @@ -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); @@ -1880,15 +1874,15 @@ TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTimestampODBCVer2) { } TEST_F(TypeInfoOdbcV2MockTest, TestSQLGetTypeInfoSQLTypeTimestamp) { -#ifdef __APPLE__ - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); -#else +#ifdef _WIN32 // Pass ODBC Ver 3 data type ASSERT_EQ(SQL_ERROR, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); // Driver manager returns SQL data type out of range error state VerifyOdbcErrorState(SQL_HANDLE_STMT, stmt, kErrorStateS1004); -#endif // __APPLE__ +#else // Mac & Linux + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_TYPE_TIMESTAMP)); +#endif } TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoInvalidDataType) { @@ -1900,10 +1894,10 @@ TEST_F(TypeInfoMockTest, TestSQLGetTypeInfoInvalidDataType) { TYPED_TEST(TypeInfoTest, TestSQLGetTypeInfoUnsupportedDataType) { // Assumes mock and remote server don't support GUID data type - ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(stmt, SQL_GUID)); + ASSERT_EQ(SQL_SUCCESS, SQLGetTypeInfo(this->stmt, SQL_GUID)); // Result set is empty with valid data type that is unsupported by the server - ASSERT_EQ(SQL_NO_DATA, SQLFetch(stmt)); + ASSERT_EQ(SQL_NO_DATA, SQLFetch(this->stmt)); } } // namespace arrow::flight::sql::odbc 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", diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt index bd685845bc7c..6dea092feacf 100644 --- a/dev/release/rat_exclude_files.txt +++ b/dev/release/rat_exclude_files.txt @@ -13,6 +13,8 @@ ci/vcpkg/*.patch CHANGELOG.md cpp/CHANGELOG_PARQUET.md cpp/src/arrow/c/dlpack_abi.h +cpp/src/arrow/flight/sql/odbc/install/mac/README.txt +cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt cpp/src/arrow/io/mman.h cpp/src/arrow/util/random.h cpp/src/arrow/status.cc