Five defects from the sweep, sent upstream as fixes instead of reports
Until now every finding went upstream as a report with a reproduction. On 2026-09-17 five of them went as pull requests instead: the cause was already known, the fix was small, and a fix with a test is less work for a maintainer than a report. Each section below has the failure as a caller sees it, the cause in the project's own source, and what the pull request changes.
| Project | What a caller saw | Pull request |
|---|---|---|
| DuckDB ODBC | SQLGetInfo(SQL_DBMS_VER) segfaults under unixODBC; returns an empty string when linked directly |
duckdb/duckdb-odbc#523 |
| DuckDB ODBC | a parameter array stores set 0's value in every row, under SQL_SUCCESS |
duckdb/duckdb-odbc#524 |
| ArcadeDB | [libpq] Failed to begin transaction: from the Arrow PostgreSQL ADBC driver |
ArcadeData/arcadedb#7815 |
| SingleStore Connector/ODBC | SQLColumns with a NULL catalog segfaults |
memsql/singlestore-odbc-connector#47 |
| SingleStore Connector/ODBC | 42S22 Unknown column 'json' from SQLGetTypeInfo under ANSI_QUOTES |
memsql/singlestore-odbc-connector#48 |
DuckDB ODBC: SQLGetInfo(SQL_DBMS_VER)
Twelve lines of plain ODBC against the 1.5.5 release:
SQLDriverConnect -> 0
SQL_DBMS_NAME -> 0 "DuckDB"
Segmentation fault
#0 duckdb::FreeHandle(short, void*) libduckdb_odbc.so
#1 GetInfoInternal<unsigned char>(void*, unsigned short, void*, short, short*)
#2 ?? () libodbc.so.2
The driver answers this one info type by running SELECT library_version FROM
pragma_version() through the public SQLAllocHandle / SQLExecDirect / SQLFetch /
SQLGetData entry points. Two defects share those thirty lines. Under unixODBC the call to
SQLAllocHandle inside the driver binds to the driver manager's function of the same name
(LD_DEBUG=bindings shows it), which rejects the driver's handle; the statement handle is
still uninitialized and the error path frees it. Linked directly, as the driver's own tests
are, the call succeeds but the value is read into the caller's buffer and then overwritten
from a second, zero-filled one: SQL_SUCCESS, length 6, six NUL bytes. That second form is
the Windows entry in the matrix that recorded DuckDB (via ODBC) with nothing after it.
The fix returns DuckDB::LibraryVersion() directly, the same value pragma_version()
reports, and the new test compares the two.
DuckDB ODBC: parameter arrays
Four sets of (SQL_C_SLONG, SQL_C_DOUBLE, SQL_C_CHAR), (10, 1.5, "a") to
(40, 4.5, "dddd"), on the release and on main:
execute -> 0, processed = 4
row: i=10 d=1.5 s=a
row: i=10 d=1.5 s=bb
row: i=10 d=1.5 s=ccc
row: i=10 d=1.5 s=dddd
In ParameterDescriptor::SetValue the string and binary branches index the bound buffer by
the current set; the fixed-length branches all load from the start of it, and a TODO above
them says so. The driver's one parameter-array test binds SQL_C_CHAR only, which is why it
never failed. The fix steps each fixed-length load to the current set's element; the new
test covers INTEGER, BIGINT, DOUBLE, DATE, TIMESTAMP and VARCHAR with a NULL set
in the middle.
ArcadeDB: BEGIN answered with a RowDescription
→ Q "BEGIN"
← T RowDescription, 0 fields
← C "BEGIN"
← Z ReadyForQuery 'T'
PostgreSQL answers a statement that returns no rows with the bare CommandComplete. The
zero-field RowDescription in front of it makes libpq report PGRES_TUPLES_OK instead of
PGRES_COMMAND_OK. psql shows an empty table after BEGIN; the Arrow PostgreSQL ADBC
driver checks the status when it opens a transaction and gives up, and since its Python
DB-API starts with autocommit off, adbc_driver_postgresql.dbapi.connect(uri) cannot run one
query until autocommit=True is passed. psqlodbc ignores the status, so the ODBC route
never noticed. In PostgresNetworkExecutor.queryCommand the transaction-control and
savepoint branches now skip the RowDescription; the new test speaks the wire directly and
fails on main at BEGIN and at SAVEPOINT.
SingleStore Connector/ODBC: two catalog functions
SQLColumns with a NULL catalog, on a connection opened without DATABASE=:
#1 __GI___strdup (s=0x0)
#2 MADB_StmtColumnsNoInfoSchema (... CatalogName=0x0, NameLength1=0 ...) at ma_statement.c:5063
TABLE_CAT falls back to the client library's current-database field, which only the
connect-time database sets; USE does not. The same line exists in SQLPrimaryKeys. Both
now leave TABLE_CAT NULL.
SQLGetTypeInfo with ANSI_QUOTES in sql_mode:
[42S22] [ss-1.2.2][9.1.1] Unknown column 'json' in 'field list' (1054) (SQLGetTypeInfo)
The result set is built from a SQL template with double-quoted values, which that mode turns into identifiers. The template now uses single-quoted literals, and because the literal prefix of the character types is itself a single quote, the values go through a helper that doubles it.
How each one was checked
| Fix | Reproduced on | New test on unpatched code | With the fix |
|---|---|---|---|
DuckDB SQL_DBMS_VER |
1.5.5 release zip, checksum matched | fails, "" == "v2.1.0-alpha…" |
whole suite passes, 93 test cases; no crash through unixODBC |
| DuckDB parameter arrays | 1.5.5 release and main |
fails at row two | whole suite passes, 93 test cases; rows read 10, 20, 30, 40 |
| ArcadeDB transaction control | 26.10.1-SNAPSHOT container, wire capture |
fails at BEGIN and at SAVEPOINT |
every integration test of the PostgreSQL module passes, 243 |
SingleStore SQLColumns |
SingleStore 9.1.1, build of master |
segfault | catalog tests pass in both prepared-statement modes |
SingleStore SQLGetTypeInfo |
SingleStore 9.1.1, build of master |
42S22 |
info tests pass in both modes; 56 rows with and without ANSI_QUOTES |
The reproductions are plain ODBC or plain wire protocol in every case, the failing outputs above are copied from those runs, and the status of each pull request is tracked in the upstream record.