← All databases

Database · native ODBC

OpenLink Virtuoso into Apache Arrow with ADBC

OpenLink Virtuoso 7.2, read and written through adbcBridge — the ADBC driver that loads the database's ODBC driver — verified on Linux, macOS arm64 and Windows x64. Everything below is the compatibility matrix's record for this row.

Status

Linux✓ pass

PASS

macOS arm64✓ pass

PASS (OpenLink Virtuoso (via ODBC) 07.20.3243) through a bridge built against iODBC 3.52.16, once the virtodbc quirk stopped forcing the narrow path on a four-byte-SQLWCHAR build — there the driver's narrow charset is single-byte (a héllo statement literal never matches, and CHARSET=UTF-8 reads back one byte per unit) while its wide path is correct end to end; Python fetch 252,282 rows/s, ingest 3,128. Through unixODBC it aborts at the first failing statement: the driver is iODBC-width and unixODBC's driver manager overflows its own sqlstate buffer reading the diagnostic (lurcher/unixODBC#239, openlink/virtuoso-opensource#1469)

Windows x64✓ pass

PASS (OpenLink Virtuoso 07.20.3243 container; the Windows Virtuoso Open Source 7.2 installer's Virtuoso (Open Source) driver, virtodbc.dll)

Driver and connection string

ODBC driver
Virtuoso ODBC (virtodbc.so, ANSI build)
Wire
native ODBC
adbcBridge
0.1.1 (release)

The connection string the matrix used, as the connection strings reference records it (Databases with their own native protocol and ODBC driver); {drv} is the driver library or its name from odbcinst.ini, and the host, port and credentials are the test server's.

Driver={drv};HOST=127.0.0.1:11111;UID=dba;PWD=adbc;

Python

import adbcbridge

# {drv}: the ODBC driver library (path), or its name from odbcinst.ini
conn = adbcbridge.connect(uri="Driver={drv};HOST=127.0.0.1:11111;UID=dba;PWD=adbc;")
with conn.cursor() as cur:
    cur.execute("SELECT * FROM my_table")
    table = cur.fetch_arrow_table()      # pyarrow.Table

Polars and pandas

import polars as pl, pandas as pd

df = pl.read_database("SELECT * FROM my_table", connection=conn)   # Polars, Arrow-native
pdf = pd.read_sql("SELECT * FROM my_table", conn)                   # pandas 2.2+, ADBC connection

pip install adbcbridge brings the driver library; the OpenLink Virtuoso ODBC driver is installed the way its vendor documents, then named in Driver=. Rust, Go, C# and Java use the same connection string through their ADBC driver managers — see the docs.

What the matrix recorded

ODBC-native server; driver quirks handled: SQL_C_WCHAR is a 4-byte wchar_t on both the parameter and the fetch side, not unixODBC's 2-byte SQLWCHAR (UTF-8 narrow path instead), SQL_C_SBIGINT is stored as 0 and read back as 0 without a diagnostic (64-bit ints sent as text declared SQL_NUMERIC, the one declaration that converts exactly), and datetime parameter arrays are strided by ColumnSize rather than by the C struct — a DATE32 bound with ColumnSize 0 repeats row 0 (so no parameter arrays); no BOOLEAN type.

What this stack needed

Read next