ArcadeDB fixed the pg_type bootstrap within a day, verified on the merged build
The native-driver probe of 2026-09-05 found that the Apache Arrow PostgreSQL ADBC driver (1.12.0) could not open a connection to ArcadeDB's PostgreSQL-protocol plugin at all. This note records what happened next, because it happened fast, and because the first verification needed a correction.
Timeline
| When (UTC) | What |
|---|---|
| 2026-09-05 21:19 | Follow-up comment on ArcadeDB's discussion thread with the probe result: Expected 5 or 6 columns from type resolver pg_type query but got 0 |
| 22:11 | ArcadeDB's maintainer opened #7178 with the diagnosis |
| 22:33 | Fix PR #7179 opened, with tests |
| 22:44 | Verified on the PR's CI image: the driver connects (see the correction below) |
| 22:47 | Maintainer filed #7180 for what the driver hits next |
| 2026-09-06 02:48 | PR merged; #7178 closed |
| 03:05 | Verified again on the merged code, this time with the fixture types present |
| 03:29 | Maintainer opened PR #7187 for the ::regclass cast behind GetTableSchema, and #7188 for binary COPY |
| 04:2x | Verified #7187 on its CI build: GetTableSchema answers with five and eight fields |
| 06:31 | #7187 merged; #7180 closed |
What was wrong
The driver bootstraps its type resolver with three queries before it hands back a
connection, and it checks the shape of each answer: zero rows are fine, zero columns are
fatal. The third query selects oid, typname, typreceive, typbasetype, typrelid, typarray
from pg_catalog.pg_type with a WHERE clause of inequalities, a parenthesised OR and a
::TEXT cast. ArcadeDB's emulated pg_type knew neither typreceive nor typsend, and its
WHERE parser accepted a single equality only, so the whole projection was declined and the
answer had no columns. The fix teaches the emulation those columns, with PostgreSQL's real
receive and send function names (the driver selects a column's decoder by that name), and
registers pg_type as a query family of its own so the filter is evaluated.
What the merged build does now
Same seven-step probe, native driver, fixture types created first:
| Step | Driver defaults | With adbc.postgresql.use_copy=false |
|---|---|---|
| connect | passes | passes |
SELECT 1 |
stops: COPY (…) TO STDOUT (FORMAT binary) is not ArcadeDB SQL |
passes |
GetTableSchema |
empty schema, then five fields with #7187 | same |
GetObjects |
lists both types | lists both types |
| read the fixture table | stops at COPY | passes; @rid, @type, @cat as strings, the five properties as int64, string, double, date32 and bool |
So the fix does exactly what #7178 says, and with one driver option the native driver now runs the read workload against ArcadeDB end to end apart from the schema lookup. adbcBridge over psqlodbc passes all seven steps before and after, as it did in the original probe.
ArcadeDB published their own account of this fix and the three that followed it on 2026-09-21: ArcadeDB in the Apache Arrow Ecosystem, Through Its PostgreSQL Wire Protocol.
What is left, and where it is tracked
Both items were in #7180 with the driver's exact statements; one is fixed, one is tracked on its own:
- Binary
COPY … TO STDOUT, #7188, implemented in #7398 on 2026-09-10, four days after it was split out: text, csv and binary, both protocol paths, in 26.10.1. Verified on the snapshot the same day: the stream is correct on the wire and the rows match theDescribeOIDs byte for byte, but the Arrow driver's default path still stops at the first row, because ArcadeDB sends the 19-byte binary header as its ownCopyDatamessage and PostgreSQL sends it inside the first row's message, which is what the driver's reader expects. Fixed on 2026-09-15 in #7607, the morning after the byte-level report: on the26.10.1-SNAPSHOTbuild that carries it, the Arrow driver with its defaults passes the whole seven-step probe and decodes real rows through binary COPY.use_copy=falseis no longer needed from 26.10.1. The issue was closed on 2026-09-15, and a wider check on the same build passed with the driver's defaults: an empty result set (header and trailer with no rows, the case the fix names), one row, 10,000 rows in oneCOPY, a NULL in every column, text outside the Basic Multilingual Plane,GetTableSchemaandGetObjects. GetTableSchema, now fixed. The driver's statement joinspg_class,pg_attributeandpg_typewithcls.oid = $1::regclass::oid; ArcadeDB ignored theregclasscast, so a name was compared with a number and the statement was answered with zero rows. PR #7187 makes::regclassand::regtypereal lookups; on its buildadbc_bigdescribes with its five properties andadbc_twith all eight, and the whole seven-step read probe passes withuse_copy=false.
All three fixes ship in ArcadeDB 26.10.1, the October release, and are in the
26.10.1-SNAPSHOT build now. With them the native driver works out of the box; the ArcadeDB row
in the probe note and on the ArcadeDB page will say so once 26.10.1 is out.
A correction to the first verification
The first verification, on the PR's CI image, reported two further stops that were not
ArcadeDB's: GetObjects returning no tables and SELECT * FROM "adbc_big" failing with
"type not found". Both came from the probe's own order of operations. It runs the native
driver before the ODBC pass, and the ODBC pass is what creates the fixture types, so on a
freshly started image the native run saw a database with nothing in it. With the types
present, GetObjects lists everything and quoted identifiers work. The correction was
posted on the PR and on #7180 the same evening, and the probe is now run twice on a fresh
server so the second pass measures a populated database.
Trying it
docker run -d -p 5432:5432 \
-e JAVA_OPTS="-Darcadedb.server.rootPassword=… -Darcadedb.server.defaultDatabases=adbc[adbc:adbc] \
-Darcadedb.server.plugins=Postgres:com.arcadedb.postgres.PostgresProtocolPlugin" \
arcadedata/arcadedb:latest
import adbc_driver_postgresql.dbapi as pg
from adbc_driver_postgresql import StatementOptions
conn = pg.connect("postgresql://root:…@127.0.0.1:5432/adbc", autocommit=True)
cur = conn.cursor()
cur.adbc_statement.set_options(**{StatementOptions.USE_COPY.value: "false"})
cur.execute("SELECT * FROM adbc_big")
print(cur.fetch_arrow_table())
Until 26.10.1 is out, that needs the 26.10.1-SNAPSHOT build. The ODBC route works on the
released 26.9.1 today:
import adbcbridge
conn = adbcbridge.connect(uri="Driver=psqlodbcw.so;Server=127.0.0.1;Port=5432;Database=adbc;Uid=root;Pwd=…;BoolsAsChar=0;")