-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial experimental(!) implementation of loadable extensions with C extension API See duckdb/duckdb#12682 for more info on the DuckDB C extension API --------- Co-authored-by: martin <[email protected]>
- Loading branch information
1 parent
f887844
commit 71b01f7
Showing
25 changed files
with
19,839 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,12 +33,13 @@ jobs: | |
rust-version: stable${{ matrix.host }} | ||
targets: ${{ matrix.target }} | ||
components: 'rustfmt, clippy' | ||
|
||
# download libduckdb | ||
- uses: robinraju/[email protected] | ||
name: Download duckdb | ||
with: | ||
repository: "duckdb/duckdb" | ||
tag: "v1.0.0" | ||
tag: "v1.1.1" | ||
fileName: ${{ matrix.duckdb }} | ||
out-file-path: . | ||
|
||
|
@@ -49,15 +50,25 @@ jobs: | |
with: | ||
file_path: ${{ github.workspace }}/${{ matrix.duckdb }} | ||
extract_dir: libduckdb | ||
|
||
- run: cargo fmt --all -- --check | ||
if: matrix.os == 'ubuntu-latest' | ||
- run: cargo clippy --all-targets --workspace --all-features -- -D warnings -A clippy::redundant-closure | ||
|
||
# TODO: remove | ||
- name: Workaround for https://github.com/pola-rs/polars/issues/19063 | ||
run: | | ||
cargo update [email protected] --precise 2.5.0 | ||
- name: run cargo clippy | ||
if: matrix.os == 'ubuntu-latest' | ||
name: run cargo clippy | ||
env: | ||
DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb | ||
DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb | ||
LD_LIBRARY_PATH: ${{ github.workspace }}/libduckdb | ||
run: | | ||
cargo clippy --all-targets --workspace --all-features -- -D warnings -A clippy::redundant-closure | ||
- name: Run cargo-tarpaulin | ||
if: matrix.os == 'ubuntu-latest' | ||
uses: actions-rs/[email protected] | ||
|
@@ -70,6 +81,7 @@ jobs: | |
DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb | ||
DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb | ||
LD_LIBRARY_PATH: ${{ github.workspace }}/libduckdb | ||
|
||
- name: Upload to codecov.io | ||
if: matrix.os == 'ubuntu-latest' | ||
uses: codecov/codecov-action@v1 | ||
|
@@ -88,19 +100,28 @@ jobs: | |
with: | ||
name: PATH | ||
value: $env:PATH;${{ github.workspace }}/libduckdb | ||
|
||
- name: Run cargo-test | ||
if: matrix.os == 'windows-latest' | ||
run: cargo test --features "modern-full vtab-full vtab-loadable" | ||
env: | ||
DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb | ||
DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb | ||
|
||
- name: Build loadable extension | ||
run: cargo build --example hello-ext --features="vtab-loadable" | ||
env: | ||
DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb | ||
DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb | ||
LD_LIBRARY_PATH: ${{ github.workspace }}/libduckdb | ||
|
||
- name: Build loadable extension | ||
run: cargo build --example hello-ext-capi --features="vtab-loadable loadable-extension" | ||
env: | ||
DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb | ||
DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb | ||
LD_LIBRARY_PATH: ${{ github.workspace }}/libduckdb | ||
|
||
Windows: | ||
name: Windows build from source | ||
needs: test | ||
|
@@ -117,6 +138,7 @@ jobs: | |
with: | ||
rust-version: stable | ||
targets: x86_64-pc-windows-msvc | ||
|
||
- run: cargo install cargo-examples | ||
|
||
Sanitizer: | ||
|
@@ -140,7 +162,9 @@ jobs: | |
# leak sanitization, but we don't care about backtraces here, so long | ||
# as the other tests have them. | ||
RUST_BACKTRACE: "0" | ||
run: cargo -Z build-std test --features "modern-full extensions-full" --target x86_64-unknown-linux-gnu | ||
run: | | ||
# TODO switch back to modern-full once polars is fixed | ||
cargo -Z build-std test --features "chrono serde_json url r2d2 uuid extensions-full" --target x86_64-unknown-linux-gnu --package duckdb | ||
- name: publish crates --dry-run | ||
uses: katyo/publish-crates@v2 | ||
with: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
[submodule "crates/libduckdb-sys/duckdb-sources"] | ||
path = crates/libduckdb-sys/duckdb-sources | ||
url = https://github.com/duckdb/duckdb | ||
update = none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ members = [ | |
] | ||
|
||
[workspace.package] | ||
version = "1.0.0" | ||
version = "1.1.1" | ||
authors = ["wangfenjin <[email protected]>"] | ||
edition = "2021" | ||
repository = "https://github.com/duckdb/duckdb-rs" | ||
|
@@ -19,8 +19,8 @@ license = "MIT" | |
categories = ["database"] | ||
|
||
[workspace.dependencies] | ||
duckdb = { version = "1.0.0", path = "crates/duckdb" } | ||
libduckdb-sys = { version = "1.0.0", path = "crates/libduckdb-sys" } | ||
duckdb = { version = "1.1.1", path = "crates/duckdb" } | ||
libduckdb-sys = { version = "1.1.1", path = "crates/libduckdb-sys" } | ||
duckdb-loadable-macros = { version = "0.1.2", path = "crates/duckdb-loadable-macros" } | ||
autocfg = "1.0" | ||
bindgen = { version = "0.69", default-features = false } | ||
|
@@ -43,6 +43,7 @@ pkg-config = "0.3.24" | |
polars = "0.35.4" | ||
polars-core = "0.35.4" | ||
pretty_assertions = "1.4.0" | ||
prettyplease = "0.2.20" | ||
proc-macro2 = "1.0.56" | ||
quote = "1.0.21" | ||
r2d2 = "0.8.9" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
extern crate duckdb; | ||
extern crate duckdb_loadable_macros; | ||
extern crate libduckdb_sys; | ||
|
||
use duckdb::{ | ||
core::{DataChunkHandle, Inserter, LogicalTypeHandle, LogicalTypeId}, | ||
vtab::{BindInfo, Free, FunctionInfo, InitInfo, VTab}, | ||
Connection, Result, | ||
}; | ||
use duckdb_loadable_macros::duckdb_entrypoint_c_api; | ||
use libduckdb_sys as ffi; | ||
use std::{ | ||
error::Error, | ||
ffi::{c_char, CString}, | ||
}; | ||
|
||
#[repr(C)] | ||
struct HelloBindData { | ||
name: *mut c_char, | ||
} | ||
|
||
impl Free for HelloBindData { | ||
fn free(&mut self) { | ||
unsafe { | ||
if self.name.is_null() { | ||
return; | ||
} | ||
drop(CString::from_raw(self.name)); | ||
} | ||
} | ||
} | ||
|
||
#[repr(C)] | ||
struct HelloInitData { | ||
done: bool, | ||
} | ||
|
||
struct HelloVTab; | ||
|
||
impl Free for HelloInitData {} | ||
|
||
impl VTab for HelloVTab { | ||
type InitData = HelloInitData; | ||
type BindData = HelloBindData; | ||
|
||
unsafe fn bind(bind: &BindInfo, data: *mut HelloBindData) -> Result<(), Box<dyn std::error::Error>> { | ||
bind.add_result_column("column0", LogicalTypeHandle::from(LogicalTypeId::Varchar)); | ||
let param = bind.get_parameter(0).to_string(); | ||
unsafe { | ||
(*data).name = CString::new(param).unwrap().into_raw(); | ||
} | ||
Ok(()) | ||
} | ||
|
||
unsafe fn init(_: &InitInfo, data: *mut HelloInitData) -> Result<(), Box<dyn std::error::Error>> { | ||
unsafe { | ||
(*data).done = false; | ||
} | ||
Ok(()) | ||
} | ||
|
||
unsafe fn func(func: &FunctionInfo, output: &mut DataChunkHandle) -> Result<(), Box<dyn std::error::Error>> { | ||
let init_info = func.get_init_data::<HelloInitData>(); | ||
let bind_info = func.get_bind_data::<HelloBindData>(); | ||
|
||
unsafe { | ||
if (*init_info).done { | ||
output.set_len(0); | ||
} else { | ||
(*init_info).done = true; | ||
let vector = output.flat_vector(0); | ||
let name = CString::from_raw((*bind_info).name); | ||
let result = CString::new(format!("Hello {}", name.to_str()?))?; | ||
// Can't consume the CString | ||
(*bind_info).name = CString::into_raw(name); | ||
vector.insert(0, result); | ||
output.set_len(1); | ||
} | ||
} | ||
Ok(()) | ||
} | ||
|
||
fn parameters() -> Option<Vec<LogicalTypeHandle>> { | ||
Some(vec![LogicalTypeHandle::from(LogicalTypeId::Varchar)]) | ||
} | ||
} | ||
|
||
#[duckdb_entrypoint_c_api(ext_name = "rusty_quack", min_duckdb_version = "v0.0.1")] | ||
pub fn extension_entrypoint(con: Connection) -> Result<(), Box<dyn Error>> { | ||
con.register_table_function::<HelloVTab>("hello") | ||
.expect("Failed to register hello table function"); | ||
Ok(()) | ||
} |
Oops, something went wrong.