Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ table with neither gets one partition. The numbers are in
| InfluxDB 3 Core (InfluxDB IOx 2.0, Arrow Flight SQL) | Flight SQL ODBC 0.9.7 (Dremio, open source) | PASS (read) | a second Flight SQL server behind the same driver, and it needed no new driver quirk (the `SQLColumns` one is shared with sqlflite — here it crashes only for tables whose Flight SQL schema carries no per-field metadata, InfluxDB's `system` and `information_schema` tables, while the entry's own `iox` tables fetch cleanly); the entry is read-only twice over (InfluxDB 3's SQL is query-only — DDL answers `DDL not supported: <op>`, DML `DML not supported: <op>`, and tables come into existence when line protocol is written to them over the HTTP API — and the driver has no `SQLBindParameter`); server side: a table is tags, fields and a nanosecond `time` column that is always spelled `time`, with no `DATE`, `DECIMAL` or binary type, so the entry reads `time` as `ts` and casts the date back in its own `SELECT`; fetch 1.03M rows/s |
| Dremio 26.0.5 (OSS, Arrow Flight SQL) | Flight SQL ODBC 0.9.7 (Dremio, open source) | PASS (read) | the engine that publishes this driver, and it needed no new driver quirk — `no_sql_columns` is keyed on the driver name, so Dremio takes the path shared with sqlflite and InfluxDB, though against Dremio 26 `SQLColumns` does not in fact crash (it describes its 18 result columns and fetches every row), so here the quirk costs a describe rather than avoiding a segfault; read-only because of the driver alone -- Dremio writes fine (`$scratch`, the writable source a stock dremio-oss ships, takes CTAS, and a table created there with a column list is Iceberg and takes `INSERT`), but `SQLBindParameter` is `HYC00 Unsupported function` even after a `SQLPrepare` that succeeds, and `SQLNumParams` reports 0, so no parameter can reach the server and `setup` builds both tables with literal `CREATE TABLE IF NOT EXISTS ... AS SELECT`; unlike sqlflite the driver reports a `DECIMAL`'s declared scale — described as (19, *s*), precision still always 19 — so decimals arrive exact in a wider decimal128 rather than as text; a string literal holding any character outside ISO-8859-1 (a BMP `漢` as much as an emoji) needs the `_UTF8'…'` prefix or Dremio's parser encodes it as ISO-8859-1 and fails planning; server side, the first admin user has to be created over the REST API before any login works, and the query context comes from a `schema` connection property the driver forwards as a gRPC header; fetch 1.1M rows/s |
| Microsoft Access `.mdb`/`.accdb` | MDB Tools 1.0 (`odbc-mdbtools`) | PASS (read) | the driver executes no DDL/DML and has no `SQLBindParameter`; 32-bit `SQLLEN`, as Db2 |
| ArcadeDB 26.9 (PostgreSQL wire) | psqlodbc 16 (PG wire) | PASS (read) | multi-model engine behind the PG wire: no `CREATE TABLE` at all (a table is a document type plus one `CREATE PROPERTY` per column), so `adbc_ingest`'s generated DDL has nowhere to go and the entry runs the read side — queries, parameters and the catalog all work; driver quirks handled: psqlodbc's `SQLColumns` and `SQLTables(SQL_ALL_TABLE_TYPES)` are queries its parser will not run -- `SQLColumns` answers `SQL_SUCCESS` with zero rows, `SQLTables(SQL_ALL_TABLE_TYPES)` answers `SQL_ERROR` -- so `GetObjects` describes a zero-row SELECT and `GetTableTypes` falls back to the types the server's own tables have; `BoolsAsChar=0`, ISO-8601 `T` timestamp literals, `@rid`/`@type`/`@cat` in every `SELECT *`; also traverses a small graph (vertices, edges, `expand(out())`); fetch 332k rows/s. ArcadeDB published an account of this integration and the four protocol findings behind it on 2026-09-21: <https://arcadedb.com/blog/arcadedb-apache-arrow-adbc-postgresql-wire/>. Native-driver status, for comparison: the Apache Arrow PostgreSQL ADBC driver (1.12.0) could not connect at all until ArcadeDB fixed its `pg_type` bootstrap ([#7178](https://github.com/ArcadeData/arcadedb/issues/7178), opened and merged by the maintainer within a day of the [probe note](https://adbcbridge.org/notes/native-adbc-drivers-on-wire-compatible-databases/), 2026-09-06; ships in 26.10.1, in `26.10.1-SNAPSHOT` now); on the merged build it connects and lists types, stops at `COPY … TO STDOUT (FORMAT binary)` with its defaults, and with `adbc.postgresql.use_copy=false` reads the fixture end to end; `GetTableSchema`'s `::regclass` lookup, the last catalog gap, is fixed in [#7187](https://github.com/ArcadeData/arcadedb/pull/7187) (merged 2026-09-06, also in 26.10.1); binary `COPY` itself, [#7188](https://github.com/ArcadeData/arcadedb/issues/7188), was implemented in [#7398](https://github.com/ArcadeData/arcadedb/pull/7398) and its framing matched to PostgreSQL's in [#7607](https://github.com/ArcadeData/arcadedb/pull/7607) (2026-09-15), so on `26.10.1-SNAPSHOT` the native driver passes the whole probe with its defaults; on the released 26.9.1 the ODBC route above is the one that works |
| ArcadeDB 26.9 (PostgreSQL wire) | psqlodbc 16 (PG wire) | PASS (read) | multi-model engine behind the PG wire: no `CREATE TABLE` at all (a table is a document type plus one `CREATE PROPERTY` per column), so `adbc_ingest`'s generated DDL has nowhere to go and the entry runs the read side — queries, parameters and the catalog all work; driver quirks handled: psqlodbc's `SQLColumns` and `SQLTables(SQL_ALL_TABLE_TYPES)` are queries its parser will not run -- `SQLColumns` answers `SQL_SUCCESS` with zero rows, `SQLTables(SQL_ALL_TABLE_TYPES)` answers `SQL_ERROR` -- so `GetObjects` describes a zero-row SELECT and `GetTableTypes` falls back to the types the server's own tables have; `BoolsAsChar=0`, ISO-8601 `T` timestamp literals, `@rid`/`@type`/`@cat` in every `SELECT *`; also traverses a small graph (vertices, edges, `expand(out())`); fetch 332k rows/s. ArcadeDB published an account of this integration and the four protocol findings behind it on 2026-09-21: <https://arcadedb.com/blog/arcadedb-apache-arrow-adbc-postgresql-wire/>. The `T`-literal requirement is a 26.9.1 trait only: the silent `NULL` behind it, [#8090](https://github.com/ArcadeData/arcadedb/issues/8090), is fixed in [#8096](https://github.com/ArcadeData/arcadedb/pull/8096) (merged 2026-09-22, ships in 26.10.1), and on `26.10.1-SNAPSHOT` the space-and-fraction literal and a bound timestamp parameter both round-trip, verified here 2026-09-22. Native-driver status, for comparison: the Apache Arrow PostgreSQL ADBC driver (1.12.0) could not connect at all until ArcadeDB fixed its `pg_type` bootstrap ([#7178](https://github.com/ArcadeData/arcadedb/issues/7178), opened and merged by the maintainer within a day of the [probe note](https://adbcbridge.org/notes/native-adbc-drivers-on-wire-compatible-databases/), 2026-09-06; ships in 26.10.1, in `26.10.1-SNAPSHOT` now); on the merged build it connects and lists types, stops at `COPY … TO STDOUT (FORMAT binary)` with its defaults, and with `adbc.postgresql.use_copy=false` reads the fixture end to end; `GetTableSchema`'s `::regclass` lookup, the last catalog gap, is fixed in [#7187](https://github.com/ArcadeData/arcadedb/pull/7187) (merged 2026-09-06, also in 26.10.1); binary `COPY` itself, [#7188](https://github.com/ArcadeData/arcadedb/issues/7188), was implemented in [#7398](https://github.com/ArcadeData/arcadedb/pull/7398) and its framing matched to PostgreSQL's in [#7607](https://github.com/ArcadeData/arcadedb/pull/7607) (2026-09-15), so on `26.10.1-SNAPSHOT` the native driver passes the whole probe with its defaults; on the released 26.9.1 the ODBC route above is the one that works |
| Materialize 26.38 | psqlodbc 16 (PG wire) | PASS | streaming warehouse; PostgreSQL SQL layer, so no driver quirks -- but no `SAVEPOINT`, so the entry sets psqlodbc's `Protocol=7.4-0` to stop the driver wrapping the second batch of a large ingest in one (with that setting, a prepared statement freed before a manual commit also lost the transaction's rows through a psqlodbc/Materialize pair of defects: fixed in psqlodbc 18.00.0003 and in Materialize [#38606](https://github.com/MaterializeInc/materialize/pull/38606), merged 2026-09-14, verified on its main image, not yet in a Materialize release); its single 39-digit `NUMERIC` is wider than an Arrow decimal128, so decimals read back as exact strings; also ingests into and reads back an incrementally maintained `MATERIALIZED VIEW`; ingest 23.6k rows/s (23.7k with array binding), fetch 322k rows/s |
| Apache Ignite 2.17 | Ignite ODBC (built from the sources in the image) | PASS | in-memory key-value grid with a SQL engine: no prebuilt Linux driver exists, so `platforms/cpp` is built root-free (`-DWITH_ODBC=ON -DWITH_CORE=OFF`, no JVM); driver quirks handled: no wide SQL type at all (`SQL_WVARCHAR` refused outright by `SQLBindParameter`, `SQL_C_WCHAR` sized in `wchar_t`) so the UTF-8 narrow path, as for Firebird, and column-wise parameter arrays that test the NULL indicator of row 0 for every row — a NULL below the first row is dropped rather than sent: a character column stores an empty string, and a `BINARY` column segfaults the client inside `SQLExecute` (`WriteInt8Array` is handed the -1 indicator as its length), so arrays are off (row-wise binding is refused outright). `SQL_DRIVER_VER` and `SQL_DBMS_VER` are both the hardcoded `02.04.0000`, neither the server's 2.17.0 nor the negotiated protocol 2.13.0. Server side: every table is a cache and must declare a `PRIMARY KEY`, which generated ingest DDL cannot, so `mode="create"` is impossible (`ingest_create=False`) and the entry ingests by appending into a keyed table; identifiers fold to upper case and the driver reports no quote character. Fetch 930k rows/s; append into a keyed table ~95k rows/s |
| Google Cloud Spanner (emulator + PGAdapter 0.55) | psqlodbc 16 (PG wire) | PASS | two driver quirks, both keyed on a PGAdapter-only setting because `version()` just says PostgreSQL 14.1: psqlodbc inlines a parameter array's timestamps as `'...'::timestamp`, a type Spanner does not have, so a batch binding a timestamp goes row-at-a-time (`no_timestamp_param_arrays`); and every Spanner table needs a PRIMARY KEY, so generated ingest DDL adds a surrogate `GENERATED BY DEFAULT AS IDENTITY` column (`ingest_key_column`). Server side: no 32-bit integer, no `TIMESTAMP WITHOUT TIME ZONE` (so `ts` reads back zone-aware), no modifier on `NUMERIC`, no DDL inside a transaction; also ingests into and reads back an `INTERLEAVE IN PARENT` child table. A third quirk on the same key is Spanner's ceiling of **950 parameters per statement** (`max_statement_params`): PGAdapter prepares a multi-row INSERT that carries more without complaint and then closes the connection at `SQLExecute` (`08S01`), leaving the batching's halving search no connection to halve on -- measured exactly, 948 parameters go through and 952 drop the connection -- so it is declared rather than probed, and ingest runs at 237 four-column rows per INSERT. ingest 7.3k rows/s (7.4k with array binding), fetch 95.8k rows/s at `--rows 300 --fetch-rows 2000`, which is the size this entry is benchmarked at |
Expand Down
2 changes: 1 addition & 1 deletion docs/UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ before it is filed.
| 2026-09-05 | ArcadeDB | [ArcadeData/arcadedb#7178](https://github.com/ArcadeData/arcadedb/issues/7178) (opened by the maintainer from the [discussion follow-up](https://github.com/ArcadeData/arcadedb/discussions/6888#discussioncomment-18309009)) | The Arrow native PostgreSQL ADBC driver cannot connect to ArcadeDB's PostgreSQL-protocol plugin: its type-resolver bootstrap `SELECT oid, typname, typreceive, typbasetype, typrelid, typarray FROM pg_catalog.pg_type WHERE …` is answered with zero columns (`Expected 5 or 6 columns from type resolver pg_type query but got 0`), because the emulated `pg_type` knows neither `typreceive` nor `typsend` and its WHERE parser accepts only a single equality. Found by the 2026-09-05 native-driver probe; the maintainer's own diagnosis is in the issue. | **fixed on main**: [ArcadeData/arcadedb#7179](https://github.com/ArcadeData/arcadedb/pull/7179), opened by the maintainer the same day and merged 2026-09-06 (558e6042); ships in ArcadeDB 26.10.1 (October 2026, per the maintainer) and is in `26.10.1-SNAPSHOT` now. Verified on the PR's CI build with the fixture types present: the native driver connects and `GetObjects` lists the types; with the driver's defaults it then stops at the first result set because ArcadeDB has no `COPY (…) TO STDOUT (FORMAT binary)` (the CockroachDB, CrateDB and YDB stop); with `adbc.postgresql.use_copy=false` reads work end to end and only `GetTableSchema` (its `$1::regclass::oid` lookup) returns an empty schema. Follow-up issue [#7180](https://github.com/ArcadeData/arcadedb/issues/7180) carried the driver's exact statements; its `GetTableSchema` item (the `::regclass` cast) is **fixed in [#7187](https://github.com/ArcadeData/arcadedb/pull/7187)**, merged 2026-09-06 (ec871770), verified on its CI build: five and eight fields with the right Arrow types. Binary `COPY` was tracked as [#7188](https://github.com/ArcadeData/arcadedb/issues/7188), implemented in [#7398](https://github.com/ArcadeData/arcadedb/pull/7398) on 2026-09-10 and framed like PostgreSQL's in [#7607](https://github.com/ArcadeData/arcadedb/pull/7607) on 2026-09-15; with all three, the native driver passes the whole probe with its defaults on `26.10.1-SNAPSHOT`. |
| 2026-09-06 | ArcadeDB | [ArcadeData/arcadedb#7188](https://github.com/ArcadeData/arcadedb/issues/7188) (opened by the maintainer from the probe follow-up) | `COPY (<query>) TO STDOUT`, text and binary, is not supported by the PostgreSQL-protocol plugin; the Arrow native PostgreSQL ADBC driver reads every result through binary `COPY` by default, so with defaults it stops at the first result set. The driver's `adbc.postgresql.use_copy=false` statement option reads through ordinary binary-format results and works end to end on ArcadeDB, which the issue records. | **fixed on main**: [ArcadeData/arcadedb#7398](https://github.com/ArcadeData/arcadedb/pull/7398) (merged 2026-09-10) implemented `COPY (<query>) TO STDOUT` in text, csv and binary on both protocol paths; the one framing detail left between it and the Arrow driver's default path (the binary header sent as its own `CopyData` message, [reported](https://github.com/ArcadeData/arcadedb/issues/7188#issuecomment-5647328956) with both servers' chunk dumps on 2026-09-12) was fixed by the maintainer in [ArcadeData/arcadedb#7607](https://github.com/ArcadeData/arcadedb/pull/7607), merged 2026-09-15 (3bdb3451b). Verified the same morning on `26.10.1-SNAPSHOT` build 99f4cb48: the Arrow PostgreSQL ADBC driver 1.12.0 with its defaults passes all seven probe steps and decodes real rows (int64, string, double, date32, bool) through binary COPY, no `use_copy=false` needed. The maintainer closed the issue on 2026-09-15; re-verified the same day past the probe — an empty result set (header and trailer with no rows, the case the fix names), one row, 10,000 rows in one `COPY`, a NULL in every column, non-BMP text, `GetTableSchema` and `GetObjects` — all correct with the driver's defaults. Ships in ArcadeDB 26.10.1 |
| 2026-09-04 | SingleStore Connector/ODBC | [memsql/singlestore-odbc-connector#46](https://github.com/memsql/singlestore-odbc-connector/issues/46) | `SQLColumns` with a NULL `CatalogName` segfaults the client on a connection opened without `Database=`: `TABLE_CAT` falls back to the client library's current-database field, which stays NULL after `USE`, and `strdup(NULL)` is called (`ma_statement.c`). Zero matching rows, an explicit catalog, or `Database=` in the connection string avoid it. | open — **fix PR [#47](https://github.com/memsql/singlestore-odbc-connector/pull/47) (ours)**, opened 2026-09-17: `TABLE_CAT` NULL instead of `strdup(NULL)` in `SQLColumns` and `SQLPrimaryKeys`, with a test; verified against SingleStore 9.1.1 |
| 2026-09-21 | ArcadeDB | [ArcadeData/arcadedb#8090](https://github.com/ArcadeData/arcadedb/issues/8090) | A `DATETIME_MICROS` (also `DATETIME_NANOS`, `DATETIME`) value written as a string with a space separator **and** a fractional second — `'2024-02-29 13:45:10.123456'`, exactly the form psqlodbc renders a bound timestamp in — is stored as `NULL` while the `INSERT` reports success. Either half alone is fine: the `T` separator round-trips, and the space form without a fraction round-trips. Carried into the project's own tracker by a maintainer after we documented it in the compatibility notes, with the root cause named: a blanket catch in `Type.convert()` logs at `FINE` and returns `null`. Every PostgreSQL-wire client that binds a timestamp against a sub-second property is affected, not only this driver | **open**, filed 2026-09-21 by the project (Luca Garulli) and labelled `severity:critical`, crediting the report; a reproducer and the root cause are in the issue. ArcadeDB published an account of this and the three earlier findings on 2026-09-21: [arcadedb.com](https://arcadedb.com/blog/arcadedb-apache-arrow-adbc-postgresql-wire/) |
| 2026-09-21 | ArcadeDB | [ArcadeData/arcadedb#8090](https://github.com/ArcadeData/arcadedb/issues/8090) | A `DATETIME_MICROS` (also `DATETIME_NANOS`, `DATETIME`) value written as a string with a space separator **and** a fractional second — `'2024-02-29 13:45:10.123456'`, exactly the form psqlodbc renders a bound timestamp in — is stored as `NULL` while the `INSERT` reports success. Either half alone is fine: the `T` separator round-trips, and the space form without a fraction round-trips. Carried into the project's own tracker by a maintainer after we documented it in the compatibility notes, with the root cause named: a blanket catch in `Type.convert()` logs at `FINE` and returns `null`. Every PostgreSQL-wire client that binds a timestamp against a sub-second property is affected, not only this driver | **fixed** in [#8096](https://github.com/ArcadeData/arcadedb/pull/8096), merged 2026-09-22 by the project (Luca Garulli), who had filed the issue on 2026-09-21 as `severity:critical`, crediting the report and naming the root cause. The space-and-fraction form is now accepted, and a value no parser can read fails the write with an error naming it instead of storing `NULL`; reads stay lenient and return `NULL`. Verified here on `26.10.1-SNAPSHOT` (build `382ae09d`, 60 commits past the merge) on 2026-09-22: the literal and the bound parameter both round-trip to the microsecond, an unreadable value raises SQLSTATE 22023 through psqlodbc, and the column now reaches Arrow as `timestamp[us]` rather than a string. Awaiting the 26.10.1 release. ArcadeDB published an account of this and the three earlier findings on 2026-09-21: [arcadedb.com](https://arcadedb.com/blog/arcadedb-apache-arrow-adbc-postgresql-wire/) |

## Documented here, not yet reported

Expand Down
Loading
Loading