ADBC-compatible driver for Exasol with Apache Arrow data format support.
Community-maintained. Not officially supported by Exasol. This is a side-project of mine!
exarrow-rs is a Rust library that provides ADBC (Arrow Database Connectivity) compatible access to Exasol databases. It enables efficient data transfer using the Apache Arrow columnar format, making it ideal for analytical workloads and data science applications.
exarrow-rs uses WebSocket-based transport using Exasol's native WebSocket API.
- ADBC-Compatible Interface: Standard database connectivity API
- Apache Arrow Format: Efficient columnar data representation
- Async/Await: Built on Tokio for concurrent operations
- Secure: TLS/SSL support, secure credential handling
- Parameter Binding: Type-safe parameterized queries
- Metadata Queries: Introspect catalogs, schemas, tables, and columns
Add this to your Cargo.toml:
[dependencies]
exarrow-rs = "2.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }use exarrow_rs::adbc::Driver;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create driver and connect
let driver = Driver::new();
let database = driver.open("exasol://sys:exasol@localhost:8563/my_schema")?;
let mut connection = database.connect().await?;
// Execute a query (convenience method)
let results = connection.query("SELECT * FROM customers WHERE age > 25").await?;
// Process results as Arrow RecordBatches
for batch in results {
println!("Retrieved {} rows", batch.num_rows());
println!("Schema: {:?}", batch.schema());
}
// Execute with parameters using Statement
let mut stmt = connection.create_statement("SELECT * FROM orders WHERE customer_id = ?");
stmt.bind(0, 12345)?;
let results = connection.execute_statement(&stmt).await?;
// Or use prepared statements for repeated execution
let mut prepared = connection.prepare("SELECT * FROM orders WHERE status = ?").await?;
prepared.bind(0, "pending")?;
let results = connection.execute_prepared(&prepared).await?;
connection.close_prepared(prepared).await?;
// Transaction support
connection.begin_transaction().await?;
connection.execute_update("INSERT INTO logs VALUES (1, 'test')").await?;
connection.commit().await?;
connection.close().await?;
Ok(())
}Load the driver dynamically via the ADBC driver manager:
use adbc_core::options::{AdbcVersion, OptionDatabase, OptionValue};
use adbc_core::{Connection, Database, Driver, Statement};
use adbc_driver_manager::ManagedDriver;
// Build the FFI library first: cargo build --release --features ffi
let mut driver = ManagedDriver::load_dynamic_from_filename(
"target/release/libexarrow_rs.dylib", // .so on Linux
Some(b"ExarrowDriverInit"),
AdbcVersion::V110,
)?;
let opts = vec![(OptionDatabase::Uri, OptionValue::String(
"exasol://sys:exasol@localhost:8563".to_string()
))];
let db = driver.new_database_with_opts(opts)?;
let mut conn = db.new_connection()?;
let mut stmt = conn.new_statement()?;
stmt.set_sql_query("SELECT 1")?;
let reader = stmt.execute()?;exasol://[user[:password]@]host[:port][/schema][?param=value&...]
Parameters:
connection_timeout- Connection timeout in seconds (default: 30)query_timeout- Query timeout in seconds (default: 300)tls- Enable TLS/SSL (default: true)
Example:
exasol://myuser:mypass@exasol.example.com:8563/production?connection_timeout=60&query_timeout=600
| Exasol Type | Arrow Type | Notes |
|---|---|---|
BOOLEAN |
Boolean |
|
CHAR, VARCHAR |
Utf8 |
|
DECIMAL(p, s) |
Decimal128(p, s) |
Precision 1-36 |
DOUBLE |
Float64 |
|
DATE |
Date32 |
|
TIMESTAMP |
Timestamp(Microsecond) |
Exasol: 0-9 fractional digits |
INTERVAL YEAR TO MONTH |
Interval(MonthDayNano) |
|
INTERVAL DAY TO SECOND |
Interval(MonthDayNano) |
0-9 fractional seconds |
GEOMETRY |
Binary |
WKB format |
See the examples/ directory:
basic_usage.rs- Direct API usagedriver_manager_usage.rs- ADBC driver manager integration
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Apache Arrow
- Powered by Tokio
- Connects to Exasol