Skip to content

GH-47876: [C++][FlightRPC] ODBC: macOS .PKG installer for Intel and ARM#49766

Open
alinaliBQ wants to merge 2 commits intoapache:mainfrom
Bit-Quill:gh-47876-mac-pkg
Open

GH-47876: [C++][FlightRPC] ODBC: macOS .PKG installer for Intel and ARM#49766
alinaliBQ wants to merge 2 commits intoapache:mainfrom
Bit-Quill:gh-47876-mac-pkg

Conversation

@alinaliBQ
Copy link
Copy Markdown
Collaborator

@alinaliBQ alinaliBQ commented Apr 15, 2026

Rationale for this change

Generate and upload macOS .pkg installer in CI. The installer is unsigned.

What changes are included in this PR?

Adds in support for macOS .PKG Installer for Intel and ARM. It will install:

/Library/ODBC/arrow-odbc
├── doc
│   ├── Connection-Options.md
│   └── LICENSE.txt
└── lib
    ├── libarrow_flight_sql_odbc.2400.0.0.dylib
    ├── libarrow_flight_sql_odbc.2400.dylib -> libarrow_flight_sql_odbc.2400.0.0.dylib
    └── libarrow_flight_sql_odbc.dylib -> libarrow_flight_sql_odbc.2400.dylib

3 directories, 5 files

If Apache Arrow Flight SQL ODBC is already registered in the system DSN on the user machine, the installer will not overwrite the registration.

Are these changes tested?

Tested on Intel macOS. Team will test ARM installer using ARM machine later.

Are there any user-facing changes?

Developers can download the .pkg installers for usage.

@github-actions github-actions bot added the awaiting review Awaiting review label Apr 15, 2026
@github-actions
Copy link
Copy Markdown

⚠️ GitHub issue #47876 has been automatically assigned in GitHub to PR creator.

Co-authored-by: vic-tsang <victor.tsang@improving.com>

cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh is originally authored by  vic-tsang <victor.tsang@improving.com>

---------------------------------------

* 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
@alinaliBQ alinaliBQ marked this pull request as ready for review April 16, 2026 17:55
@alinaliBQ
Copy link
Copy Markdown
Collaborator Author

@lidavidm @kou PR is ready for review, please have a look

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds macOS .pkg packaging support for the Arrow Flight SQL ODBC driver, integrating installer generation into CI and providing post-install registration scripts/resources.

Changes:

  • Add macOS CPack productbuild configuration for an ODBC .pkg installer (including postinstall registration and bundled docs).
  • Introduce a Unix DSN registration helper (install_odbc_ini.sh) and a macOS postinstall script to register the driver + DSN.
  • Update CI and repo configs to build/upload the .pkg and accommodate new installer resource files.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
dev/release/rat_exclude_files.txt Excludes new macOS installer resource text files from RAT scanning.
cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini.sh Adds a DSN registration script for system odbc.ini.
cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh Adjusts macOS driver registration to write to system /Library/ODBC/odbcinst.ini.
cpp/src/arrow/flight/sql/odbc/install/mac/postinstall Adds post-install script to register driver + DSN and delete temporary scripts.
cpp/src/arrow/flight/sql/odbc/install/mac/Welcome.txt Adds installer welcome text resource.
cpp/src/arrow/flight/sql/odbc/install/mac/README.txt Adds installer readme text resource with setup steps.
cpp/src/arrow/flight/sql/odbc/Connection-Options.md Adds a (currently placeholder) connection options doc intended to be shipped in the installer.
cpp/src/arrow/flight/sql/odbc/CMakeLists.txt Adds macOS CPack config, installs driver/scripts/docs, and defines Docs component for UNIX.
.pre-commit-config.yaml Adds new scripts to ShellCheck scope.
.github/workflows/cpp_extra.yml Enables ODBC installer build, runs cpack, and uploads .pkg artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +168 to +179
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()
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linked issue description calls out installing the driver under /Library/Apache/ArrowFlightSQLODBC/lib/..., but this packaging installs under /Library/ODBC/arrow-odbc/... (via CPACK_INSTALL_PREFIX and ODBC_INSTALL_DIR). Please confirm the intended install root and align with the issue (or update the issue/PR description) to avoid shipping an installer that doesn't meet the documented path expectation.

