Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .github/workflows/cpp_extra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,15 @@ jobs:
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
env:
ARCH: amd64
ARCHERY_DEBUG: 1
Expand Down Expand Up @@ -393,7 +402,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-pkg-installer-${{ matrix.format }}
path: build/cpp/ArrowFlightSqlOdbcODBC-*.${{ matrix.format }}
if-no-files-found: error

- name: Docker Push
if: >-
success() &&
Expand All @@ -404,7 +422,7 @@ 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
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ 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/linux/rpm/postinstall$|
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$|
?^dev/release/05-binary-upload\.sh$|
?^dev/release/08-binary-verify\.sh$|
Expand Down
1 change: 1 addition & 0 deletions ci/docker/ubuntu-24.04-cpp.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ RUN apt-get update -y -q && \
python3-venv \
rados-objclass-dev \
rapidjson-dev \
rpm \
rsync \
tzdata \
tzdata-legacy \
Expand Down
1 change: 1 addition & 0 deletions ci/scripts/cpp_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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} \
Expand Down
7 changes: 5 additions & 2 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,15 @@ services:
ARROW_PARQUET: "OFF"
ARROW_S3: "OFF"
ARROW_SUBSTRAIT: "OFF"
# 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
Expand Down
6 changes: 6 additions & 0 deletions cpp/cmake_modules/DefineOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
79 changes: 79 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,85 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)

set(CPACK_WIX_UI_BANNER
"${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp")
else()
set(ODBC_UNIX_FILE_NAME
"ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}"
)
if(APPLE)
set(CPACK_PACKAGE_FILE_NAME "${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")
# GH-49595 TODO: implement DEB installer
message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595")
elseif(${ODBC_PACKAGE_FORMAT} STREQUAL "RPM")
set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64)
set(CPACK_GENERATOR RPM)
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE
"${CMAKE_CURRENT_SOURCE_DIR}/install/linux/rpm/postinstall")
set(CPACK_RPM_FILE_NAME "${ODBC_UNIX_FILE_NAME}.rpm")
# Disable dependency check as ODBC embeds all third party dependencies
set(CPACK_RPM_PACKAGE_AUTOREQPROV "no")
set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
set(CPACK_RPM_COMPONENT_INSTALL ON)
else()
message(FATAL_ERROR "ODBC_PACKAGE_FORMAT '${ODBC_PACKAGE_FORMAT}' must be DEB or RPM for Linux installer."
)
endif()

# By default, Linux installs under /usr
set(ODBC_INSTALL_DIR "lib64/arrow-odbc/lib")
set(DOC_INSTALL_DIR "lib64/arrow-odbc/doc")
endif()

# Install ODBC
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)
Expand Down
16 changes: 16 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ After ODBC has been registered, you can run the ODBC tests. It is recommended to
.\cpp\build\< release | debug >\< Release | Debug>\arrow-flight-sql-odbc-test.exe
```

## Installers

ODBC installers are uploaded to the CI artifacts.

| Operating System | Package Format |
|------------------|----------------|
| Windows | MSI |
| macOS | PKG |
| Linux | DEB / RPM |

### Install `.RPM` on Ubuntu
While installing via `.DEB` installer on Ubuntu is the recommended approach, users may install `.RPM` on Ubuntu using below command
```
alien -i --scripts ArrowFlightSqlOdbcODBC-<version>.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.
Expand Down
30 changes: 30 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall
Original file line number Diff line number Diff line change
@@ -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"
31 changes: 19 additions & 12 deletions cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,44 +42,51 @@ 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..."
echo "
[$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
{
echo ""
echo "[ODBC Drivers]"
echo "${DRIVER_NAME}=Installed"
} >>"$USER_ODBCINST_FILE"
} >>"$SYSTEM_ODBCINST_FILE"
fi
Loading