The Ingres ODBC client kills any Java process that loads it
While adding Actian Ingres 10.1 to a compatibility matrix that runs one workload through 53 databases' ODBC drivers, three defects in the Ingres client stack turned up that are worth writing down, because the error messages they produce do not lead anywhere on the web today.
1. A Java process dies within a second of loading the driver
Load libiiodbcdriver.1.so into a JVM, from any ODBC layer, and the process aborts before the
first ODBC call:
# A fatal error has been detected by the Java Runtime Environment:
# SIGSEGV (0xb) at pc=0x00007676c818e483 (sent by kill)
# C [libcompat.1.so+0x6e483] EXsignal+0x39
The frame is the Ingres client's own exception facility. When the driver's GCF layer
initialises it calls i_EXcatch → EXsignal → EXsetsig → sigaction, installing
process-wide handlers for SIGSEGV and friends. The JVM relies on SIGSEGV for its implicit
null checks: it deliberately touches a guard page and expects its own handler to turn that into a
NullPointerException. With Ingres' handler in the chain the first such fault, here 0.37 s into
Bench.makeRoot, is treated as a fatal error and the process is killed. The (sent by kill)
in the report is the tell: the signal did not come from the faulting instruction, it came from a
handler re-raising it.
A library loaded into a host process should not replace the host's signal handlers. The same driver from Python, Rust and Go runs the whole workload fine; none of those runtimes use SIGSEGV as a control-flow mechanism.
Workaround: none inside the JVM. Run Ingres access out of process, or through a client that does not load the Ingres libraries.
2. Under unixODBC the driver reads only the first character of your connection string
[08004] [Ingres][Ingres ODBC Driver][Ingres]E_GC0138_GCN_NO_SERVER (786744)
with a vnode and database that look empty. The driver exports SQLConnectW, and unixODBC
selects a driver's Unicode entry points purely on that symbol's presence. But the driver's
SQLWCHAR is the platform wchar_t, four bytes, while unixODBC hands over two-byte UTF-16. The
driver reads the string as UTF-32, so Driver=Ingres;... arrives as the single character D
followed by what UTF-32 makes of the rest. Passing the same string as UTF-32 connects, which is the
proof.
The narrow entry points are complete and correct. The matrix loads the driver behind a
72-function ANSI-only forwarding library, so unixODBC does the UCS-2 conversion itself and
the driver only ever sees the narrow calls. That library is 60 lines of generated C; the
pattern applies to any driver built with SQL_WCHART_CONVERT.
3. A real Driver= path aborts the process
*** buffer overflow detected ***: terminated
ConDriverInfo copies the Driver= value into a 32-byte stack buffer with strcpy. Any
absolute path to the library is longer than that, and glibc's fortified strcpy aborts.
Register the driver in odbcinst.ini under a short name and use Driver=Ingres; a DSN-less
connection string with the full path cannot work.
What the driver gets right
Everything else on the workload, once the string reaches it: the array-bound INSERT (Ingres
has no multi-row VALUES), Unicode round trips through the narrow path, DATE semantics
with date_alias = ansidate, catalog metadata. It needs a 32-bit SQLLEN (the client was built
that way, like IBM's Db2 driver) and it rejects UTF-16 surrogate pairs in wide parameters
(5000B, Unicode code point 0000D83D cannot be mapped to local character set), so text goes
through the UTF-8 narrow path. The C# route has its own problem: SQLTables segfaults inside
the driver when called from a .NET process, with or without autocommit, at any workload size.
Where this comes from
The numbers and reproductions are in the adbcBridge compatibility matrix, which runs the same workload through every database's ODBC driver on Linux, macOS and Windows and records every failure with its first error: https://adbcbridge.org/matrix/#ingres. The upstream record, including these three findings and their reproductions, is docs/UPSTREAM.md in the repository. Ingres 10.1 is the last open-source Ingres release; Actian's current client is 1.5 and the findings above are against the 10.1 driver that ships with that server.