Copilot uses AI. Check for mistakes.
Comment on lines +218 to +220
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md"
DESTINATION "${DOC_INSTALL_DIR}"
COMPONENT Docs)
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connection-Options.md is installed into the package (Docs component) but currently only contains a TODO placeholder. Since this is user-facing documentation shipped with the installer, it should either be populated with the supported keys/options or omitted from installation until it has real content.

Suggested change
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md"
DESTINATION "${DOC_INSTALL_DIR}"
COMPONENT Docs)

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +9
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.
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User-facing text fixes: change "To setup a connection" to "To set up a connection" (grammar), change "Ok" to "OK", and remove the trailing whitespace at the end of line 7. Since this README is used as an installer resource, it should be polished.

Suggested change
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.
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.

Copilot uses AI. Check for mistakes.
Comment on lines 48 to +50
# 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
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On macOS this script now writes to the system-level /Library/ODBC/odbcinst.ini, but the variable is still named USER_ODBCINST_FILE. Renaming it to reflect that it's a system-wide file would reduce confusion for future maintenance (especially since the script requires sudo).

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +30
# 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"
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The postinstall script doesn't enable strict error handling (e.g., set -euo pipefail). As written, if either registration script fails, the postinstall can still exit successfully because the final rm -f commands will return 0, leaving the driver/DSN unregistered while the installer reports success. Please fail fast on any error and consider emitting a clear error message if registration fails.

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +31
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"

Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script doesn't use strict mode (set -euo pipefail) like install_odbc.sh does. Without it, failures from commands like touch, awk, or mv may go unnoticed depending on where they occur, which is risky for an installer-time system configuration update. Please add strict mode and ensure any failures propagate as a non-zero exit code.

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +64
# 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
# Add DSN entry under [ODBC Data Sources] section

# Use awk to insert the line immediately after [ODBC Data Sources]
awk -v dsn="$DSN_NAME" -v driver="$DRIVER_NAME" '
$0 ~ /^\[ODBC Data Sources\]/ && !inserted {
print
print dsn "=" driver
inserted=1
next
}
{ print }
' "$SYSTEM_ODBC_FILE" > "${SYSTEM_ODBC_FILE}.tmp" && mv "${SYSTEM_ODBC_FILE}.tmp" "$SYSTEM_ODBC_FILE"
fi
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DSN existence check under [ODBC Data Sources] only matches entries formatted exactly as Apache Arrow Flight SQL ODBC DSN=.... In many odbc.ini files the = is surrounded by whitespace (e.g., DSN_NAME = Driver), so this can fail to detect an existing entry and insert a duplicate. Consider matching optional whitespace around = (and/or parsing the section more robustly) before inserting.

Copilot uses AI. Check for mistakes.
"${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")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use lower case (welcome.txt)?

install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt"
DESTINATION "${DOC_INSTALL_DIR}"
COMPONENT Docs)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/Connection-Options.md"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use lower case (connection-options.md)?

else()
if(APPLE)
set(CPACK_PACKAGE_FILE_NAME
"ArrowFlightSqlOdbcODBC-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the OdbcODBC part intentional?

Comment on lines +181 to +184
# 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")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to use CPack for deb and RPM?
I want to use https://github.com/apache/arrow/tree/main/dev/tasks/linux-packages for them.

"${CMAKE_CURRENT_SOURCE_DIR}/install/mac/Welcome.txt")

set(ODBC_INSTALL_DIR "arrow-odbc/lib")
set(DOC_INSTALL_DIR "arrow-odbc/doc")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use ODBC_ prefix?

Comment on lines +215 to +217
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../LICENSE.txt"
DESTINATION "${DOC_INSTALL_DIR}"
COMPONENT Docs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LICENSE.txt (and NOTICE.txt) are already installed to ARROW_DOC_DIR. Do we need to install them separately for ODBC?

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting review Awaiting review labels Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants