duckdb-rs is an ergonomic wrapper for using duckdb from Rust.

Overview

duckdb-rs

Build Status dependency status codecov Latest Version Docs

duckdb-rs is an ergonomic wrapper for using duckdb from Rust. It attempts to expose an interface similar to rusqlite. Acctually the initial code and even this README is forked from rusqlite as duckdb also tries to expose a sqlite3 compatible API.

use duckdb::{params, Connection, Result};

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>,
}

fn main() -> Result<()> {
    let conn = Connection::open_in_memory()?;

    conn.execute_batch(
        r"CREATE SEQUENCE seq;
          CREATE TABLE person (
                  id              INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq'),
                  name            TEXT NOT NULL,
                  data            BLOB
                  );
        ")?;

    let me = Person {
        id: 0,
        name: "Steven".to_string(),
        data: None,
    };
    conn.execute(
        "INSERT INTO person (name, data) VALUES (?, ?)",
        params![me.name, me.data],
    )?;

    let mut stmt = conn.prepare("SELECT id, name, data FROM person")?;
    let person_iter = stmt.query_map([], |row| {
        Ok(Person {
            id: row.get(0)?,
            name: row.get(1)?,
            data: row.get(2)?,
        })
    })?;

    for person in person_iter {
        println!("Found person {:?}", person.unwrap());
    }
    Ok(())
}

Notes on building duckdb and libduckdb-sys

libduckdb-sys is a separate crate from duckdb-rs that provides the Rust declarations for DuckDB's C API. By default, libduckdb-sys attempts to find a DuckDB library that already exists on your system using pkg-config, or a Vcpkg installation for MSVC ABI builds.

You can adjust this behavior in a number of ways:

  • If you use the bundled feature, libduckdb-sys will use the cc crate to compile DuckDB from source and link against that. This source is embedded in the libduckdb-sys crate and as we are still in development, we will update it regularly. After we are more stable, we will use the stable released version from duckdb. This is probably the simplest solution to any build problems. You can enable this by adding the following in your Cargo.toml file:
    [dependencies.duckdb]
    version = "0.1"
    features = ["bundled"]
  • When linking against a DuckDB library already on the system (so not using any of the bundled features), you can set the DUCKDB_LIB_DIR environment variable to point to a directory containing the library. You can also set the DUCKDB_INCLUDE_DIR variable to point to the directory containing duckdb.h.
  • Installing the duckdb development packages will usually be all that is required, but the build helpers for pkg-config and vcpkg have some additional configuration options. The default when using vcpkg is to dynamically link, which must be enabled by setting VCPKGRS_DYNAMIC=1 environment variable before build.

Binding generation

We use bindgen to generate the Rust declarations from DuckDB's C header file. bindgen recommends running this as part of the build process of libraries that used this. We tried this briefly (duckdb 0.10.0, specifically), but it had some annoyances:

  • The build time for libduckdb-sys (and therefore duckdb) increased dramatically.
  • Running bindgen requires a relatively-recent version of Clang, which many systems do not have installed by default.
  • Running bindgen also requires the DuckDB header file to be present.

So we try to avoid running bindgen at build-time by shipping pregenerated bindings for DuckDB.

If you use the bundled features, you will get pregenerated bindings for the bundled version of DuckDB. If you want to run bindgen at buildtime to produce your own bindings, use the buildtime_bindgen Cargo feature.

Contributing

See to Contributing.md

Checklist

  • Run cargo fmt to ensure your Rust code is correctly formatted.
  • Ensure cargo clippy --all-targets --workspace --features bundled passes without warnings.
  • Ensure cargo test --all-targets --workspace --features bundled reports no failures.

TODOs

  • Refactor the ErrorCode part, it's borrowed from rusqlite, we should have our own
  • Support more type
  • Update duckdb.h
  • Adjust the code examples and documentation
  • Delete unused code / functions
  • Add CI
  • Publish to crate

License

DuckDB and libduckdb-sys are available under the MIT license. See the LICENSE file for more info.

Comments
  • Re-exports arrow dependency to minimise version maintenance for crate…

    Re-exports arrow dependency to minimise version maintenance for crate…

    Hi,

    I think this is all that is required to fix #92.

    For my use case it would be ideal if you could add parquet as well but I understand if you are hesitant to add a dependency to the crate that you're not even using. However arrow and parquet are often used together so if you want to write the results of your DuckDB query out to a parquet file then you might well run into the same versin dependency problem if you don't have access to the same version of arrow and parquet.

    opened by snth 15
  • Problem with `stmt.query_arrow([])?.collect()`

    Problem with `stmt.query_arrow([])?.collect()`

    I'm a total starter and trying to learn Rust with DuckDB. Just close if it's too basic of a question, just posting it here in case others have trouble getting started.

    Error:

    rustc: a value of type `Vec<RecordBatch>` cannot be built from an iterator over elements of type `arrow::record_batch::RecordBatch` the trait `FromIterator<arrow::record_batch::RecordBatch>` is not implemented for `Vec<RecordBatch>`
    

    Question: What am I doing wrong: image

    I understand the rust iterator does not like the arrow RecordBatch. But how can I fix that, did I use the wrong arrow dependencies in my Cargo.toml on the right?

    opened by sspaeti 7
  • uuid::UUID feature - use new DuckDB UUID datatype rather than BLOB

    uuid::UUID feature - use new DuckDB UUID datatype rather than BLOB

    After duckdb 0.3.0, we should start thinking about using UUID instead of BLOB as the underlying datatype for uuid::Uuid.

    A new variant of Value seems to be required so that we can stop piggybacking off of Value::Blob.

    #[cfg(feature = "uuid")]
    impl From<uuid::Uuid> for Value {
        #[inline]
        fn from(id: uuid::Uuid) -> Value {
            Value::Blob(id.as_bytes().to_vec())
        }
    }
    

    Is it accurate to say that we will require at least 1 PR to the duckdb repo?

    • From what I can see, /src/appender.rs makes use of APIs such as ffi::duckdb_append_blob, but an API called ffi::duckdb_append_uuid doesn't exist yet.
    help wanted 
    opened by aarashy 5
  • Unable to build in Ubuntu linux

    Unable to build in Ubuntu linux

    I am trying to build the examples. But i am unable to build in Linux. Using the bundled feature flag takes quite a long time and appears to fail.

    duckdb = { version = "0.6.0", features = ["bundled" ]}
    

    Logs

       Compiling tokio-util v0.7.4
       Compiling tokio-stream v0.1.11
    The following warnings were emitted during compilation:
    
    warning: c++: fatal error: Killed signal terminated program cc1plus
    warning: compilation terminated.
    
    error: failed to run custom build command for `libduckdb-sys v0.6.0`
    
    Caused by:
      process didn't exit successfully: `/home/swoorup/personal/sample-rs/target/debug/build/libduckdb-sys-fa153eb3d17a1282/build-script-build` (exit status: 1)
      --- stdout
      cargo:rerun-if-changed=/usr/include/clang/15.0.2/include/stdbool.h
      cargo:rerun-if-changed=/usr/include/clang/15.0.2/include/stdint.h
      cargo:rerun-if-changed=/usr/include/stdint.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/features-time64.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/timesize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/stdc-predef.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/sys/cdefs.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/long-double.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/gnu/stubs.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/timesize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/typesizes.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/time64.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wchar.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/stdint-intn.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/stdlib.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/clang/15.0.2/include/stddef.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/waitflags.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/waitstatus.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/floatn.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/floatn-common.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/long-double.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/sys/types.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/clock_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/time_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/timer_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/clang/15.0.2/include/stddef.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/stdint-intn.h
      cargo:rerun-if-changed=/usr/include/endian.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/endian.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/endianness.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/byteswap.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/uintn-identity.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/sys/select.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/select.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/time_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/endian.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/types/time_t.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/wordsize.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/struct_mutex.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h
      cargo:rerun-if-changed=/usr/include/alloca.h
      cargo:rerun-if-changed=/usr/include/features.h
      cargo:rerun-if-changed=/usr/include/clang/15.0.2/include/stddef.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/stdlib-float.h
      cargo:rerun-if-changed=/usr/include/x86_64-linux-gnu/bits/floatn.h
      cargo:rerun-if-changed=duckdb/duckdb.hpp
      cargo:rerun-if-changed=duckdb/duckdb.cpp
      TARGET = Some("x86_64-unknown-linux-gnu")
      OPT_LEVEL = Some("0")
      HOST = Some("x86_64-unknown-linux-gnu")
      cargo:rerun-if-env-changed=CXX_x86_64-unknown-linux-gnu
      CXX_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXX_x86_64_unknown_linux_gnu
      CXX_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXX
      HOST_CXX = None
      cargo:rerun-if-env-changed=CXX
      CXX = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64-unknown-linux-gnu
      CXXFLAGS_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64_unknown_linux_gnu
      CXXFLAGS_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXXFLAGS
      HOST_CXXFLAGS = None
      cargo:rerun-if-env-changed=CXXFLAGS
      CXXFLAGS = None
      cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
      CRATE_CC_NO_DEFAULTS = None
      DEBUG = Some("true")
      CARGO_CFG_TARGET_FEATURE = Some("fxsr,llvm14-builtins-abi,sse,sse2")
      cargo:rerun-if-env-changed=CXX_x86_64-unknown-linux-gnu
      CXX_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXX_x86_64_unknown_linux_gnu
      CXX_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXX
      HOST_CXX = None
      cargo:rerun-if-env-changed=CXX
      CXX = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64-unknown-linux-gnu
      CXXFLAGS_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64_unknown_linux_gnu
      CXXFLAGS_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXXFLAGS
      HOST_CXXFLAGS = None
      cargo:rerun-if-env-changed=CXXFLAGS
      CXXFLAGS = None
      cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
      CRATE_CC_NO_DEFAULTS = None
      CARGO_CFG_TARGET_FEATURE = Some("fxsr,llvm14-builtins-abi,sse,sse2")
      cargo:rerun-if-env-changed=CXX_x86_64-unknown-linux-gnu
      CXX_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXX_x86_64_unknown_linux_gnu
      CXX_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXX
      HOST_CXX = None
      cargo:rerun-if-env-changed=CXX
      CXX = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64-unknown-linux-gnu
      CXXFLAGS_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64_unknown_linux_gnu
      CXXFLAGS_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXXFLAGS
      HOST_CXXFLAGS = None
      cargo:rerun-if-env-changed=CXXFLAGS
      CXXFLAGS = None
      cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
      CRATE_CC_NO_DEFAULTS = None
      CARGO_CFG_TARGET_FEATURE = Some("fxsr,llvm14-builtins-abi,sse,sse2")
      cargo:rerun-if-env-changed=CXX_x86_64-unknown-linux-gnu
      CXX_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXX_x86_64_unknown_linux_gnu
      CXX_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXX
      HOST_CXX = None
      cargo:rerun-if-env-changed=CXX
      CXX = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64-unknown-linux-gnu
      CXXFLAGS_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64_unknown_linux_gnu
      CXXFLAGS_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXXFLAGS
      HOST_CXXFLAGS = None
      cargo:rerun-if-env-changed=CXXFLAGS
      CXXFLAGS = None
      cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
      CRATE_CC_NO_DEFAULTS = None
      CARGO_CFG_TARGET_FEATURE = Some("fxsr,llvm14-builtins-abi,sse,sse2")
      cargo:rerun-if-env-changed=CXX_x86_64-unknown-linux-gnu
      CXX_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXX_x86_64_unknown_linux_gnu
      CXX_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXX
      HOST_CXX = None
      cargo:rerun-if-env-changed=CXX
      CXX = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64-unknown-linux-gnu
      CXXFLAGS_x86_64-unknown-linux-gnu = None
      cargo:rerun-if-env-changed=CXXFLAGS_x86_64_unknown_linux_gnu
      CXXFLAGS_x86_64_unknown_linux_gnu = None
      cargo:rerun-if-env-changed=HOST_CXXFLAGS
      HOST_CXXFLAGS = None
      cargo:rerun-if-env-changed=CXXFLAGS
      CXXFLAGS = None
      cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
      CRATE_CC_NO_DEFAULTS = None
      CARGO_CFG_TARGET_FEATURE = Some("fxsr,llvm14-builtins-abi,sse,sse2")
      running: "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-std=c++11" "-o" "/home/swoorup/personal/sample-rs/target/debug/build/libduckdb-sys-0d8aca56e8cb0792/out/duckdb/duckdb.o" "-c" "duckdb/duckdb.cpp"
      cargo:warning=c++: fatal error: Killed signal terminated program cc1plus
      cargo:warning=compilation terminated.
      exit status: 1
    
      --- stderr
    
    
      error occurred: Command "c++" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-std=c++11" "-o" "/home/swoorup/personal/sample-rs/target/debug/build/libduckdb-sys-0d8aca56e8cb0792/out/duckdb/duckdb.o" "-c" "duckdb/duckdb.cpp" with args "c++" did not execute successfully (status code exit status: 1).
    
    
    opened by Swoorup 4
  • Question about usage of RefCell and Connection being `!Sync`

    Question about usage of RefCell and Connection being `!Sync`

    Hello!

    You can ignore the actual diff of this PR for the moment, my real purpose is to raise a discussion.

    1. I'm interested in wrapping Connection with an Arc<RwLock<_>> rather than an Arc<Mutex<_>>, so that I may have multiple reader threads simultaneously reading a database. (According to my reading of 1, 2, it's even alright for different processes to simultaneously read the same file, but I just want multiple async threads in the same process using the same connection. DuckDB does support this based on 3 within Python, so there's no reason we shouldn't be able to).

    2. I noticed that conn.execute_batch takes a &self - immutable ref instead of mutable ref - which seemed odd to me, since it does mutate the underlying data. I realized this is possible due to the usage of RefCell and borrow_mut around InnerConnection which this crate took from rusqlite which was our starting point. This led me to a rusqlite thread where they discuss intentionally opting out of the compile-time borrow checker 4.

    I realize that there are limitations of using the compile-time borrow checker... there's clearly not a practical/efficient way to check whether a raw SQL string is read-only or not... but the usage of RefCell makes our Connection struct !Sync. This means that I cannot pass Arc<RwLock<Connection>> into a tokio::spawn_blocking because only Mutex is the only wrapper that can make a non-Sync T into Sync.

    So basically, my question is: do you think it's possible and/or desirable to make Connection into a Sync struct by avoiding usage of RefCell? If I were to embark on that, do you think I should take special care to continue supporting the sqlite API's reference mutability?

    The long term goal would be to make query_arrow take a immutable ref instead of a mut ref so that multiple Tokio threads can process SELECT statements on the same connection.

    opened by aarashy 3
  • "Invalid memory reference" when appending a row with a timestamp

    Thanks for the crate!

    I'm trying to use the Appender api but get a segfault when there is a timestamp in the row. Here's a minimal example showing what happens (and here is a repo reproducing it):

        #[test]
        fn timestamp_appender_minimal_example_sig_segv() {
            let db = Connection::open_in_memory().unwrap();
    
            let create_table_sql = r"
              CREATE TABLE item (
                  id INTEGER NOT NULL,
                  ts TIMESTAMP
              );";
            db.execute_batch(create_table_sql).unwrap();
    
            let mut app = db.appender("item").unwrap();
            let row_count = 10;
            for i in 0..row_count {
                app.append_row(params![i, "1970-01-01T00:00:00Z"]).unwrap();
            }
    
            // running 1 test
            // error: test failed, to rerun pass '--lib'
            // Caused by:
            //   process didn't exit successfully: `/path-to-repo` (signal: 11, SIGSEGV: invalid memory reference)
    
            let val = db
                .query_row("SELECT count(1) FROM item", [], |row| {
                    <(u32,)>::try_from(row)
                })
                .unwrap();
    
            assert_eq!(val, (row_count,));
        }
    

    I've enabled the chrono feature and tried with Utc::now as well. This is using the bundled version of duckdb.

    I'd love to help fix the issue, would you mind pointing me in the right direction? I started a draft with failing tests here

    opened by danbruder 3
  • Update Arrow dependency version

    Update Arrow dependency version

    I have a project using the latest version of arrow (11.1.0), which seems to conflict with the version used by duckdb-rs (6.5.0):

        = note: expected reference `&arrow::datatypes::Schema`
                   found reference `&arrow::datatypes::schema::Schema`
        = note: perhaps two different versions of crate `arrow` are being used?
    

    I can't downgrade my version as I'm also attempting to use arrow-flight (also 11.1.0) which wasn't available around 6.5.0 (I'm assuming I need to keep arrow and arrow-flight in lockstep).

    Is it possible to update the version of arrow used by duckdb-rs?

    opened by mharmer 3
  • Baffled by problems building libduckdb-sys with Dockerfile

    Baffled by problems building libduckdb-sys with Dockerfile

    I am also working on the prql project, and trying to create a Dockerfile to encapulate all the machinery in a reproducible Docker container. I encounter a problem with an error while compiling libduckdb-sys.

    Specifically, I'm working with the prql-query repo. I can run cargo build natively without problem. But when I attempt to use docker build -t pq . on the repo, I get the error reported in this Issue: error: failed to run custom build command for libduckdb-sys v0.5.1

    Here's an excerpt showing the error message - The original report lists all the details. Any ideas about how to troubleshoot this? Many thanks.

    # error from "docker build -t pq ." ...
    ...
    #12 470.9 The following warnings were emitted during compilation:
    #12 470.9
    #12 470.9 warning: c++: fatal error: Killed signal terminated program cc1plus
    #12 470.9 warning: compilation terminated.
    #12 470.9
    #12 470.9 error: failed to run custom build command for `libduckdb-sys v0.5.1`
    #12 470.9
    #12 470.9 Caused by:
    #12 471.0   process didn't exit successfully: `/app/target/release/build/libduckdb-sys-dd2866ecae070e6b/build-script-build` (exit status: 1)
    ...
    
    opened by richb-hanover 2
  • Update arrow requirement from 21 to 22

    Update arrow requirement from 21 to 22

    Updates the requirements on arrow to permit the latest version.

    Changelog

    Sourced from arrow's changelog.

    22.0.0 (2022-09-02)

    Full Changelog

    Breaking changes:

    Implemented enhancements:

    • Add Macros to assist with static dispatch #2635 [arrow]
    • Support comparison between DictionaryArray and BooleanArray #2617 [arrow]
    • Use total_cmp for floating value ordering and remove nan_ordering feature flag #2613 [arrow]
    • Support empty projection in CSV, JSON readers #2603 [arrow]
    • Support SQL-compliant NaN ordering between for DictionaryArray and non-DictionaryArray #2599 [arrow]
    • Add dyn_cmp_dict feature flag to gate dyn comparison of dictionary arrays #2596 [arrow]
    • Add max_dyn and min_dyn for max/min for dictionary array #2584 [arrow]
    • Allow FlightSQL implementers to extend do_get() #2581 [arrow-flight]
    • Support SQL-compliant behavior on eq_dyn, neq_dyn, lt_dyn, lt_eq_dyn, gt_dyn, gt_eq_dyn #2569 [arrow]
    • Add sql-compliant feature for enabling sql-compliant kernel behavior #2568
    • Calculate sum for dictionary array #2565 [arrow]
    • Add test for float nan comparison #2556 [arrow]
    • Compare dictionary with string array #2548 [arrow]
    • Compare dictionary with primitive array in lt_dyn, lt_eq_dyn, gt_dyn, gt_eq_dyn #2538 [arrow]
    • Compare dictionary with primitive array in eq_dyn and neq_dyn #2535 [arrow]
    • UnionBuilder Create Children With Capacity #2523 [arrow]
    • Speed up like_utf8_scalar for %pat% #2519 [arrow]
    • Replace macro with TypedDictionaryArray in comparison kernels #2513 [arrow]
    • Use same codebase for boolean kernels #2507 [arrow]
    • Use u8 for Decimal Precision and Scale #2496 [arrow]
    • Integrate skip row without pageIndex in SerializedPageReader in Fuzz Test #2475 [parquet]
    • Avoid unecessary copies in Arrow IPC reader #2437 [arrow]
    • Add GenericColumnReader::skip_records Missing OffsetIndex Fallback #2433 [parquet]
    • Support Reading PageIndex with ParquetRecordBatchStream #2430 [parquet]
    • Specialize FixedLenByteArrayReader for Parquet #2318 [parquet]
    • Make JSON support Optional via Feature Flag #2300 [arrow]

    Fixed bugs:

    • Casting timestamp array to string should not ignore timezone #2607 [arrow]
    • Ilike_ut8_scalar kernals have incorrect logic #2544 [arrow]
    • Always validate the array data when creating array in IPC reader #2541 [arrow]

    ... (truncated)

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    auto-dependencies 
    opened by dependabot[bot] 2
  • Compile from source on Windows

    Compile from source on Windows

    We found that you can compile the duckdb-rs crate with its bundled feature on Windows if you use Clang as the compiler (i.e. set CC=clang and CXX=clang++). All we needed to do is let the cc crate decide whether to emit -fPIC instead of forcing it to always be enabled (the default is false for Windows, true for everything else).

    Fixes #62.

    opened by Michael-F-Bryan 2
  • Unable to compile `duckdb-sys` on Windows

    Unable to compile `duckdb-sys` on Windows

    We were setting up Windows builds in GitHub Actions for our app and noticed that the duckdb-sys v0.4.0 crate's build script is unable to compile DuckDB from source.

    There are a lot of suspicious warnings, and I've had to attach the output as a file because GitHub has a 65536 character limit on comments, but I think this is the thing that actually fails the build:

    fatal error C1128: number of sections exceeded object file format limit: compile with /bigobj
    

    (Link to full output from the build script)

    I notice you've actually commented out the Windows build for this repo's CI. Does that mean this is a known issue?

    https://github.com/wangfenjin/duckdb-rs/blob/30d8e3e637f8a3f9b96ca6de9e2275bc69a5bbae/.github/workflows/rust.yaml#L15-L17

    help wanted 
    opened by Michael-F-Bryan 2
  • [WIP] Initial support of table function

    [WIP] Initial support of table function

    This is based on @Mause 's https://github.com/Mause/duckdb-extension-framework

    It works (refer test_table_function), but I'm thinking about design a more safe and high level API, similiar to rusqlite vtab, So need more time to merge the MR

    If anyone interested to work on this base on this version can let me know

    related to #102 #79

    opened by wangfenjin 1
  • Very high RAM consumption on build

    Very high RAM consumption on build

    Is it normal the bundled crate requires >16GB of RAM to build? It looks like the C++ compiler is compiling one giant cpp file. Is it not possible to perform separate compilation?

    questions 
    opened by rongcuid 1
  • Improve docs

    Improve docs

    Currently there is no way to learn how to use this library. There should be a duckdb-rs book for the best practices to do common operations such as inserting, querying etc..

    opened by 0b01 0
  • Allow bundling of extensions at compilation time

    Allow bundling of extensions at compilation time

    Hi,

    First of all a huge thank you very much for creating and maintaining this extension! It works wonderfully and I am making extensive use of it in prql-query.

    I'm currently loading DuckDB extensions through remote installation, eg INSTALL parquet; LOAD parquet; code example. This works fine but causes a noticeable delay on each invocation.

    Discussing this with the DuckDB developers on Discord (thread) they pointed out that these extensions can be bundled at compile time:

    The various extensions can be bundled by toggling the BUILD_..._EXTENSION in the CMake whereever the shared library is produced:

    option(BUILD_ICU_EXTENSION "Build the ICU extension." FALSE)
    option(BUILD_PARQUET_EXTENSION "Build the Parquet extension." FALSE)
    option(BUILD_TPCH_EXTENSION "Build the TPC-H extension." FALSE)
    option(BUILD_TPCDS_EXTENSION "Build the TPC-DS extension." FALSE)
    option(BUILD_FTS_EXTENSION "Build the FTS extension." FALSE)
    option(BUILD_HTTPFS_EXTENSION "Build the HTTP File System extension." FALSE)
    option(BUILD_JSON_EXTENSION "Build the JSON extension." FALSE)
    option(BUILD_EXCEL_EXTENSION "Build the excel extension." FALSE)
    option(BUILD_INET_EXTENSION "Build the inet extension." FALSE)
    

    Would it be possible for you to facilitate this somehow?

    My guess is that this would have to be done as part of the libduckdb-sys build stage somehow but I don't understand enough of this to really attempt a PR for this myself.

    opened by snth 8
  • How to insert lists, maps, and structs?

    How to insert lists, maps, and structs?

    Maybe I missed it, but I couldn't see how to insert a row if one of the columns is e.g. TEXT[]. I naively tried params![a_vec_of_str] but ToSql is only implemented for Vec<u8> (I guess for blobs).

    The DuckDB docs aren't super clear but it looks like you're supposed to use list_create('a', 'b', 'c') but I'm not sure how to do that with params![].

    feature 
    opened by Timmmm 10
