Skip to content

Add write support: INSERT INTO and CREATE TABLE AS for attached ADBC databases#9

Open
jatorre wants to merge 2 commits intoQuery-farm:mainfrom
jatorre:add-write-support
Open

Add write support: INSERT INTO and CREATE TABLE AS for attached ADBC databases#9
jatorre wants to merge 2 commits intoQuery-farm:mainfrom
jatorre:add-write-support

Conversation

@jatorre
Copy link

@jatorre jatorre commented Mar 14, 2026

Summary

Enables standard SQL INSERT and CREATE TABLE AS on attached ADBC databases:

ATTACH 'driver=./libadbc_driver_oracle.dylib&oracle.dsn=...' AS ora (TYPE adbc);

-- Read (already works)
SELECT * FROM ora.my_table;

-- Write (new!)
INSERT INTO ora.my_table SELECT * FROM local_data;
CREATE TABLE ora.new_table AS SELECT * FROM local_data;

Implementation

  • AdbcInsert PhysicalOperator (new): sink that converts DataChunks → Arrow → ADBC BindStream
  • AdbcCatalog::PlanInsert and PlanCreateTableAs: wire planning into the catalog
  • Follows the same pattern as postgres_scanner's PostgresInsert
  • Reuses the existing adbc_insert.cpp infrastructure (AdbcInsertStream, ArrowAppender)

Changes

  • src/include/storage/adbc_insert.hpp — new AdbcInsert operator header
  • src/storage/adbc_insert.cpp — new operator implementation + catalog planning
  • src/storage/adbc_catalog.cpp — remove NotImplementedException stubs
  • CMakeLists.txt — add new source file

Impact

This makes every ADBC driver writable from DuckDB — not just one database. Any driver that implements the ADBC bulk ingest interface (Bind/BindStream + ExecuteUpdate) will work:

  • Oracle (adbc-driver-oracle)
  • Databricks (adbc-drivers/databricks)
  • Redshift (adbc-drivers/redshift)
  • Snowflake (apache/arrow-adbc)
  • PostgreSQL (apache/arrow-adbc)

Motivation

Currently adbc_scanner only supports reads via adbc_scan(). The adbc_insert() table function exists for programmatic writes, but standard SQL INSERT doesn't work on attached databases because PlanInsert throws NotImplementedException.

This was the last missing piece for using ADBC as a universal read/write connector from DuckDB SQL.

Test plan

  • INSERT INTO attached ADBC table from local data
  • CREATE TABLE AS on attached ADBC database
  • Verify with Oracle ADBC driver (tested with SDO_GEOMETRY round-trip)
  • Verify with PostgreSQL ADBC driver

…databases

Implement PlanInsert and PlanCreateTableAs in AdbcCatalog, enabling:

  ATTACH 'driver=./my_driver.dylib&...' AS db (TYPE adbc);
  INSERT INTO db.my_table SELECT * FROM local_data;
  CREATE TABLE db.new_table AS SELECT * FROM local_data;

The implementation follows the same pattern as postgres_scanner:
- AdbcInsert PhysicalOperator acts as a Sink, receiving DataChunks
- DataChunks are converted to Arrow batches via ArrowAppender
- Batches are fed into an AdbcInsertStream (Arrow C Data Interface)
- The stream is bound to an ADBC statement with BindStream()
- ExecuteUpdate() sends all data to the remote database

This reuses the existing adbc_insert.cpp infrastructure (AdbcInsertStream,
AdbcStatementWrapper) but wires it into the DuckDB catalog planning
system so that standard SQL INSERT works on attached databases.

Supports ADBC ingest modes: create, append (via INSERT vs CREATE TABLE AS).
@CLAassistant
Copy link

CLAassistant commented Mar 14, 2026

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants