# YugabyteDB into Apache Arrow through ADBC, using psqlodbc 16 (PG wire) (adbcBridge 0.1.0)

**URL:** https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201
**Category:** General
**Created:** [September 1, 2026, 10:27am UTC](https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201 "2026-09-01T10:27:53Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![singhpratech](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/singhpratech/32/1030_2.png) [@singhpratech](https://forum.yugabyte.com/u/singhpratech)
#### Post date: [September 1, 2026, 10:27am UTC](https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201/1 "2026-09-01T10:27:53Z")

</div>

adbcBridge is a small Apache-2.0 ADBC driver written in C11 that loads an ODBC driver and exposes it through the Arrow ADBC C ABI: block-cursor reads straight into Arrow record batches, bulk ingest, metadata, partitioned parallel reads. I ran YugabyteDB through it as one of 46 databases in a single compatibility workload and wanted to share the entry here, since the quirks it records are YugabyteDB-specific.

What was verified (YugabyteDB 2026.1 (YSQL); driver: psqlodbc 16 (PG wire)):  
Linux: PASS  
macOS arm64: PASS (YugabyteDB, PostgreSQL wire 15.12, arm64)  
Windows x64: PASS (YugabyteDB 2026.1.1.1, PostgreSQL wire 15.12; psqlodbc 18.00.0002)

What the compatibility entry records:  
no quirks; YSQL is PostgreSQL 15, and its internal row id is a system column so GetObjects is unaffected; version() carries -YB-, so the PostgreSQL array-ingest form stays off (verified).  
Full entry: docs/COMPATIBILITY.md in the repository.

The postgresql ADBC driver may also work with YugabyteDB over its wire protocol; this path goes through psqlodbc 16 (PG wire) and records exactly what it needed, so it is a second, documented route rather than a replacement. ExecutePartitions splits a query on yb\_hash\_code() so a parallel read follows the tablets rather than a key range; the partition benchmark in bench/BENCHMARKS.md shows what that gains.

Trying it (Python; Rust, Go, Java and C# are on the docs site):

pip install adbcbridge

import adbcbridge  
with adbcbridge.connect(uri=“Driver=psqlodbcw.so;Servername=127.0.0.1;Port=5433;Database=yugabyte;Username=yugabyte;”) as conn:  
with conn.cursor() as cur:  
cur.execute(“SELECT …”)  
table = cur.fetch\_arrow\_table() # a pyarrow.Table

Repository (the full compatibility entry, docs, upstream notes and the PyPI package are all linked from its README):

> **[GitHub - singhpratech/adbcbridge: Any ODBC driver as an Apache Arrow ADBC driver....](https://github.com/singhpratech/adbcbridge)**
>
> Any ODBC driver as an Apache Arrow ADBC driver. One C library, 46 databases verified on Linux, macOS and Windows, five languages.

It is a 0.1.0. If the entry says something wrong about YugabyteDB, or you run a version or driver I didn’t, an issue on the repository with the details is the most useful thing you could send.

▎ Update (Sep 1): adbcBridge is now listed in the Apache Arrow ADBC documentation, on the Tools & Integrations page : [Tools & Integrations - ADBC 25 (dev) Documentation](https://arrow.apache.org/adbc/main/integrations.html)

---

<div class="post-metadata">

### Author: ![singhpratech](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/singhpratech/32/1030_2.png) [@singhpratech](https://forum.yugabyte.com/u/singhpratech)
#### Post date: [September 5, 2026, 9:37pm UTC](https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201/2 "2026-09-05T21:37:54Z")

</div>

A follow-up with one new measurement and one correction that matters for YDB users.

On 2026-09-05 I ran the same seven-step ADBC workload (connect, SELECT 1, DDL + inserts + read, 1,000-row `adbc_ingest`, GetTableSchema, GetObjects, read back) through the Apache Arrow native PostgreSQL ADBC driver (1.12.0) and through adbcBridge over psqlodbc, against YDB’s PostgreSQL-wire endpoint.

Native driver: connects, then stops at SELECT 1 with `could not begin COPY: … RawStmt: alternative is not implemented yet : 138`. The driver reads every result through `COPY … TO STDOUT (FORMAT binary)`, which YDB’s PG layer does not implement. Ingest also fails (`Postgres type with oid 0 not found`).  
ODBC path: all seven steps pass.

The correction: adbcBridge can hand a connection to a native ADBC driver when it recognises one (`adbc.odbc.delegate`, default `auto`). With `adbc-driver-postgresql` installed in the same environment, 0.1.0 delegated the YDB connection because it saw psqlodbc, and the connection then failed exactly as above. Workaround on 0.1.0: set `adbc.odbc.delegate=never` (Python: `adbcbridge.connect(..., delegate="never")`). The fix, probing the native driver before handing over and falling back to ODBC, is in [delegate: probe the native driver before handing a PostgreSQL-wire connection to it by singhpratech · Pull Request #74 · singhpratech/adbcbridge · GitHub](https://github.com/singhpratech/adbcbridge/pull/74) and ships in 0.1.1.

Full table for all 28 PostgreSQL-wire and MySQL-wire databases: [Where the native PostgreSQL and MySQL ADBC drivers stop on wire-compatible databases — adbcBridge notes](https://adbcbridge.org/notes/native-adbc-drivers-on-wire-compatible-databases/)

---

<div class="post-metadata">

### Author: ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)
#### Post date: [September 8, 2026, 4:23pm UTC](https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201/3 "2026-09-08T16:23:40Z")

</div>

> [@singhpratech](#):
>
> Native driver: connects, then stops at SELECT 1 with `could not begin COPY: … RawStmt: alternative is not implemented yet : 138`. The driver reads every result through `COPY … TO STDOUT (FORMAT binary)`, which YDB’s PG layer does not implement. Ingest also fails (`Postgres type with oid 0 not found`).  
> ODBC path: all seven steps pass.

Hi @singhpratech

Can you provide a minimal test script/query to reproduce this? We do support `COPY (FORMAT binary)`. Maybe it’s related to [Multiple test failures in Rust when Connection Manager is enabled · Issue #31564 · yugabyte/yugabyte-db · GitHub](https://github.com/yugabyte/yugabyte-db/issues/31564) when run under connection manager?

Or maybe it failed on “YDB” which is a different database from YugabyteDB?

---

<div class="post-metadata">

### Author: ![singhpratech](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/singhpratech/32/1030_2.png) [@singhpratech](https://forum.yugabyte.com/u/singhpratech)
#### Post date: [September 8, 2026, 8:13pm UTC](https://forum.yugabyte.com/t/yugabytedb-into-apache-arrow-through-adbc-using-psqlodbc-16-pg-wire-adbcbridge-0-1-0/5201/4 "2026-09-08T20:13:55Z")

</div>

Hi Dorian, thank you for reading it that closely, and my apologies: your second guess is right. That follow-up is about YDB, the Yandex database, and belongs on the YDB thread. I pasted it here by mistake on Friday. YugabyteDB was not the database that failed, and nothing in the entry above changed.

For the record, here is what the same seven-step run measured on YugabyteDB with the native PostgreSQL ADBC driver, re-run today:

```auto
server : PostgreSQL 15.12-YB-2026.1.1.1-b0 on x86_64-pc-linux-gnu
driver : adbc-driver-postgresql 1.12.0
SELECT 1 -> [{'?column?': 1}] # read via COPY (SELECT 1) TO STDOUT (FORMAT binary)
ingest -> 1000 rows via COPY FROM STDIN
read back-> [{'count': 1000, 'min': 0, 'max': 999}]
schema -> id: int32, val: double

```

All seven steps pass, COPY (FORMAT binary) included. The script, in case it is useful to anyone:

```python
import adbc_driver_postgresql.dbapi as pg, pyarrow as pa
uri = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte"
with pg.connect(uri, autocommit=True) as conn, conn.cursor() as cur:
    cur.execute("SELECT version()"); print("server :", cur.fetchone()[0][:60])
    cur.execute("SELECT 1"); print("SELECT 1 ->", cur.fetch_arrow_table().to_pylist())
    tbl = pa.table({"id": pa.array(range(1000), pa.int32()), "val": pa.array([i/7 for i in range(1000)])})
    cur.adbc_ingest("adbc_copy_check", tbl, mode="create"); print("ingest -> 1000 rows via COPY FROM STDIN")
    cur.execute("SELECT count(*), min(id), max(id) FROM adbc_copy_check"); print("read back->", cur.fetch_arrow_table().to_pylist())
    print("schema ->", conn.adbc_get_table_schema("adbc_copy_check"))
    cur.execute("DROP TABLE adbc_copy_check")

```

Setup: the `yugabytedb/yugabyte` 2026.1.1.1 image started with plain `yugabyted start`, no connection manager, so #31564 was not involved either. The comparison table in the note ([Where the native PostgreSQL and MySQL ADBC drivers stop on wire-compatible databases — adbcBridge notes](https://adbcbridge.org/notes/native-adbc-drivers-on-wire-compatible-databases/)) has always listed YugabyteDB under “both pass”, the native driver and the ODBC route through [adbcBridge](https://github.com/singhpratech/adbcbridge) alike, and the YugabyteDB compatibility entry there still reads “no quirks”.

I will edit the post above to say so, or ask a moderator to move it if the edit window has closed. Sorry for the noise.
