A clean-room ODBC driver for a proprietary database, written in C.
SeerODBC lets ODBC consumers (BI tools, Microsoft-stack applications, anything that speaks ODBC) talk to the database by speaking its native wire protocol (TNS/TTC) directly. No vendor client libraries are required.
Independent project — not affiliated with Oracle. SeerODBC is a clean-room, independent effort and is not affiliated with, endorsed by, or sponsored by Oracle Corporation. Oracle®, Oracle Database, and related names are trademarks of Oracle and/or its affiliates. SeerODBC reimplements the wire protocol for interoperability only.
Status: working driver. Connects, queries, and does DML in transactions against live servers through unixODBC. See
docs/ODBC_CONFORMANCE.mdfor the function set anddocs/ARCHITECTURE.mdfor the design and progress log.
Validated live across six server releases — 9i, 10g, 11g, 18c, 21c and 23ai
(TTC field versions 2 through 24) — via tests/odbc/run-matrix.sh. The 10g–23ai
tier runs the full ODBC surface through unixODBC; 9i (the legacy fv2 / TTI_ALL7
dialect) is validated through the core API. 11g/21c/23ai are the public-CI tier;
9i, 10g and 18c stay local (their images aren't redistributable). 12.1 / 12.2 /
19c have no live server here but share the down-negotiated 12c wire forms (the
12.1 level is exercised by capping a 21c session at fv7). 8i (8.1.7) is
read-only: it logs in and runs queries (validated live through the core API
and an ODBC Driver Manager connection); DML, DDL, PL/SQL, COMMIT / ROLLBACK and
LOB columns are refused with "not implemented".
- Connect & auth — O5LOGON across the 10g (DES), 11g (AES-192/SHA-1) and
12c (AES-256/PBKDF2) verifiers, 23ai fv24 fast-auth, and 9i O3LOGON (legacy
DES); full Unicode (
*W) entry points. - SQL — queries, DML, transactions (commit/rollback/autocommit), the full
scalar type set incl. NUMBER/DATE/TIMESTAMP/BINARY_FLOAT|DOUBLE/RAW, LOBs
(CLOB/BLOB/BFILE) and LONG/LONG RAW, and the complete
SQL_C_*conversion matrix incl.SQL_C_WCHAR. - PL/SQL — anonymous blocks, stored procedures/functions via
{call}/{?=call}, IN/OUT parameters, REF CURSOR result sets, and PL/SQL associative arrays (IN and OUT). - Binding & fetch —
?and named (:name) markers, array (bulk) binding with batch-error row status, data-at-execution (SQLPutData), block fetch, scrollable + updatable cursors (positioned UPDATE/DELETE, optionalFOR UPDATErow locking), and large (multi-KB) LOB binds. - Catalog — Tables, Columns, PrimaryKeys, ForeignKeys, Statistics, GetTypeInfo, Procedures, ProcedureColumns, SpecialColumns.
- Advanced types — SQL objects / ADTs (nested, collections-of-objects, objects-with-collection attributes), VARRAY / nested tables, REF, XMLType (fetch + bind, incl. LOB-backed), and 23ai JSON + VECTOR binds (every element type, incl. sparse f32/f64/i8 and binary).
- Performance — statement caching: a closed statement's parsed server cursor is kept open and re-executed without a re-parse when the same SQL is prepared again (transparent; the describe travels with the cursor).
- Beyond ODBC (via the core
seer_*API) — Advanced Queuing (RAW / object / JSON payloads, array + multi-consumer), XA / two-phase commit, proxy authentication + DRCP, and TLS / TCPS transport.
- Connect to the database and support its features — not implement every protocol. The aim is that an ODBC application can reach every database in the supported range and use what that database offers. The wire protocols are the means, not the product: a dialect is implemented as far as the features need it and no further, and an alternative wire form that does a job already done (for example, OCI's native forms where the thin form works) is out of scope. An old release is supported as far as its realistic use needs — 8i logs in and runs queries, and stops there. When a choice has to be made, a fix a user would see wins over protocol fidelity.
- Support the release range 9i through 23ai (field versions 2–24), negotiating the wire form down to each server; 11g remains the reference target.
- Implement the ODBC 3.x functions that cover real consumer usage, driven by the public Microsoft ODBC Programmer's Reference.
- Stay clean-room: no vendor source, no decompiled binaries, no code
copied from any other driver. Public references and our own packet
captures only. See
CONTRIBUTING.md.
Two layers, strictly separated (the protocol core does not know ODBC exists):
+-----------------------------+ src/odbc/ ODBC shim (the SQL* entry points)
| ODBC shim |
+-----------------------------+
| TNS/TTC protocol core | src/tns/ speaks the TNS/TTC protocol
+-----------------------------+
The core is also exercised directly — without a Driver Manager — by the
seersql CLI (tools/seersql/), a tsql-style client for proving the
protocol against a real server.
Requirements: a C17 compiler, Meson + Ninja, OpenSSL >= 3.0, and (for the driver shim) the ODBC headers from unixODBC or iODBC.
meson setup build
meson compile -C build
meson test -C buildUseful options: -Dwith_tls=false, -Dbuild_tools=false, -Dbuild_tests=false,
and -Ddriver_libdir=<path> to override where the driver shim installs (default
<libdir>/odbc, e.g. /usr/lib64/odbc).
If the ODBC headers (sql.h) are not installed, the build skips the driver
shim and still builds the protocol core and seersql.
The primary target. Install the ODBC headers via unixODBC-devel (or iODBC)
and OpenSSL 3 via your distribution, then build as above.
Builds on macOS (Apple Silicon and Intel) with Homebrew. OpenSSL 3 is keg-only and the ODBC Driver Manager lives under the brew prefix, so point the toolchain at both:
brew install meson ninja pkg-config openssl@3 unixodbc
export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig"
export CPPFLAGS="-I$(brew --prefix unixodbc)/include"
export LDFLAGS="-L$(brew --prefix unixodbc)/lib"
meson setup build
meson compile -C buildiODBC (brew install libiodbc) works too — the driver is Driver-Manager
neutral and links against neither. The shim builds as libseerodbc.dylib, with
symbol export handled by the linker's -exported_symbols_list (the macOS
equivalent of the Linux version script).
To install a release instead, use the Homebrew formula in
packaging/homebrew/seerodbc.rb from a tap of
your own (its header shows how); it installs lib/odbc/libseerodbc.dylib and a
ready odbcinst.ini.sample that brew info seerodbc points at. CI builds,
installs and tests the formula on every PR.
Apache-2.0, chosen over MIT/BSD for its explicit patent grant. The repository is REUSE 3.3 compliant — every file carries SPDX copyright + license tags (trivial config under CC0-1.0).