Read Oracle tables in parallel, load query results into Oracle through the OCI Direct Path API and run statements in Oracle
Compatibility Matrix
This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 |
|---|---|---|---|---|---|
| Linux AMD64 | |||||
| Linux ARM64 | |||||
| macOS AMD64 | |||||
| macOS ARM64 | |||||
| Windows AMD64 | |||||
| Windows ARM64 | |||||
| WebAssembly |
Installing and Loading
INSTALL oraduck FROM community;
LOAD oraduck;
Example
CREATE SECRET oracle_test (TYPE oraduck, USER 'scott', PASSWORD 'tiger', DSN 'dbhost:1521/ORCLPDB1');
-- Read: attach the Oracle database (read-only); filters and columns are pushed to Oracle
ATTACH '' AS ora (TYPE oraduck, SECRET oracle_test);
SELECT * FROM ora.MY_SCHEMA.MY_TABLE WHERE part_date = DATE '2024-05-07';
-- Or read one table with the table function
SELECT count(*) FROM oraduck_scan('MY_SCHEMA.MY_TABLE', connection := 'oracle_test');
-- Write: the target table must exist in Oracle; columns are matched by name
COPY (SELECT id, amount, operation_date, label FROM source)
TO 'MY_SCHEMA.MY_TABLE' (FORMAT oraduck, CONNECTION 'oracle_test');
-- Run one SQL statement or PL/SQL block in Oracle (committed; rolled back on error)
CALL oraduck_execute('TRUNCATE TABLE MY_SCHEMA.MY_TABLE', connection := 'oracle_test');
About oraduck
OraDuck reads Oracle tables into DuckDB and loads DuckDB query results into Oracle, both through OCI with one Oracle session per DuckDB thread and no intermediate file. It also runs SQL statements and PL/SQL blocks in Oracle.
Reading:
-
ATTACH '' AS ora (TYPE oraduck, SECRET '<secret>')exposes an Oracle database as a read-only catalog (schemas are Oracle users; tables, views and synonyms);oraduck_scan('SCHEMA.TABLE', …)reads one table or view - projection and filter pushdown: only the selected columns are fetched, and
WHEREconditions that Oracle evaluates exactly like DuckDB run in Oracle, which prunes partitions - parallel sessions over ROWID ranges (from DBA_EXTENTS or DBMS_PARALLEL_EXECUTE) or ORA_HASH(ROWID),
with a common
AS OF SCNsnapshot when the user may read the current SCN - exact types: NUMBER(p,s) as integers or DECIMAL, DATE/TIMESTAMP, CLOB/BLOB read inline with bounded memory, UTF-8 validated strings
Writing:
-
COPY ... TO 'SCHEMA.TABLE' (FORMAT oraduck, CONNECTION '<secret>')through the OCI Direct Path API, the engine behindsqlldr direct=true; all sessions commit together, any error aborts the load - on Oracle 19c, 1.2 to 3.2 times faster than a CSV export loaded by parallel direct path SQL*Loader
- indexed tables need
SKIP_INDEX_MAINTENANCE true, which leaves their indexes UNUSABLE until rebuilt
Running statements:
-
CALL oraduck_execute('<statement>', connection := '<secret>')runs one SQL statement or PL/SQL block in its own Oracle session and commits it;rows_affectedgives the row count of an INSERT, UPDATE, DELETE or MERGE - an error rolls the statement back; Ctrl-C and
max_execution_timestop it in Oracle and roll it back - upsert:
COPYinto a staging table, thenMERGEit into the target withoraduck_execute
Options, type mapping, recommended Oracle privileges, benchmarks and limitations: https://github.com/hugues31/oraduck
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| oraduck_execute | table | NULL | NULL | |
| oraduck_oci_version | scalar | NULL | NULL | |
| oraduck_scan | table | NULL | NULL |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
| name | description | input_type | scope | aliases | typed_value |
|---|---|---|---|---|---|
| temp_directory | Set the directory to which temporary files are written. | VARCHAR | GLOBAL | [] | post.db.tmp |