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

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):

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

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 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

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 when run under connection manager?

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

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:

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:

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) has always listed YugabyteDB under “both pass”, the native driver and the ODBC route through 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.