# ADBC (Arrow)

Arrow Database Connectivity (ADBC) provides a standardized interface for accessing various databases using the Apache Arrow columnar format. ADBC enables efficient, high-performance data movement with zero-copy semantics and native Arrow support (*v1.5.2+*)

## Supported Database Types

Sling supports the following databases via ADBC drivers:

* **PostgreSQL** - Full support via ADBC PostgreSQL driver
* **MySQL** - Support via ADBC MySQL driver (v9.4+)
* **SQL Server** - Full support via ADBC SQL Server driver
* **Snowflake** - Full support via ADBC Snowflake driver
* **SQLite** - Support via ADBC SQLite driver
* **DuckDB** - Full support via ADBC DuckDB driver
* **BigQuery** - Full support via ADBC BigQuery driver
* **Trino** - Support via ADBC Trino driver (v4.0+)

## Setup

Using ADBC requires two components:

1. **ADBC Driver Manager** — a shared library (`libadbc_driver_manager.so` / `.dylib` / `.dll`) that loads and manages drivers
2. **Database Driver** — the native ADBC driver for your specific database (e.g., DuckDB, PostgreSQL)

### Step 1: Install the ADBC Driver Manager

The driver manager is a shared library that Sling loads at runtime. You must install it before using any ADBC connection.

{% tabs %}
{% tab title="macOS" %}
Using Conda (recommended):

```bash
conda install -c conda-forge libadbc-driver-manager
```

Or with Homebrew + Conda:

```bash
brew install --cask mambaforge
mamba install -c conda-forge libadbc-driver-manager
```

The library is installed to your conda environment's `lib/` directory (e.g., `~/mambaforge/lib/libadbc_driver_manager.dylib`). Sling auto-detects common conda paths.
{% endtab %}

{% tab title="Linux (apt — amd64 only)" %}
The Apache Arrow apt repository provides pre-built packages for **amd64** (x86\_64):

```bash
# Add Apache Arrow apt repository
sudo apt update
sudo apt install -y ca-certificates lsb-release wget
wget -q https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb -O /tmp/arrow.deb
sudo apt install -y /tmp/arrow.deb && rm /tmp/arrow.deb
sudo apt update

# Install the driver manager
sudo apt install -y libadbc-driver-manager110
```

{% hint style="warning" %}
The `libadbc-driver-manager` apt package is only available for **amd64**. For arm64/aarch64, use conda-forge (see below).
{% endhint %}
{% endtab %}

{% tab title="Linux (conda — amd64 & arm64)" %}
Conda-forge provides packages for both amd64 and arm64:

```bash
conda install -c conda-forge libadbc-driver-manager
```

The library is installed to your conda environment's `lib/` directory. Sling auto-detects common conda paths (`~/mambaforge/lib/`, `~/miniforge3/lib/`, `~/miniconda3/lib/`).
{% endtab %}

{% tab title="Windows" %}
Using Conda:

```powershell
conda install -c conda-forge libadbc-driver-manager
```

If Sling cannot find the library, set the `ADBC_DRIVER_MANAGER_LIB` environment variable to the full path of `adbc_driver_manager.dll`.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Sling auto-detects the driver manager from common installation paths. If it cannot find the library, you can set the `ADBC_DRIVER_MANAGER_LIB` environment variable to the full path:

```bash
export ADBC_DRIVER_MANAGER_LIB=/path/to/libadbc_driver_manager.so    # Linux
export ADBC_DRIVER_MANAGER_LIB=/path/to/libadbc_driver_manager.dylib  # macOS
```

{% endhint %}

### Step 2: Install the Database Driver