Releases(v0.6.1)
  • v0.6.1(Dec 12, 2022)

    What's Changed

    • Update arrow requirement from 26 to 27 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/98
    • Update bindgen requirement from 0.61 to 0.62 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/100
    • Update bindgen requirement from 0.62 to 0.63 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/101
    • Update arrow requirement from 27 to 28 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/103
    • Add timestamp wrapper type by @0b01 in https://github.com/wangfenjin/duckdb-rs/pull/105
    • update to 0.6.1 by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/104

    New Contributors

    • @0b01 made their first contribution in https://github.com/wangfenjin/duckdb-rs/pull/105

    Full Changelog: https://github.com/wangfenjin/duckdb-rs/compare/v0.6.0...v0.6.1

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Nov 14, 2022)

  • v0.5.1(Sep 20, 2022)

    What's Changed

    • add parquet example by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/80
    • Update arrow requirement from 21 to 23 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/82
    • upgrade to 0.5.1 by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/83

    Full Changelog: https://github.com/wangfenjin/duckdb-rs/compare/v0.5.0...v0.5.1

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Sep 7, 2022)

    NOTE: please be noted that there is an issue in duckdb 0.5.0 https://github.com/duckdb/duckdb/issues/4612 . If you use this feature, you may need to build the binary from source by yourself.

    What's Changed

    • Update arrow requirement from 16 to 17 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/61
    • Update arrow requirement from 17 to 18 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/64
    • Compile from source on Windows by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/65
    • impl cache for prepared_stmt by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/67
    • Update arrow requirement from 18 to 19 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/71
    • Update arrow requirement from 19 to 20 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/72
    • fix security warning by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/73
    • Update arrow requirement from 20 to 21 by @dependabot in https://github.com/wangfenjin/duckdb-rs/pull/74
    • add test append string as ts by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/75
    • Bump 0.4.0 -> 0.5.0 by @chhetripradeep in https://github.com/wangfenjin/duckdb-rs/pull/77
    • clear bindings by @wangfenjin in https://github.com/wangfenjin/duckdb-rs/pull/78

    New Contributors

    • @chhetripradeep made their first contribution in https://github.com/wangfenjin/duckdb-rs/pull/77

    Full Changelog: https://github.com/wangfenjin/duckdb-rs/compare/v0.4.0...v0.5.0

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 20, 2022)

  • v0.3.4(Apr 25, 2022)

  • v0.3.3(Apr 12, 2022)

  • v0.3.2(Feb 8, 2022)

    Please be noted that we also upgrade rust edition to 2021 in this release

    🚀 Features

    • add r2d2 connection pool
      • PR: #32
    • upgrade to 0.3.2
      • PR: #34
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jan 2, 2022)

    🚀 Features

    • Update duckdb to v0.3.1
      • PR: #30

    🐛 Fixes

    • Fix u64/UBigInt 'FromSql' trait impl
      • PR: #25
    • support hugeint
      • PR: #28

    🧪 Tests

    • add test for uint
      • PR: #26
    Source code(tar.gz)
    Source code(zip)
  • v0.2.9(Sep 11, 2021)

  • v0.2.4(Sep 5, 2021)

    🚀 Features

    • impl appender
      • PR: #12
    • impl date32 and timestamp
      • PR: #17
    • enable serde_json and url
      • PR: #19
    • feat: impl config
      • PR: #20
    • enable publish crates in CI
      • PR: #21
    Source code(tar.gz)
    Source code(zip)
