From efbdf635cb3daea7dcf5a8081f4c1df6eee35652 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:47:31 -0700 Subject: [PATCH 1/5] macOS `.PKG` installer for Intel and ARM Co-authored-by: vic-tsang cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh is originally authored by vic-tsang --------------------------------------- * Initial draft for macOS .pkg installer * in-progress for `install_odbc` * Remove `$HOME` from registration script * Generate .pkg installer and attempts to fix installer * Attempt to fix doc not seen * Attempt to fix ODBC registration script * Fix installer script and doc * Rename `install_odbc_ini.sh` to `postinstall` * Reuse `install_odbc.sh` script inside `postinstall` * Fix to generate macOS installer - Check $(pwd)/build/cpp * Clean up PR and todos * Update format to re-use code * Use `install_odbc_ini.sh` script to install DSN Keep a lightweight `postinstall` file for macOS * Update install_odbc_ini.sh execution access * Address Justin's comment --- .github/workflows/cpp_extra.yml | 14 ++++ .pre-commit-config.yaml | 2 + cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 75 ++++++++++++++++++- .../flight/sql/odbc/install/mac/README.txt | 9 +++ .../flight/sql/odbc/install/mac/Welcome.txt | 1 + .../flight/sql/odbc/install/mac/postinstall | 30 ++++++++ .../sql/odbc/install/unix/install_odbc.sh | 6 +- .../sql/odbc/install/unix/install_odbc_ini.sh | 72 ++++++++++++++++++ dev/release/rat_exclude_files.txt | 2 + 9 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 cpp/src/arrow/flight/sql/odbc/install/mac/README.txt create mode 100644 cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt create mode 100755 cpp/src/arrow/flight/sql/odbc/install/mac/postinstall create mode 100755 cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index c762b7cfcdb4..cef0cf169d88 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -428,6 +428,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 +504,19 @@ jobs: --allow libresolv \ --allow libz \ "$(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib" + - name: Generate macOS Installer + if: matrix.build-type == 'release' + shell: bash + run: | + cd $(pwd)/build/cpp + cpack + - name: Upload ODBC PKG to the job + if: matrix.build-type == 'release' + uses: actions/upload-artifact@v7 + with: + name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} + path: build/cpp/ArrowFlightSqlOdbcODBC-*.pkg + if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | sudo cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh $(pwd)/build/cpp/${{ matrix.build-type }}/libarrow_flight_sql_odbc.dylib diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b7e3ce7633d..e7cf88b16c1f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -347,7 +347,9 @@ repos: ?^cpp/build-support/update-thrift\.sh$| ?^cpp/examples/minimal_build/run\.sh$| ?^cpp/examples/tutorial_examples/run\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$| ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$| + ?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$| ?^dev/release/05-binary-upload\.sh$| ?^dev/release/07-flightsqlodbc-upload\.sh$| ?^dev/release/09-binary-verify\.sh$| diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 4227873706ff..0f9757c2c80d 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -132,7 +132,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 +158,66 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp") + else() + if(APPLE) + set(CPACK_PACKAGE_FILE_NAME + "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + ) + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") + + set(CPACK_SET_DESTDIR ON) + set(CPACK_INSTALL_PREFIX "/Library/ODBC") + # Register ODBC after install + set(CPACK_POSTFLIGHT_ARROW_FLIGHT_SQL_ODBC_SCRIPT + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/postinstall") + set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/README.txt") + set(CPACK_RESOURCE_FILE_WELCOME + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/Welcome.txt") + + set(ODBC_INSTALL_DIR "arrow-odbc/lib") + set(DOC_INSTALL_DIR "arrow-odbc/doc") + else() + # Linux + # GH-49595: TODO implement DEB installer + # GH-47977: TODO implement RPM installer + message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595") + message(STATUS "ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977") + endif() + + # Install ODBC + install(TARGETS arrow_flight_sql_odbc_shared + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc) + + # Install temporary driver registration scripts, they will be removed after driver registration is complete + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc_ini.sh" + DESTINATION "${ODBC_INSTALL_DIR}" + COMPONENT arrow_flight_sql_odbc + PERMISSIONS OWNER_EXECUTE + OWNER_WRITE + OWNER_READ + GROUP_EXECUTE + GROUP_READ + WORLD_EXECUTE + WORLD_READ) + + # Install documentation files + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md" + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT Docs) endif() get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) @@ -173,8 +232,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 +247,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/install/mac/README.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt new file mode 100644 index 000000000000..8624470eb8bb --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt @@ -0,0 +1,9 @@ +Files are available in '/Library/ODBC/arrow-odbc' after installation. + +To setup a connection, you can use DSN to store your data source connection information. +1. Open 'iODBC Data Source Administrator'. +2. To create a user DSN, go to 'User DSN' tab and click 'Add'. +3. Select 'Apache Arrow Flight SQL ODBC Driver' and click 'Finish'. +4. Enter DSN name and connection string values. +For the list of all supported options, check '/Library/ODBC/arrow-odbc/doc/Connection-Options.md'. +5. Click 'Ok' to save the DSN. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt new file mode 100644 index 000000000000..5898db428f6f --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt @@ -0,0 +1 @@ +Apache Arrow Flight SQL ODBC Driver is a read-only ODBC driver for connecting to data sources that support Arrow Flight SQL. diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall new file mode 100755 index 000000000000..9499c2fe0e92 --- /dev/null +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Use temporary driver registration script to register ODBC driver in system DSN +odbc_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc.sh" +"$odbc_install_script" /Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib + +# Use temporary DSN registration script to register sample system DSN +dsn_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc_ini.sh" +"$dsn_install_script" /Library/ODBC/odbc.ini + +# clean temporary script +rm -f "$odbc_install_script" +rm -f "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh index 5ddcc8a4cbda..b97fabfbadac 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -# Used by macOS ODBC installer script `install_odbc_ini.sh` and macOS ODBC testing +# Used by arrow/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall set -euo pipefail @@ -46,8 +46,8 @@ case "$(uname)" in ;; *) # macOS - USER_ODBCINST_FILE="$HOME/Library/ODBC/odbcinst.ini" - mkdir -p "$HOME"/Library/ODBC + USER_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + mkdir -p /Library/ODBC ;; esac diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh 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/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt index bd685845bc7c..6dea092feacf 100644 --- a/dev/release/rat_exclude_files.txt +++ b/dev/release/rat_exclude_files.txt @@ -13,6 +13,8 @@ ci/vcpkg/*.patch CHANGELOG.md cpp/CHANGELOG_PARQUET.md cpp/src/arrow/c/dlpack_abi.h +cpp/src/arrow/flight/sql/odbc/install/mac/README.txt +cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt cpp/src/arrow/io/mman.h cpp/src/arrow/util/random.h cpp/src/arrow/status.cc From 0d36e8a6a1b836aed1ce74a28adabffefbd82492 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:35:57 -0700 Subject: [PATCH 2/5] Address feedback --- .github/workflows/cpp_extra.yml | 2 +- cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 12 +++---- .../flight/sql/odbc/install/mac/README.txt | 8 ++--- .../flight/sql/odbc/install/mac/postinstall | 32 +++++++++++++++---- .../install/mac/{Welcome.txt => welcome.txt} | 0 .../sql/odbc/install/unix/install_odbc.sh | 18 +++++------ .../sql/odbc/install/unix/install_odbc_ini.sh | 21 ++++++++---- dev/release/rat_exclude_files.txt | 2 +- 8 files changed, 61 insertions(+), 34 deletions(-) rename cpp/src/arrow/flight/sql/odbc/install/mac/{Welcome.txt => welcome.txt} (100%) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index cef0cf169d88..2a0348a905a5 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -515,7 +515,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} - path: build/cpp/ArrowFlightSqlOdbcODBC-*.pkg + path: build/cpp/ArrowFlightSqlOdbc-*.pkg if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 0f9757c2c80d..632303f127f4 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -161,7 +161,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) else() if(APPLE) set(CPACK_PACKAGE_FILE_NAME - "ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + "ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" ) set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") @@ -172,10 +172,10 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) "${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") + "${CMAKE_CURRENT_SOURCE_DIR}/install/mac/welcome.txt") set(ODBC_INSTALL_DIR "arrow-odbc/lib") - set(DOC_INSTALL_DIR "arrow-odbc/doc") + set(ODBC_DOC_INSTALL_DIR "arrow-odbc/doc") else() # Linux # GH-49595: TODO implement DEB installer @@ -213,10 +213,10 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Install documentation files install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" - DESTINATION "${DOC_INSTALL_DIR}" + DESTINATION "${ODBC_DOC_INSTALL_DIR}" COMPONENT Docs) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md" - DESTINATION "${DOC_INSTALL_DIR}" + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md" + DESTINATION "${ODBC_DOC_INSTALL_DIR}" COMPONENT Docs) endif() diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt index 8624470eb8bb..f83af5eb4a04 100644 --- a/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/README.txt @@ -1,9 +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. +To set up 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. +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/postinstall b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall index 9499c2fe0e92..e4f20181431c 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall +++ b/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall @@ -17,14 +17,32 @@ # 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 +set -euo pipefail -# Use temporary DSN registration script to register sample system DSN +odbc_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc.sh" dsn_install_script="/Library/ODBC/arrow-odbc/lib/install_odbc_ini.sh" -"$dsn_install_script" /Library/ODBC/odbc.ini +driver_lib="/Library/ODBC/arrow-odbc/lib/libarrow_flight_sql_odbc.dylib" +dsn_file="/Library/ODBC/odbc.ini" + +if [[ ! -x "$odbc_install_script" ]]; then + echo "ERROR: ODBC install script $odbc_install_script not found" >&2 + exit 1 +fi + +"$odbc_install_script" "$driver_lib" || { + echo "ERROR: Failed to register ODBC driver ($driver_lib)" >&2 + exit 1 +} + +if [[ ! -x "$dsn_install_script" ]]; then + echo "ERROR: DSN install script $dsn_install_script not found" >&2 + exit 1 +fi + +"$dsn_install_script" "$dsn_file" || { + echo "ERROR: Failed to register DSN to ($dsn_file)" >&2 + exit 1 +} # clean temporary script -rm -f "$odbc_install_script" -rm -f "$dsn_install_script" +rm -f "$odbc_install_script" "$dsn_install_script" diff --git a/cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt b/cpp/src/arrow/flight/sql/odbc/install/mac/welcome.txt similarity index 100% rename from cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt rename to cpp/src/arrow/flight/sql/odbc/install/mac/welcome.txt diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh index b97fabfbadac..c0de301b6d8b 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -42,20 +42,20 @@ fi case "$(uname)" in Linux) - USER_ODBCINST_FILE="/etc/odbcinst.ini" + ODBCINST_FILE="/etc/odbcinst.ini" ;; *) # macOS - USER_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + ODBCINST_FILE="/Library/ODBC/odbcinst.ini" mkdir -p /Library/ODBC ;; esac DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" -touch "$USER_ODBCINST_FILE" +touch "$ODBCINST_FILE" -if grep -q "^\[$DRIVER_NAME\]" "$USER_ODBCINST_FILE"; then +if grep -q "^\[$DRIVER_NAME\]" "$ODBCINST_FILE"; then echo "Driver [$DRIVER_NAME] already exists in odbcinst.ini" else echo "Adding [$DRIVER_NAME] to odbcinst.ini..." @@ -63,17 +63,17 @@ else [$DRIVER_NAME] Description=An ODBC Driver for Apache Arrow Flight SQL Driver=$ODBC_64BIT -" >>"$USER_ODBCINST_FILE" +" >>"$ODBCINST_FILE" fi # Check if [ODBC Drivers] section exists -if grep -q '^\[ODBC Drivers\]' "$USER_ODBCINST_FILE"; then +if grep -q '^\[ODBC Drivers\]' "$ODBCINST_FILE"; then # Section exists: check if driver entry exists - if ! grep -q "^${DRIVER_NAME}=" "$USER_ODBCINST_FILE"; then + if ! grep -q "^${DRIVER_NAME}=" "$ODBCINST_FILE"; then # Driver entry does not exist, add under [ODBC Drivers] sed -i '' "/^\[ODBC Drivers\]/a\\ ${DRIVER_NAME}=Installed -" "$USER_ODBCINST_FILE" +" "$ODBCINST_FILE" fi else # Section doesn't exist, append both section and driver entry at end @@ -81,5 +81,5 @@ else echo "" echo "[ODBC Drivers]" echo "${DRIVER_NAME}=Installed" - } >>"$USER_ODBCINST_FILE" + } >>"$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 index b86d4047b12c..ba5a661c9801 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh @@ -17,17 +17,23 @@ # specific language governing permissions and limitations # under the License. -SYSTEM_ODBC_FILE="$1" +set -euo pipefail + +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" + echo "ERROR: path to system ODBC DSN is not specified." >&2 + echo "Usage: install_odbc_ini.sh " >&2 exit 1 fi DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" DSN_NAME="Apache Arrow Flight SQL ODBC DSN" -touch "$SYSTEM_ODBC_FILE" +if ! touch "$SYSTEM_ODBC_FILE"; then + echo "ERROR: Cannot access or create $SYSTEM_ODBC_FILE" >&2 + exit 1 +fi if grep -q "^\[$DSN_NAME\]" "$SYSTEM_ODBC_FILE"; then echo "DSN [$DSN_NAME] already exists in $SYSTEM_ODBC_FILE" @@ -37,7 +43,7 @@ else [$DSN_NAME] Description = An ODBC Driver DSN for Apache Arrow Flight SQL -Driver = Apache Arrow Flight SQL ODBC Driver +Driver = $DRIVER_NAME Host = Port = UID = @@ -48,8 +54,9 @@ fi # Check if [ODBC Data Sources] section exists if grep -q '^\[ODBC Data Sources\]' "$SYSTEM_ODBC_FILE"; then # Section exists: check if DSN entry exists - if ! grep -q "^${DSN_NAME}=" "$SYSTEM_ODBC_FILE"; then + if ! grep -Eq "^${DSN_NAME}[[:space:]]*=" "$SYSTEM_ODBC_FILE"; then # Add DSN entry under [ODBC Data Sources] section + tmp_file="$(mktemp "${SYSTEM_ODBC_FILE}.XXXX")" # Use awk to insert the line immediately after [ODBC Data Sources] awk -v dsn="$DSN_NAME" -v driver="$DRIVER_NAME" ' @@ -60,7 +67,9 @@ if grep -q '^\[ODBC Data Sources\]' "$SYSTEM_ODBC_FILE"; then next } { print } - ' "$SYSTEM_ODBC_FILE" > "${SYSTEM_ODBC_FILE}.tmp" && mv "${SYSTEM_ODBC_FILE}.tmp" "$SYSTEM_ODBC_FILE" + ' "$SYSTEM_ODBC_FILE" > "$tmp_file" + + mv "$tmp_file" "$SYSTEM_ODBC_FILE" fi else # Section doesn't exist, append section and DSN entry at end diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt index 6dea092feacf..f9e1cebcd74a 100644 --- a/dev/release/rat_exclude_files.txt +++ b/dev/release/rat_exclude_files.txt @@ -14,7 +14,7 @@ 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/flight/sql/odbc/install/mac/welcome.txt cpp/src/arrow/io/mman.h cpp/src/arrow/util/random.h cpp/src/arrow/status.cc From 8f1b4f9adfad0b7d96ba5471f50dc87864e2f9cb Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Mon, 4 May 2026 14:00:30 -0700 Subject: [PATCH 3/5] More feedback --- .github/workflows/cpp_extra.yml | 2 +- cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cpp_extra.yml b/.github/workflows/cpp_extra.yml index 2a0348a905a5..73b06f9deec5 100644 --- a/.github/workflows/cpp_extra.yml +++ b/.github/workflows/cpp_extra.yml @@ -515,7 +515,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: flight-sql-odbc-pkg-installer-${{ matrix.architecture }} - path: build/cpp/ArrowFlightSqlOdbc-*.pkg + path: build/cpp/ArrowFlightSQLODBC-*.pkg if-no-files-found: error - name: Register Flight SQL ODBC Driver run: | diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 632303f127f4..1eb2f7591564 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -132,12 +132,11 @@ 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-47877 TODO: set up `arrow_flight_sql_odbc` component for Linux Installer if(WIN32) # Install ODBC and its Arrow dependencies install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin - COMPONENT arrow_flight_sql_odbc) + COMPONENT ArrowFlightSQLODBC) install(TARGETS arrow_shared arrow_compute_shared arrow_flight_shared @@ -149,7 +148,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) "ext-ms-.*" POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" - RUNTIME DESTINATION bin COMPONENT arrow_flight_sql_odbc) + RUNTIME DESTINATION bin COMPONENT ArrowFlightSQLODBC) set(CPACK_WIX_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-flight-sql-odbc.wxs") @@ -161,14 +160,14 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) else() if(APPLE) set(CPACK_PACKAGE_FILE_NAME - "ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" + "ArrowFlightSQLODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}" ) 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 + set(CPACK_POSTFLIGHT_ARROWFLIGHTSQLODBC_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 @@ -187,12 +186,12 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Install ODBC install(TARGETS arrow_flight_sql_odbc_shared DESTINATION "${ODBC_INSTALL_DIR}" - COMPONENT arrow_flight_sql_odbc) + COMPONENT ArrowFlightSQLODBC) # 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 + COMPONENT ArrowFlightSQLODBC PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ @@ -202,7 +201,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) WORLD_READ) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/install/unix/install_odbc_ini.sh" DESTINATION "${ODBC_INSTALL_DIR}" - COMPONENT arrow_flight_sql_odbc + COMPONENT ArrowFlightSQLODBC PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ @@ -221,7 +220,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) endif() get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) - set(CPACK_COMPONENTS_ALL "arrow_flight_sql_odbc") + set(CPACK_COMPONENTS_ALL "ArrowFlightSQLODBC") if(WIN32) # WiX msi installer on Windows @@ -243,7 +242,7 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Load CPack after all CPACK* variables are set include(CPack) - cpack_add_component(arrow_flight_sql_odbc + cpack_add_component(ArrowFlightSQLODBC DISPLAY_NAME "ODBC library" DESCRIPTION "Apache Arrow Flight SQL ODBC library bin, required to install" REQUIRED) From fc075e02ed535bf29a5098c2769250704b891114 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Tue, 19 May 2026 11:29:40 -0700 Subject: [PATCH 4/5] Address feedback --- cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 19 +++++------- .../sql/odbc/install/unix/install_odbc.sh | 29 ++++++++++++------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 1eb2f7591564..7584fec686d2 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -212,15 +212,14 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) # Install documentation files install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt" - DESTINATION "${ODBC_DOC_INSTALL_DIR}" - COMPONENT Docs) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md" + "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../NOTICE.txt" + "${CMAKE_CURRENT_SOURCE_DIR}/connection-options.md" DESTINATION "${ODBC_DOC_INSTALL_DIR}" COMPONENT Docs) endif() get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) - set(CPACK_COMPONENTS_ALL "ArrowFlightSQLODBC") + set(CPACK_COMPONENTS_ALL "ArrowFlightSQLODBC" "Docs") if(WIN32) # WiX msi installer on Windows @@ -233,7 +232,6 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER) 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() @@ -246,11 +244,8 @@ 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() + cpack_add_component(Docs + DISPLAY_NAME "Documentation" + DESCRIPTION "Documentation for Apache Arrow Flight SQL ODBC Driver" + REQUIRED) endif() 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 c0de301b6d8b..8c9423f1218e 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh @@ -42,20 +42,20 @@ fi case "$(uname)" in Linux) - ODBCINST_FILE="/etc/odbcinst.ini" + SYSTEM_ODBCINST_FILE="/etc/odbcinst.ini" ;; *) # macOS - ODBCINST_FILE="/Library/ODBC/odbcinst.ini" + SYSTEM_ODBCINST_FILE="/Library/ODBC/odbcinst.ini" mkdir -p /Library/ODBC ;; esac DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver" -touch "$ODBCINST_FILE" +touch "$SYSTEM_ODBCINST_FILE" -if grep -q "^\[$DRIVER_NAME\]" "$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 -" >>"$ODBCINST_FILE" +" >>"$SYSTEM_ODBCINST_FILE" fi # Check if [ODBC Drivers] section exists -if grep -q '^\[ODBC Drivers\]' "$ODBCINST_FILE"; then +if grep -q '^\[ODBC Drivers\]' "$SYSTEM_ODBCINST_FILE"; then # Section exists: check if driver entry exists - if ! grep -q "^${DRIVER_NAME}=" "$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 -" "$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" - } >>"$ODBCINST_FILE" + } >>"$SYSTEM_ODBCINST_FILE" fi From 85d9b5aa709ee98595da894e2ac8393b49b5b4e9 Mon Sep 17 00:00:00 2001 From: justing-bq <62349012+justing-bq@users.noreply.github.com> Date: Wed, 20 May 2026 14:44:13 -0700 Subject: [PATCH 5/5] Address more feedback --- cpp/src/arrow/flight/sql/odbc/CMakeLists.txt | 6 ++---- cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh | 2 +- .../arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt index 7584fec686d2..446dac95272c 100644 --- a/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt +++ b/cpp/src/arrow/flight/sql/odbc/CMakeLists.txt @@ -230,11 +230,9 @@ 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() + elseif(APPLE) # macOS and Linux - if(APPLE) - set(CPACK_GENERATOR "productbuild") - endif() + set(CPACK_GENERATOR "productbuild") endif() # GH-47877 TODO: create Linux Installer using cpack 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 8c9423f1218e..97899923f5d1 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 arrow/cpp/src/arrow/flight/sql/odbc/install/mac/postinstall +# Used by cpp/src/arrow/flight/sql/odbc/install/mac/postinstall set -euo pipefail diff --git a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh index ba5a661c9801..4fa7a31901ff 100755 --- a/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh +++ b/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh @@ -70,6 +70,9 @@ if grep -q '^\[ODBC Data Sources\]' "$SYSTEM_ODBC_FILE"; then ' "$SYSTEM_ODBC_FILE" > "$tmp_file" mv "$tmp_file" "$SYSTEM_ODBC_FILE" + + # Restore expected permissions/ownership for system ODBC config + chmod 644 "$SYSTEM_ODBC_FILE" fi else # Section doesn't exist, append section and DSN entry at end