Skip to content

Commit d5e5865

Browse files
authored
GH-49463: [C++][FlightRPC] Add Ubuntu ODBC Support (#49564)
### Rationale for this change GH-49463 Add Ubuntu support so users can connect using odbc on Linux. ### What changes are included in this PR? - Enable Linux ODBC build with unicode support - Add ODBC Ubuntu build in CI - Added `docker-compose` for Flight SQL ODBC - Register ODBC after build - Replaced `boost::lexicographical_compare` with `std::lexicographical_compare` - Fixed conversion bugs in `SetAttributeSQLWCHAR` - Convert from std::string to std::u16string directly without involving wide string (wstring) - Enabling ODBC Linux test build will be added in a separate PR ### Are these changes tested? - Ubuntu build is tested in CI - ODBC is tested with `isql` on local docker, and confirmed to be able to connect to online remote instance ### Are there any user-facing changes? N/A * GitHub Issue: #49463 Lead-authored-by: Alina (Xi) Li <alinal@bitquilltech.com> Co-authored-by: Alina (Xi) Li <alina.li@improving.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent aa30af3 commit d5e5865

39 files changed

Lines changed: 372 additions & 126 deletions

.github/workflows/cpp_extra.yml

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,62 @@ jobs:
346346
cd cpp/examples/minimal_build
347347
../minimal_build.build/arrow-example
348348
349+
odbc-linux:
350+
needs: check-labels
351+
name: ODBC Linux
352+
runs-on: ubuntu-latest
353+
if: >-
354+
needs.check-labels.outputs.force == 'true' ||
355+
contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra') ||
356+
contains(fromJSON(needs.check-labels.outputs.ci-extra-labels || '[]'), 'CI: Extra: C++')
357+
timeout-minutes: 75
358+
strategy:
359+
fail-fast: false
360+
env:
361+
ARCH: amd64
362+
ARCHERY_DEBUG: 1
363+
ARROW_ENABLE_TIMING_TESTS: OFF
364+
DOCKER_VOLUME_PREFIX: ".docker/"
365+
UBUNTU: 24.04
366+
steps:
367+
- name: Checkout Arrow
368+
uses: actions/checkout@v6
369+
with:
370+
fetch-depth: 0
371+
submodules: recursive
372+
- name: Cache Docker Volumes
373+
uses: actions/cache@v5
374+
with:
375+
path: .docker
376+
key: ubuntu-cpp-odbc-${{ hashFiles('cpp/**') }}
377+
restore-keys: ubuntu-cpp-odbc-
378+
- name: Setup Python on hosted runner
379+
uses: actions/setup-python@v6
380+
with:
381+
python-version: 3
382+
- name: Setup Archery
383+
run: python3 -m pip install -e dev/archery[docker]
384+
- name: Execute Docker Build
385+
env:
386+
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
387+
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
388+
run: |
389+
# GH-40558: reduce ASLR to avoid ASAN/LSAN crashes
390+
sudo sysctl -w vm.mmap_rnd_bits=28
391+
source ci/scripts/util_enable_core_dumps.sh
392+
archery docker run ubuntu-cpp-odbc
393+
- name: Docker Push
394+
if: >-
395+
success() &&
396+
github.event_name == 'push' &&
397+
github.repository == 'apache/arrow' &&
398+
github.ref_name == 'main'
399+
env:
400+
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
401+
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
402+
continue-on-error: true
403+
run: archery docker push ubuntu-cpp-odbc
404+
349405
odbc-macos:
350406
needs: check-labels
351407
name: ODBC ${{ matrix.build-type }} ${{ matrix.architecture }} macOS ${{ matrix.macos-version }}
@@ -445,7 +501,7 @@ jobs:
445501
"$(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib"
446502
- name: Register Flight SQL ODBC Driver
447503
run: |
448-
sudo cpp/src/arrow/flight/sql/odbc/install/mac/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib
504+
sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib
449505
- name: Test
450506
shell: bash
451507
run: |
@@ -708,6 +764,7 @@ jobs:
708764
- jni-linux
709765
- jni-macos
710766
- msvc-arm64
767+
- odbc-linux
711768
- odbc-macos
712769
- odbc-msvc
713770
- odbc-nightly

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ repos:
353353
?^cpp/build-support/update-thrift\.sh$|
354354
?^cpp/examples/minimal_build/run\.sh$|
355355
?^cpp/examples/tutorial_examples/run\.sh$|
356-
?^cpp/src/arrow/flight/sql/odbc/install/mac/install_odbc\.sh$|
356+
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$|
357357
?^dev/release/05-binary-upload\.sh$|
358358
?^dev/release/08-binary-verify\.sh$|
359359
?^dev/release/binary-recover\.sh$|

ci/docker/ubuntu-24.04-cpp.dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ RUN apt-get update -y -q && \
121121
rsync \
122122
tzdata \
123123
tzdata-legacy \
124+
unixodbc-dev \
124125
uuid-runtime \
125126
unzip \
126127
wget && \

compose.yaml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ x-hierarchy:
151151
- ubuntu-r-only-r
152152
- ubuntu-cpp-bundled
153153
- ubuntu-cpp-bundled-offline
154+
- ubuntu-cpp-odbc
154155
- ubuntu-cpp-minimal
155156
- ubuntu-cuda-cpp:
156157
- ubuntu-cuda-python
@@ -371,7 +372,7 @@ services:
371372
/arrow/ci/scripts/cpp_build.sh /arrow /build &&
372373
/arrow/ci/scripts/cpp_test.sh /arrow /build"
373374

374-
ubuntu-cpp:
375+
ubuntu-cpp: &ubuntu-cpp-base
375376
# Usage:
376377
# docker compose build ubuntu-cpp
377378
# docker compose run --rm ubuntu-cpp
@@ -496,6 +497,33 @@ services:
496497
volumes: *ubuntu-volumes
497498
command: *cpp-command
498499

500+
ubuntu-cpp-odbc:
501+
# Arrow Flight SQL ODBC build with BUNDLED dependencies with downloaded dependencies.
502+
<<: *ubuntu-cpp-base
503+
environment:
504+
<<: [*common, *ccache, *sccache, *cpp]
505+
ARROW_ACERO: "OFF"
506+
ARROW_AZURE: "OFF"
507+
ARROW_BUILD_TYPE: RELEASE
508+
ARROW_CSV: "OFF"
509+
ARROW_DATASET: "OFF"
510+
ARROW_DEPENDENCY_SOURCE: BUNDLED
511+
ARROW_DEPENDENCY_USE_SHARED: "OFF"
512+
ARROW_FLIGHT_SQL_ODBC: "ON"
513+
ARROW_GANDIVA: "OFF"
514+
ARROW_GCS: "OFF"
515+
ARROW_HDFS: "OFF"
516+
ARROW_ORC: "OFF"
517+
ARROW_PARQUET: "OFF"
518+
ARROW_S3: "OFF"
519+
ARROW_SUBSTRAIT: "OFF"
520+
# Register ODBC before running tests
521+
command: >
522+
/bin/bash -c "
523+
/arrow/ci/scripts/cpp_build.sh /arrow /build &&
524+
sudo /arrow/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /usr/local/lib/libarrow_flight_sql_odbc.so &&
525+
/arrow/ci/scripts/cpp_test.sh /arrow /build"
526+
499527
ubuntu-cpp-minimal:
500528
# Arrow build with minimal components/dependencies
501529
image: ${REPO}:${ARCH}-ubuntu-${UBUNTU}-cpp-minimal

cpp/cmake_modules/DefineOptions.cmake

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,6 @@ macro(tsort_bool_option_dependencies)
107107
endmacro()
108108

109109
macro(resolve_option_dependencies)
110-
# Arrow Flight SQL ODBC is available only for Windows and macOS for now.
111-
if(NOT WIN32 AND NOT APPLE)
112-
set(ARROW_FLIGHT_SQL_ODBC OFF)
113-
endif()
114110
if(MSVC_TOOLCHAIN)
115111
set(ARROW_USE_GLOG OFF)
116112
endif()

cpp/cmake_modules/ThirdpartyToolchain.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ function(build_boost)
10901090
set(ARROW_BOOST_NEED_MULTIPRECISION FALSE)
10911091
endif()
10921092
if(ARROW_ENABLE_THREADING)
1093-
if(ARROW_WITH_THRIFT OR (ARROW_FLIGHT_SQL_ODBC AND MSVC))
1093+
if(ARROW_WITH_THRIFT OR ARROW_FLIGHT_SQL_ODBC)
10941094
list(APPEND BOOST_INCLUDE_LIBRARIES locale)
10951095
endif()
10961096
if(ARROW_BOOST_NEED_MULTIPRECISION)

cpp/src/arrow/flight/sql/odbc/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ else()
2828
endif()
2929

3030
add_subdirectory(odbc_impl)
31-
add_subdirectory(tests)
31+
if(ARROW_BUILD_TESTS)
32+
if(WIN32 OR APPLE)
33+
# GH-49552 TODO: Enable Linux test build
34+
add_subdirectory(tests)
35+
endif()
36+
endif()
3237

3338
arrow_install_all_headers("arrow/flight/sql/odbc")
3439

cpp/src/arrow/flight/sql/odbc/install/mac/install_odbc.sh renamed to cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,18 @@ if [ ! -f "$ODBC_64BIT" ]; then
4040
exit 1
4141
fi
4242

43-
USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini"
44-
DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver"
43+
case "$(uname)" in
44+
Linux)
45+
USER_ODBCINST_FILE="/etc/odbcinst.ini"
46+
;;
47+
*)
48+
# macOS
49+
USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini"
50+
mkdir -p "$HOME"/Library/ODBC
51+
;;
52+
esac
4553

46-
mkdir -p "$HOME"/Library/ODBC
54+
DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver"
4755

4856
touch "$USER_ODBCINST_FILE"
4957

cpp/src/arrow/flight/sql/odbc/odbc_api.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#endif // defined(_WIN32)
3838

3939
namespace arrow::flight::sql::odbc {
40+
void LoadPropertiesFromDSN(const std::string& dsn, Connection::ConnPropertyMap& props);
41+
4042
SQLRETURN SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, SQLHANDLE* result) {
4143
ARROW_LOG(DEBUG) << "SQLAllocHandle called with type: " << type
4244
<< ", parent: " << parent

cpp/src/arrow/flight/sql/odbc/odbc_api_internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
#include "arrow/flight/sql/odbc/odbc_impl/platform.h"
2121

2222
#include <sql.h>
23-
#include <sqltypes.h>
24-
#include <sqlucode.h>
23+
#include <sqlext.h>
2524

2625
// \file odbc_api_internal.h
2726
//

0 commit comments

Comments
 (0)