Owner
Wang Fenjin
Software Engineer at Bytedance. wechat: wangfenjin
Wang Fenjin
Ergonomic bindings to SQLite for Rust

Rusqlite Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to expose an interface similar to rust-postgres. use rusqlite::{para

Rusqlite 1.9k Jan 5, 2023
rust wrapper for rocksdb

rust-rocksdb Requirements Clang and LLVM Contributing Feedback and pull requests welcome! If a particular feature of RocksDB is important to you, plea

null 1.3k Dec 30, 2022
UnQLite wrapper 1.0 is avaliable for Rust

unqlite A high-level UnQLite database engine wrapper. NOTE: Some of the documents is stolen from UnQLite Official Website. What is UnQLite? UnQLite is

Huo Linhe 101 Dec 12, 2022
An API Wrapper for https://paste.myst.rs written in rust

PasteMyst.RS pastemyst-rs is an api wrapper for pastemyst written in Rust. ⚠ This package is under development ⚠ Sample usage To get a paste from past

ANF Studios 14 Nov 28, 2021
ODBC wrapper for safe idiomatic Rust

ODBC wrapper for safe idiomatic Rust Library for writing ODBC applications in Rust. If you're looking for raw ODBC FFI bindings check odbc-safe and od

Konstantin V. Salikhov 91 Dec 10, 2022
Thin wrapper around [`tokio::process`] to make it streamable

process-stream Wraps tokio::process::Command to future::stream. Install process-stream = "0.2.2" Example usage: From Vec<String> or Vec<&str> use proc

null 4 Jun 25, 2022
Postgres Foreign Data Wrapper for Clerk.com API

Pre-requisites Postgres-15 Rust pgrx Getting Started To run the program locally, clone the repository git clone https://github.com/tembo-io/clerk_fdw.

Tembo 3 Aug 22, 2023
Cassandra (CQL) driver for Rust, using the DataStax C/C++ driver under the covers.

cassandra-cpp This is a maintained Rust project that exposes the DataStax cpp driver at https://github.com/datastax/cpp-driver/ in a somewhat-sane cra

null 93 Jan 7, 2023
A pure Rust database implementation using an append-only B-Tree file format.

nebari nebari - noun - the surface roots that flare out from the base of a bonsai tree Warning: This crate is early in development. The format of the

Khonsu Labs 194 Jan 3, 2023
Provides a Rust-based SQLite extension for using Hypercore as the VFS for your databases.

SQLite and Hypercore A Rust library providing SQLite with an virtual file system to enable Hypercore as a means of storage. Contributing The primary r

Jacky Alciné 14 Dec 5, 2022
A firebase HTTP v1 client implementation in Rust using google-authz

firebase-client A firebase HTTP v1 client implementation in Rust using the google_authz library. Example There are two ways to send notifications, one

Mobiltracker 2 Dec 14, 2022
Dataloader-rs - Rust implementation of Facebook's DataLoader using async-await.

Dataloader Rust implementation of Facebook's DataLoader using async-await. Documentation Features Batching load requests with caching Batching load re

cksac 229 Nov 27, 2022
Rust library to parse, deparse and normalize SQL queries using the PostgreSQL query parser

This Rust library uses the actual PostgreSQL server source to parse SQL queries and return the internal PostgreSQL parse tree.

pganalyze 37 Dec 18, 2022
Rust Uint crate using const-generics

Rust uint crate using const-generics Implements [Uint<BITS, LIMBS>], the ring of numbers modulo $2^{\mathtt{BITS}}$ . It requires two generic argument

Remco Bloemen 63 Dec 29, 2022
A mini kv database demo that using simplified bitcask storage model with rust implementation

A mini kv database demo that using simplified bitcask storage model with rust implementation.

Wancheng Long 17 Nov 28, 2022
A Rust-based comment server using SQLite and an intuitive REST API.

soudan A Rust-based comment server using SQLite and an intuitive REST API. Soudan is built with simplicity and static sites in mind. CLI usage See sou

Elnu 0 Dec 19, 2022
rustodrive is a rust client library for communicating with ODrives using the CAN protocol.

rustodrive is a WIP client library for communicating with ODrives using the CAN protocol. It is more than a simple CAN sender/receiver and has many co

null 5 Oct 31, 2022
Notification demon + web server using async Rust

Async Rust example Road to the asynchronous Rust Table of Contents About the Project Screenshots Tech Stack Features Getting Started Prerequisites Clo

Edem Khadiev 4 Feb 9, 2023
Using embedded database modeled off SQLite - in Rust

Rust-SQLite (SQLRite) Rust-SQLite, aka SQLRite , is a simple embedded database modeled off SQLite, but developed with Rust. The goal is get a better u

Hand of Midas 3 May 19, 2023