What dbSaci is
dbSaci is a proxy that speaks Oracle’s TNS/TTC wire protocol on the front and connects to PostgreSQL or MariaDB on the back. An unmodified Oracle client points at dbSaci instead of at an Oracle database, and dbSaci:
- terminates the Oracle client handshake and authentication,
- translates the Oracle SQL dialect it understands into backend SQL,
- runs the query against PostgreSQL +
orafceor MariaDB 11.4 inSQL_MODE=ORACLE, - re-encodes the backend result back into Oracle’s binary framing.
The application keeps its Oracle driver, its connection string shape, and most of its SQL. Nothing about the database it actually talks to is Oracle.
What dbSaci is not
Section titled “What dbSaci is not”It is not an Oracle database implementation. It supports the slice of Oracle
that its SQL translation layer plus orafce can express — see
What works and Limitations.
How this differs from IvorySQL
Section titled “How this differs from IvorySQL”IvorySQL is a fork of the PostgreSQL
server that builds Oracle SQL / PL-SQL compatibility — an Oracle parse mode,
PL/iSQL, packages, NUMBER/DATE semantics, DUAL — into the database
engine. It is far deeper than dbSaci on the dialect. But IvorySQL speaks the
PostgreSQL wire protocol: your application connects to it with a PostgreSQL
driver. An unmodified Oracle client (ojdbc, ODP.NET, python-oracledb, an
OCI-linked tool) cannot connect to IvorySQL at all.
dbSaci is the inverse trade. It speaks Oracle’s TNS/TTC wire protocol, so the
Oracle client connects exactly as it would to Oracle — no driver swap, no
connection-string rewrite — while the database behind it is an ordinary,
unmodified PostgreSQL. The cost is coverage: dbSaci only supports the slice of
Oracle SQL / PL-SQL its translation layer plus orafce can express.
Use IvorySQL if you can repoint the application at a new database and want broad Oracle SQL semantics. Use dbSaci if the application and its Oracle driver have to stay exactly as they are.
Requirements
Section titled “Requirements”- PostgreSQL (a recent release) with the
orafceextension available (CREATE EXTENSION orafce), or MariaDB 11.4+ (dbSaci enablesSQL_MODE=ORACLEper session). - A login role on the selected backend for the proxy to connect as. One Oracle session maps to one dedicated backend connection, so size the backend connection capacity accordingly.
- Transport defaults to plaintext. Enable TCPS with
--tls-cert/--tls-keyand backend TLS with--db-ssl. A TLS-terminating boundary in front of a plaintext listener is still valid. - To build from source: Rust (stable, 2024 edition).
Which clients
Section titled “Which clients”Verified end to end (connect, auth, metadata, parametrised SELECT/DML, array
binds, rollback, multi-thousand-row fetch loop) against both the 19c and 11g
personas, on PostgreSQL and MariaDB (CI matrix: client × backend × persona):
| Client | Mode | Status |
|---|---|---|
python-oracledb |
thin | Supported |
| Oracle JDBC thin driver (ojdbc8 / ojdbc11) | thin | Supported |
ODP.NET (Oracle.ManagedDataAccess.Core) |
managed | Supported |
oracle-rs |
thin | Supported |
Instant Client / OCI thick (via python-oracledb thick mode) |
thick | Supported — not in CI (needs a licensed Instant Client) |
Each wire-level behaviour is chosen from the capabilities the client negotiates in the TTC handshake. See How it works.