Skip to content
Closed
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
3 changes: 2 additions & 1 deletion docs/UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ before it is filed.

| Date | Project | Report | What it is | Status |
|---|---|---|---|---|
| 2026-09-21 | ArcadeDB | [ArcadeData/arcadedb#8090](https://github.com/ArcadeData/arcadedb/issues/8090) (opened by the maintainer from the case-study exchange, credited to this project) | A `DATETIME_MICROS` (also `DATETIME`, `DATETIME_NANOS`) literal written with a space separator *and* a fraction — `'2024-02-29 13:45:10.123456'`, the form psqlodbc renders a bound `SQL_TYPE_TIMESTAMP` parameter in — is accepted by `INSERT` and stored as NULL, with no error and nothing logged at the default level. The space alone parses and the fraction alone parses; the two together fail every parser `Type.convert()` tries, and its blanket `catch (Exception)` logs at `FINE` and returns null, so the same construct turns *any* unparseable value for *any* target type into NULL. Recorded here as a documented behaviour since 2026-08-28 (`tests/compat/README.md`); the maintainer reproduced it on main, wrote the root cause and a two-part fix into the issue, and labelled it critical. Reproduced from here on 26.9.1 on 2026-09-21, text and binary result formats and through psqlodbc. | open |
| 2026-08-28 | ArcadeDB | [ArcadeData/arcadedb#6674](https://github.com/ArcadeData/arcadedb/issues/6674) (reported by an ArcadeDB contributor on 2026-08-24, not from this project; listed because this tracker carried the symptom as "documented, not yet reported" until 2026-09-21) | A NULL in a `BOOLEAN` column arrived over the wire as `false` with a non-NULL indicator: the text serializer wrote `"0"` for a NULL, the binary path wrote the `-1` sentinel, so text and binary disagreed. Observed here on `arcadedata/arcadedb:latest` = 26.8.1; the matrix entry masked it with `not_null=("bo",)`. | **fixed** the day it was reported, shipped in 26.9.1 (2026-09-03). Retested here on 26.9.1 on 2026-09-21: NULL round-trips on the text and binary paths and through psqlodbc; the matrix entry's `not_null` flag is removed and the all-NULL row check covers the column again. |
| 2026-09-17 | ArcadeDB | [ArcadeData/arcadedb#7815](https://github.com/ArcadeData/arcadedb/pull/7815) | PostgreSQL wire, simple query protocol: `BEGIN`, `COMMIT`, `ROLLBACK` and the savepoint statements are answered with a zero-field `RowDescription` before the `CommandComplete`, so libpq reports `PGRES_TUPLES_OK` instead of `PGRES_COMMAND_OK`; `psql` prints an empty table after `BEGIN` and the Arrow PostgreSQL ADBC driver, whose DB-API starts with autocommit off, fails `[libpq] Failed to begin transaction:`. psqlodbc ignores the status, so adbcBridge was never affected. Sent as a fix with a wire-level test | **fixed on main** — our fix PR was merged by the maintainer on 2026-09-17, the day it was opened (merge `7ed83075`); found on `26.10.1-SNAPSHOT` while re-checking #7188; the new test fails before the fix, and the maintainer re-ran the PostgreSQL module's integration suite on it (244 tests, 0 failures) and extended the fix so a prefixed `{sql}BEGIN` gets its command tag too. That savepoint statements are accepted without being implemented is tracked separately as [ArcadeData/arcadedb#7846](https://github.com/ArcadeData/arcadedb/issues/7846). Expected in 26.10.1 |
| 2026-09-17 | DuckDB ODBC | [duckdb/duckdb-odbc#524](https://github.com/duckdb/duckdb-odbc/pull/524) | Parameter arrays on 1.5.5 and on main: with `SQL_ATTR_PARAMSET_SIZE` above 1, every fixed-length parameter receives set 0's value in every row under `SQL_SUCCESS` with the right processed count; only character and binary parameters step (the fixed-length branches read from the start of the bound buffer). Sent as a fix: each set reads its own element, with a test over six types and a NULL set | **merged 2026-09-17** (ours) — approved ("Thanks for the PR! Looks good to me.") and merged by a DuckDB maintainer the day it was opened (merge `1e065eaf`), green on Linux, macOS and Windows on both architectures; reproduced on the 1.5.5 release and on main, verified on a build of the fix, where the driver's whole test suite passes. Ships in the first duckdb-odbc release after v1.5.5.0; adbcBridge keeps binding row by row for DuckDB until then |
| 2026-09-17 | DuckDB ODBC | [duckdb/duckdb-odbc#523](https://github.com/duckdb/duckdb-odbc/pull/523) | `SQLGetInfo(SQL_DBMS_VER)` on 1.5.5: under unixODBC the process segfaults (the driver's internal `SQLAllocHandle` call binds to the driver manager, fails, and the error path frees an uninitialized handle); linked directly it returns `SQL_SUCCESS`, the right length and an empty string (read into one buffer, returned from another). Sent as a fix: the version comes straight from the engine, with a test against `pragma_version()` | **merged 2026-09-17** (ours) — approved ("Thanks for the PR! It looks good to me.") and merged by a DuckDB maintainer the day it was opened, green on Linux, macOS and Windows; reproduced on the 1.5.5 release and verified on a build of the fix, where the driver's whole test suite passes. Ships in the first duckdb-odbc release after v1.5.5.0 |
Expand Down Expand Up @@ -73,7 +75,6 @@ time allows, and a reproduction contributed by anyone is welcome.
| DuckDB ODBC 1.5.5 (Linux) | (`SQLGetInfo(SQL_DBMS_VER)` segfault and the parameter-array defect: both sent upstream as fixes and both merged on 2026-09-17, see duckdb/duckdb-odbc#523 and #524 above.) A fetch writes the full 2048-row vector into bound buffers whatever the rowset size. adbcBridge binds row by row and fetches 2048-row rowsets there. | `COMPATIBILITY.md`, `tests/compat/README.md` |
| RisingWave 3.0 | A server-side statement name is not released when the client closes the statement, so psqlodbc's `_PLAN0x<handle>` names collide on the second prepare of an allocate/prepare/execute/free loop (`XX000 Duplicated statement name`). adbcBridge sets `UseServerSidePrepare=0` there. | `COMPATIBILITY.md` |
| OceanBase CE 4.4.2 | A server-side prepared execute in which a parameter arrives as `MYSQL_TYPE_NULL` (what MySQL Connector/ODBC sends for a NULL before a value has fixed the type) is refused with `Object type error` (4001); MySQL accepts the same sequence. | `COMPATIBILITY.md` |
| ArcadeDB 26.9 (PostgreSQL wire) | A `DATETIME_MICROS` literal written with a space separator and a fraction (`'2024-02-29 13:45:10.123456'`, the form psqlodbc renders a bound timestamp in) is stored as NULL under `SQL_SUCCESS`; a NULL `BOOLEAN` arrives over the wire as `false` with a non-NULL indicator. | `tests/compat/README.md` |
| `alexbrainman/odbc` (Go, Windows) | Access violation inside `api.SQLGetDiagRec` on the first driver diagnostic, on every server but SQLite. | `bench/LANGUAGE_BENCHMARKS-windows.md` |
| psqlodbc 18.x | Sends `SHOW DateStyle` at connect, which YDB's PostgreSQL layer rejects; 16.x does not. (Arguably YDB's to implement.) | `COMPATIBILITY.md`, macOS and Windows columns |
| Firebird ODBC 3.0.1 / 3.5.0-rc1 | No macOS build; Firebird 5's sample security database ships with no SYSDBA and bootstrapping one needs an administrator. | `COMPATIBILITY.md` |
Expand Down
16 changes: 13 additions & 3 deletions tests/compat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3505,16 +3505,26 @@ that path, since every other driver answers the enumeration.
* **`BoolsAsChar=0`** in the connection string. Without it psqlodbc reports every
`BOOLEAN` as a `VARCHAR(5)` holding `"1"`/`"0"` instead of `SQL_BIT`. Same setting, same
reason, as the `questdb` entry.
* **`not_null=("bo",)`.** With `BoolsAsChar=0` a boolean property has no NULL state on
the wire: row 2's `bo` goes in as `NULL` and reads back `False`.
* **NULL booleans, fixed upstream.** On 26.8.1 a NULL `BOOLEAN` property came back over
the wire as `false` with a non-NULL indicator (the text serializer wrote `"0"` for a
NULL; [ArcadeData/arcadedb#6674](https://github.com/ArcadeData/arcadedb/issues/6674),
reported by an ArcadeDB contributor, fixed 2026-08-24, shipped in 26.9.1). The entry
carried `not_null=("bo",)` for it until 2026-09-21, when a retest on 26.9.1 showed row
2's `bo` reading back `NULL` on the text and binary paths and through psqlodbc; the
flag is gone and the all-NULL row check covers `bo` again.
* **`decimal_type="decimal128(28, 3)"`.** ArcadeDB reports no declared precision for a
`DECIMAL` property, so psqlodbc falls back to its own maximum (28) with the scale of the
values in the result set — as it does for RisingWave's unqualified `NUMERIC`.
* **Timestamp literals need the ISO-8601 `T`.** `'2024-02-29 13:45:10.123456'` into a
`DATETIME_MICROS` property is stored as `NULL`, silently;
`'2024-02-29T13:45:10.123456'` round-trips to the microsecond. (A bound
`SQL_TYPE_TIMESTAMP` parameter goes as the space form, so it hits the same silent NULL —
a reason to write timestamps as ISO text against this server.)
a reason to write timestamps as ISO text against this server.) Reproduced on 26.9.1
on 2026-09-21: the space alone parses and the fraction alone parses, the two together
fail to parse and a blanket handler in the type converter turns the value into NULL
under a successful `INSERT`. Tracked as
[ArcadeData/arcadedb#8090](https://github.com/ArcadeData/arcadedb/issues/8090), opened
by the maintainer with the root cause and a reproducer.
* **No binary transport.** A bound `bytea` parameter is refused by the protocol layer
outright (`Error on parsing bind message: Type with code 0 not supported for
deserializing`), and a `BINARY` property fed a string hands the string straight back.
Expand Down
8 changes: 5 additions & 3 deletions tests/compat/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -1358,9 +1358,11 @@ def tdengine_setup(n=20000, chunk=1000, base=1709210000000000):
# falls back to its own maximum (28) with the scale of the values in the result
# set -- as it does for RisingWave's unqualified NUMERIC.
decimal_type="decimal128(28, 3)",
# A BOOLEAN property has no NULL state on the wire: row 2's `bo` was inserted as
# NULL and reads back false, as QuestDB's and Access's booleans do.
not_null=("bo",),
# Until 26.9.1 a NULL BOOLEAN came back as false over the wire (the text
# serializer wrote "0" for a NULL; ArcadeData/arcadedb#6674, fixed 2026-08-24) and
# this entry carried not_null=("bo",) for it. Retested on 26.9.1 on 2026-09-21:
# row 2's `bo` reads back NULL on the text and binary paths and through psqlodbc,
# so the flag is gone and the all-NULL row check covers `bo` again.
# ArcadeDB is a graph database as much as a document one, which nothing in the
# standard workload touches, so the `extra` steps build a small graph through the
# ODBC path and traverse it: three vertices, two edges, then one- and two-hop
Expand Down
Loading