Skip to content

Commit

Permalink
Merge branch 'main' into enable-union-test
Browse files Browse the repository at this point in the history
  • Loading branch information
Mause authored Dec 13, 2024
2 parents 6693513 + 2bd811e commit caa2842
Show file tree
Hide file tree
Showing 43 changed files with 20,424 additions and 365 deletions.
32 changes: 28 additions & 4 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: .

Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -117,6 +138,7 @@ jobs:
with:
rust-version: stable
targets: x86_64-pc-windows-msvc

- run: cargo install cargo-examples

Sanitizer:
Expand All @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ Cargo.lock

*.db

crates/libduckdb-sys/duckdb-sources/
crates/libduckdb-sys/duckdb-sources/*
crates/libduckdb-sys/duckdb/
crates/libduckdb-sys/._duckdb
1 change: 0 additions & 1 deletion .gitmodules
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
14 changes: 8 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -19,9 +19,9 @@ 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-loadable-macros = { version = "0.1.2", path = "crates/duckdb-loadable-macros" }
duckdb = { version = "1.1.1", path = "crates/duckdb" }
libduckdb-sys = { version = "1.1.1", path = "crates/libduckdb-sys" }
duckdb-loadable-macros = { version = "0.1.3", path = "crates/duckdb-loadable-macros" }
autocfg = "1.0"
bindgen = { version = "0.69", default-features = false }
byteorder = "1.3"
Expand All @@ -34,14 +34,16 @@ doc-comment = "0.3"
fallible-iterator = "0.3"
fallible-streaming-iterator = "0.1"
flate2 = "1.0"
hashlink = "0.8"
hashlink = "0.9"
lazy_static = "1.4"
memchr = "2.3"
num = { version = "0.4", default-features = false }
num-integer = "0.1.46"
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"
Expand All @@ -60,4 +62,4 @@ unicase = "2.6.0"
url = "2.1"
uuid = "1.0"
vcpkg = "0.2"
arrow = { version = "52", default-features = false }
arrow = { version = "53", default-features = false }
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ all:
cargo clippy --all-targets --workspace --features buildtime_bindgen --features modern-full -- -D warnings -A clippy::redundant-closure

test:
cargo test --features bundled --features modern-full -- --nocapture
cargo test --features bundled --features modern-full -- --nocapture
2 changes: 1 addition & 1 deletion add_rustfmt_hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ command -v rustfmt >/dev/null 2>&1 || { echo >&2 "Rustfmt is required but it's n
# write a whole script to pre-commit hook
# NOTE: it will overwrite pre-commit file!
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/bash -e
#!/bin/bash
declare -a rust_files=()
files=$(git diff-index --name-only --cached HEAD)
echo 'Formatting source files'
Expand Down
3 changes: 2 additions & 1 deletion crates/duckdb-loadable-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "duckdb-loadable-macros"
version = "0.1.2"
version = "0.1.3"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand All @@ -14,6 +14,7 @@ description = "Native bindings to the libduckdb library, C API; build loadable e
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
darling = "0.20.10"
proc-macro2 = { workspace = true }
quote = { workspace = true }
syn = { workspace = true, features = ["extra-traits", "full", "fold", "parsing"] }
Expand Down
102 changes: 102 additions & 0 deletions crates/duckdb-loadable-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,108 @@ use syn::{parse_macro_input, spanned::Spanned, Item};
use proc_macro::TokenStream;
use quote::quote_spanned;

use darling::{ast::NestedMeta, Error, FromMeta};

/// For parsing the arguments to the duckdb_entrypoint_c_api macro
#[derive(Debug, FromMeta)]
struct CEntryPointMacroArgs {
#[darling(default)]
/// The name to be given to this extension. This name is used in the entrypoint function called by duckdb
ext_name: String,
/// The minimum C API version this extension requires. It is recommended to set this to the lowest possible version
/// at which your extension still compiles
min_duckdb_version: Option<String>,
}

/// Wraps an entrypoint function to expose an unsafe extern "C" function of the same name.
/// Warning: experimental!
#[proc_macro_attribute]
pub fn duckdb_entrypoint_c_api(attr: TokenStream, item: TokenStream) -> TokenStream {
let attr_args = match NestedMeta::parse_meta_list(attr.into()) {
Ok(v) => v,
Err(e) => {
return TokenStream::from(Error::from(e).write_errors());
}
};

let args = match CEntryPointMacroArgs::from_list(&attr_args) {
Ok(v) => v,
Err(e) => {
return TokenStream::from(e.write_errors());
}
};

// Set the minimum duckdb version (dev by default)
let minimum_duckdb_version = match args.min_duckdb_version {
Some(i) => i,
None => "dev".to_string(),
};

let ast = parse_macro_input!(item as syn::Item);

match ast {
Item::Fn(func) => {
let c_entrypoint = Ident::new(format!("{}_init_c_api", args.ext_name).as_str(), Span::call_site());
let prefixed_original_function = func.sig.ident.clone();
let c_entrypoint_internal = Ident::new(
format!("{}_init_c_api_internal", args.ext_name).as_str(),
Span::call_site(),
);

quote_spanned! {func.span()=>
/// # Safety
///
/// Internal Entrypoint for error handling
pub unsafe fn #c_entrypoint_internal(info: ffi::duckdb_extension_info, access: *const ffi::duckdb_extension_access) -> Result<bool, Box<dyn std::error::Error>> {
let have_api_struct = ffi::duckdb_rs_extension_api_init(info, access, #minimum_duckdb_version).unwrap();

if !have_api_struct {
// initialization failed to return an api struct, likely due to an API version mismatch, we can simply return here
return Ok(false);
}

// TODO: handle error here?
let db : ffi::duckdb_database = *(*access).get_database.unwrap()(info);
let connection = Connection::open_from_raw(db.cast())?;

#prefixed_original_function(connection)?;

Ok(true)
}

/// # Safety
///
/// Entrypoint that will be called by DuckDB
#[no_mangle]
pub unsafe extern "C" fn #c_entrypoint(info: ffi::duckdb_extension_info, access: *const ffi::duckdb_extension_access) -> bool {
let init_result = #c_entrypoint_internal(info, access);

if let Err(x) = init_result {
let error_c_string = std::ffi::CString::new(x.to_string());

match error_c_string {
Ok(e) => {
(*access).set_error.unwrap()(info, e.as_ptr());
},
Err(_e) => {
let error_alloc_failure = c"An error occured but the extension failed to allocate memory for an error string";
(*access).set_error.unwrap()(info, error_alloc_failure.as_ptr());
}
}
return false;
}

init_result.unwrap()
}

#func
}
.into()
}
_ => panic!("Only function items are allowed on duckdb_entrypoint"),
}
}

/// Wraps an entrypoint function to expose an unsafe extern "C" function of the same name.
#[proc_macro_attribute]
pub fn duckdb_entrypoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
Expand Down
14 changes: 12 additions & 2 deletions crates/duckdb/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "duckdb"
version = "1.0.0"
version = "1.1.1"
authors.workspace = true
edition.workspace = true
repository.workspace = true
Expand Down Expand Up @@ -32,6 +32,11 @@ extensions-full = ["json", "parquet", "vtab-full"]
buildtime_bindgen = ["libduckdb-sys/buildtime_bindgen"]
modern-full = ["chrono", "serde_json", "url", "r2d2", "uuid", "polars"]
polars = ["dep:polars"]
# FIXME: These were added to make clippy happy: these features appear unused and should perhaps be removed
column_decltype = []
extra_check = []
# Warning: experimental feature
loadable-extension = ["libduckdb-sys/loadable-extension"]

[dependencies]
libduckdb-sys = { workspace = true }
Expand All @@ -56,7 +61,7 @@ calamine = { workspace = true, optional = true }
num = { workspace = true, features = ["std"], optional = true }
duckdb-loadable-macros = { workspace = true, optional = true }
polars = { workspace = true, features = ["dtype-full"], optional = true }
num-integer = {version = "0.1.46"}
num-integer = { workspace = true }

[dev-dependencies]
doc-comment = { workspace = true }
Expand Down Expand Up @@ -90,3 +95,8 @@ all-features = false
name = "hello-ext"
crate-type = ["cdylib"]
required-features = ["vtab-loadable"]

[[example]]
name = "hello-ext-capi"
crate-type = ["cdylib"]
required-features = ["vtab-loadable", "loadable-extension"]
Loading

0 comments on commit caa2842

Please sign in to comment.