Install the native ADBC driver for your target database using the [`dbc` CLI tool](https://docs.columnar.tech/dbc/):

```bash
# Install dbc
# macOS (Homebrew)
brew install columnar-tech/tap/dbc

# Linux/macOS (shell script)
curl -LsSf https://dbc.columnar.tech/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://dbc.columnar.tech/install.ps1 | iex"
```

Then install drivers for your target databases:

```bash
dbc install duckdb
dbc install postgresql
dbc install mysql
dbc install snowflake
dbc install trino
# ... etc
```

Drivers are installed to:

* **macOS**: `~/Library/Application Support/ADBC/Drivers/`
* **Linux**: `~/.config/adbc/drivers/`
* **Windows**: `%APPDATA%\adbc\drivers\`

Sling auto-discovers installed drivers from these locations.

### Quick Start Example (DuckDB)

Here is a complete example from scratch on macOS:

```bash
# 1. Install driver manager
conda install -c conda-forge libadbc-driver-manager

# 2. Install DuckDB driver
dbc install duckdb

# 3. Set up connection
sling conns set DUCKDB type=duckdb instance=/tmp/test.db use_adbc=true

# 4. Test it
sling conns test DUCKDB
```

And on Linux (amd64):

```bash
# 1. Install driver manager (via apt)
wget -q https://apache.jfrog.io/artifactory/arrow/ubuntu/apache-arrow-apt-source-latest-jammy.deb -O /tmp/arrow.deb
sudo apt install -y /tmp/arrow.deb && rm /tmp/arrow.deb
sudo apt update && sudo apt install -y libadbc-driver-manager110

# 2. Install DuckDB driver
curl -LsSf https://dbc.columnar.tech/install.sh | sh
dbc install duckdb

# 3. Set up connection and test
sling conns set DUCKDB type=duckdb instance=/tmp/test.db use_adbc=true
sling conns test DUCKDB
```

### Manual Driver Installation

If you prefer not to use `dbc`, you can install ADBC driver libraries manually:

{% tabs %}
{% tab title="macOS" %}

```bash
# Install via Conda
conda install conda-forge::libadbc-driver-postgresql

# Or download .dylib from ADBC releases and place in a known location
cp libadbc_driver_postgresql.dylib ~/Library/Application\ Support/ADBC/Drivers/
```

{% endtab %}

{% tab title="Linux" %}

```bash
# Ubuntu/Debian amd64 (after adding Apache Arrow APT repository)
sudo apt install libadbc-driver-postgresql-dev

# Or via Conda (amd64 and arm64)
conda install conda-forge::libadbc-driver-postgresql
```

{% endtab %}

{% tab title="Windows" %}
Download the appropriate `.dll` from the [ADBC releases](https://github.com/apache/arrow-adbc/releases) or install via Conda:

```powershell
conda install conda-forge::libadbc-driver-postgresql
```

{% endtab %}
{% endtabs %}

### Driver Discovery

Sling searches for ADBC driver libraries automatically in the following order:

1. **Explicit `driver` property** in the connection configuration
2. **`ADBC_DRIVER_PATH` environment variable** — additional directories to search (colon-separated on Unix, semicolon-separated on Windows)
3. **Standard installation paths:**

| Platform | Paths                                                                                                   |
| -------- | ------------------------------------------------------------------------------------------------------- |
| macOS    | `~/Library/Application Support/ADBC/Drivers`, `~/.dbc/drivers`, `/usr/local/lib`, `/opt/homebrew/lib`   |
| Linux    | `~/.local/share/ADBC/Drivers`, `~/.config/adbc/drivers`, `~/.dbc/drivers`, `/usr/lib`, `/usr/local/lib` |
| Windows  | `%LOCALAPPDATA%\ADBC\Drivers`, `~/.dbc/drivers`, `%ProgramFiles%\ADBC\lib`                              |

Sling looks for driver files matching `*{driver_name}*` (e.g., `libduckdb.so`, `libadbc_driver_postgresql.dylib`).

If the driver is in a non-standard location, you can either set `ADBC_DRIVER_PATH` or specify the full path directly in your connection:

```bash
# Add custom search paths
export ADBC_DRIVER_PATH="/opt/custom/lib:/another/path"
```

```yaml
# Or specify the driver path directly in the connection
connections:
  POSTGRES:
    type: postgres
    host: localhost
    use_adbc: true
    driver: /opt/custom/lib/libadbc_driver_postgresql.dylib
```

## Enabling ADBC on Connections

To use ADBC with your existing database connections, simply add `use_adbc: true` to your connection configuration. This allows you to keep your original connection properties and format while enabling ADBC's high-performance data transfer.

### Connection Properties

The following ADBC-specific properties can be added to any supported database connection:

* `use_adbc` (optional) -> Enable ADBC driver for this connection (`true` or `false`). Default is `false`.
* `adbc_uri` (optional) -> Override the automatically constructed ADBC URI. Sling automatically builds the ADBC URI from your connection properties, but you can specify a custom URI if needed.
* `driver` (optional) -> Explicit path to the ADBC driver library file (e.g., `/usr/local/lib/libadbc_driver_postgresql.dylib`). If not set, Sling auto-discovers the driver.

## Troubleshooting

### "failed to load ADBC driver manager library"

This means the driver manager shared library is not installed or cannot be found.

**Fix:** Install the driver manager (see [Step 1](#step-1-install-the-adbc-driver-manager) above), or set the `ADBC_DRIVER_MANAGER_LIB` environment variable to the full path of the library.

```bash
# Find the library
find / -name "libadbc_driver_manager*" 2>/dev/null

# Set the path
export ADBC_DRIVER_MANAGER_LIB=/path/to/libadbc_driver_manager.so
```

### "Must provide 'driver' parameter"

This means Sling cannot find the database-specific ADBC driver (e.g., the DuckDB or PostgreSQL driver).

**Fix:** Install the driver with `dbc install <driver_name>`, or set `ADBC_DRIVER_PATH` to the directory containing the driver, or set the `driver` property in your connection config.

```bash
# Install the driver
dbc install duckdb

# Or point Sling to the driver location
export ADBC_DRIVER_PATH=/path/to/drivers
```

### Windows: driver not found after dbc install

On Windows, `dbc` installs drivers to `%APPDATA%\adbc\drivers\` (Roaming), but Sling may search `%LOCALAPPDATA%` (Local). Set `ADBC_DRIVER_PATH` to the correct directory:

```powershell
$env:ADBC_DRIVER_PATH = "$env:APPDATA\adbc\drivers"
```

Or specify the driver path directly in your connection:

```yaml
connections:
  DUCKDB:
    type: duckdb
    instance: C:/path/to/file.db
    use_adbc: true
    driver: C:/Users/me/AppData/Roaming/adbc/drivers/duckdb_windows_amd64_v1.4.4/duckdb.dll
```

## Database-Specific Examples

### PostgreSQL with ADBC

```yaml
connections:
  POSTGRES:
    type: postgres
    host: localhost
    user: myuser
    password: mypass
    database: mydatabase
    port: 5432
    use_adbc: true
    # adbc_uri: "postgresql://myuser:mypass@localhost:5432/mydatabase"  # optional override
```

ADBC URI format: `postgresql://user:password@host:port/database`

**Official Documentation:** [Apache ADBC PostgreSQL Driver](https://arrow.apache.org/adbc/current/driver/postgresql.html)

### MySQL with ADBC

```yaml
connections:
  MYSQL:
    type: mysql
    host: localhost
    user: root
    password: mypass
    database: mydb
    port: 3306
    use_adbc: true
    # adbc_uri: "root@tcp(localhost:3306)/mydb"  # optional override
```

ADBC URI format: `user@tcp(host:port)/database`

**Official Documentation:** [Apache ADBC MySQL Driver](https://docs.adbc-drivers.org/drivers/mysql/index.html)

### SQL Server with ADBC

```yaml
connections:
  MSSQL:
    type: sqlserver
    host: localhost
    user: sa
    password: mypass
    database: master
    port: 1433
    use_adbc: true
    # adbc_uri: "mssql://sa:mypass@localhost:1433/master"  # optional override
```

ADBC URI format: `mssql://user:password@host:port/database`

**Official Documentation:** [Apache ADBC SQL Server Driver](https://docs.adbc-drivers.org/drivers/mssql/index.html)

### Snowflake with ADBC

```yaml
connections:
  SNOWFLAKE:
    type: snowflake
    account: myaccount.us-east-1
    user: myuser
    password: mypass
    database: mydb
    schema: myschema
    use_adbc: true
    # adbc_uri: "snowflake://myuser:mypass@myaccount/mydb/myschema"  # optional override
```

ADBC URI format: `snowflake://user:password@account/database/schema`

**Official Documentation:** [Apache ADBC Snowflake Driver](https://arrow.apache.org/adbc/current/driver/snowflake.html)

### DuckDB with ADBC

```yaml
connections:
  DUCKDB:
    type: duckdb
    instance: /path/to/file.db
    use_adbc: true
    # adbc_uri: "duckdb:///path/to/file.db"  # optional override
```

ADBC URI format: `duckdb:///path/to/file.db` or `duckdb://:memory:`

**Official Documentation:** [Apache ADBC DuckDB Driver](https://arrow.apache.org/adbc/current/driver/duckdb.html)

### SQLite with ADBC

```yaml
connections:
  SQLITE:
    type: sqlite
    instance: /path/to/file.db
    use_adbc: true
    # adbc_uri: "sqlite:///path/to/file.db"  # optional override
```

ADBC URI format: `sqlite:///path/to/file.db`

**Official Documentation:** [Apache ADBC SQLite Driver](https://arrow.apache.org/adbc/current/driver/sqlite.html)

### BigQuery with ADBC

```yaml
connections:
  BIGQUERY:
    type: bigquery
    project: myproject
    dataset: mydataset
    key_file: /path/to/service.account.json
    use_adbc: true
    # adbc_uri: "bigquery://myproject"  # optional override
```

ADBC URI format: `bigquery://project`

**Official Documentation:** [Apache ADBC BigQuery Driver](https://docs.adbc-drivers.org/drivers/bigquery/index.html)

### Trino with ADBC

```yaml
connections:
  TRINO:
    type: trino
    http_url: "http://myuser@localhost:8080?catalog=hive&schema=default"
    use_adbc: true
    # adbc_uri: "http://myuser@localhost:8080?catalog=hive&schema=default"  # optional override
```

ADBC URI format: `http://user@host:port?catalog=catalog&schema=schema`

**Official Documentation:** [Apache ADBC Trino Driver](https://docs.adbc-drivers.org/drivers/trino/index.html)

## Using `sling conns`

Here are examples of enabling ADBC on existing connections:

{% code overflow="wrap" %}

```bash
# PostgreSQL with ADBC
$ sling conns set POSTGRES type=postgres host=localhost user=myuser password=mypass database=mydb use_adbc=true

# MySQL with ADBC
$ sling conns set MYSQL type=mysql host=localhost user=root password=mypass database=mydb use_adbc=true

# SQL Server with ADBC
$ sling conns set MSSQL type=sqlserver host=localhost user=sa password=mypass database=master use_adbc=true

# Snowflake with ADBC
$ sling conns set SNOWFLAKE type=snowflake account=myaccount user=myuser password=mypass database=mydb use_adbc=true

# With custom ADBC URI override
$ sling conns set POSTGRES type=postgres host=localhost user=myuser password=mypass database=mydb use_adbc=true adbc_uri="postgresql://myuser:mypass@localhost:5432/mydb"
```

{% endcode %}

## Environment Variable

{% code overflow="wrap" %}

```bash
export POSTGRES='{ type: postgres, host: localhost, user: myuser, password: mypass, database: mydb, use_adbc: true }'

export MYSQL='{ type: mysql, host: localhost, user: root, password: mypass, database: mydb, use_adbc: true }'

export SNOWFLAKE='{ type: snowflake, account: myaccount, user: myuser, password: mypass, database: mydb, use_adbc: true }'
```

{% endcode %}

## Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  # PostgreSQL with ADBC
  POSTGRES:
    type: postgres
    host: localhost
    user: myuser
    password: mypass
    database: mydatabase
    use_adbc: true

  # MySQL with ADBC
  MYSQL:
    type: mysql
    host: localhost
    user: root
    password: mypass
    database: mydb
    use_adbc: true

  # SQL Server with ADBC
  MSSQL:
    type: sqlserver
    host: localhost
    user: sa
    password: mypass
    database: master
    use_adbc: true

  # Snowflake with ADBC
  SNOWFLAKE:
    type: snowflake
    account: myaccount
    user: myuser
    password: mypass
    database: mydb
    schema: myschema
    use_adbc: true

  # DuckDB with ADBC
  DUCKDB:
    type: duckdb
    instance: /path/to/file.db
    use_adbc: true

  # With custom ADBC URI override
  POSTGRES_CUSTOM:
    type: postgres
    host: localhost
    user: myuser
    password: mypass
    database: mydatabase
    use_adbc: true
    adbc_uri: "postgresql://myuser:mypass@localhost:5432/mydatabase?sslmode=require"
```

## Additional Resources

* [Apache ADBC Project](https://arrow.apache.org/adbc/)
* [ADBC Driver Documentation](https://docs.adbc-drivers.org/)
* [dbc CLI Documentation](https://docs.columnar.tech/dbc/)
* [Apache Arrow Documentation](https://arrow.apache.org/)

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).
