Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/nimdeveloper/better-duck/llms.txt

Use this file to discover all available pages before exploring further.

better-duck-diesel organises column types into two categories. The first is the set of standard Diesel SQL types (Bool, Integer, Text, Timestamp, and so on) — these work out of the box without any extra import. The second is a set of DuckDB-specific extensions that cover unsigned integers, oversized integers, timestamps with time zones, composite types, and more. The extension types live in better_duck_diesel::sql_types and must be brought into scope explicitly when you use them in a table! definition.

Standard Diesel Types

These types require no additional imports and map directly to common DuckDB column types. All chrono-mapped Rust types require the chrono feature on better-duck-diesel.
Diesel SQL typeDuckDB column typeRust type
BoolBOOLEANbool
SmallIntSMALLINTi16
IntegerINTEGERi32
BigIntBIGINTi64
FloatFLOATf32
DoubleDOUBLEf64
TextVARCHARString
BinaryBLOBVec<u8>
DateDATEchrono::NaiveDate (chrono)
TimeTIMEchrono::NaiveTime (chrono)
TimestampTIMESTAMPchrono::NaiveDateTime (chrono)
NumericDECIMALrust_decimal::Decimal (decimal)
Nullable columns are expressed with the standard Nullable<T> wrapper, for example Nullable<Integer> maps to Option<i32> in Rust.

DuckDB-Specific Types

Add use better_duck_diesel::sql_types::*; inside the table! macro body whenever you need one of the DuckDB-specific types below. The import must be inside the macro, not at the top of the module, because Diesel’s table! macro resolves type names in its own scope.
Import the extension types with:
use better_duck_diesel::sql_types::*;
Diesel SQL typeDuckDB column typeRust type
DuckTinyIntTINYINT (INT1)i8
DuckUTinyIntUTINYINTu8
DuckUSmallIntUSMALLINTu16
DuckUIntUINTEGERu32
DuckUBigIntUBIGINTu64
DuckHugeIntHUGEINTi128
DuckUHugeIntUHUGEINTu128
DuckTimestamptzTIMESTAMPTZchrono::DateTime<Utc> (chrono)
DuckIntervalINTERVALchrono::Duration (chrono)
DuckTimeTzTIME WITH TIME ZONEbetter_duck_core::types::date_chrono::TimeTz (chrono)
DuckTimeNsTIME_NSchrono::NaiveTime (chrono)
DuckEnumENUMString
DuckListLIST (variable-length)Vec<DuckValue>
DuckArrayARRAY (fixed-length)Vec<DuckValue>
DuckStructSTRUCTHashMap<String, DuckValue>
DuckMapMAPHashMap<DuckValue, DuckValue>
DuckUnionUNIONBox<DuckValue> (active member)
DuckUuidUUIDbetter_duck_core::types::uuid::DuckUuid
DuckBitBITbetter_duck_core::types::bit::DuckBit
DuckBignumBIGNUMbetter_duck_core::types::bignum::DuckBignum
DuckValue is from better_duck_core::types::value::DuckValue. For composite types (DuckList, DuckArray, DuckStruct, DuckMap, DuckUnion) you typically use diesel::sql_query with QueryableByName rather than the full DSL, because Diesel’s Queryable blanket does not extend to heterogeneous container types.

Using DuckDB Types in table!

Place both use statements inside the table! block to make the DuckDB-specific names available alongside the standard ones:
diesel::table! {
    use diesel::sql_types::*;
    use better_duck_diesel::sql_types::*;

    readings (id) {
        id     -> Integer,
        sensor -> DuckEnum,         // DuckDB ENUM column → String in Rust
        value  -> Double,
        ts     -> DuckTimestamptz,  // TIMESTAMPTZ column → chrono::DateTime<Utc>
    }
}
For DuckHugeInt and DuckUHugeInt, Diesel’s Queryable blanket does not cover i128/u128. Use QueryableByName with an explicit #[diesel(sql_type = DuckHugeInt)] attribute instead:
use better_duck_diesel::sql_types::DuckHugeInt;

#[derive(diesel::QueryableByName, Debug)]
struct BigRow {
    #[diesel(sql_type = DuckHugeInt)]
    val: i128,
}

let row: BigRow = diesel::sql_query("SELECT val FROM my_table LIMIT 1")
    .get_result(&mut conn)?;

Date/Time Types and the chrono Feature

Date/time types work in two modes depending on whether the chrono feature is enabled on better-duck-diesel:
  • With chronoDate maps to chrono::NaiveDate, Time to chrono::NaiveTime, Timestamp to chrono::NaiveDateTime, DuckTimestamptz to chrono::DateTime<Utc>, DuckInterval to chrono::Duration, DuckTimeTz to better_duck_core::types::date_chrono::TimeTz, and DuckTimeNs to chrono::NaiveTime.
  • Without chrono — all date/time types map to plain structs from better_duck_core::types::date_native (DuckDate, DuckTime, DuckTimestamp, and so on) and std::time::Duration for intervals.
Only one set of implementations is compiled at a time. Enable chrono if your application already depends on the chrono crate to avoid maintaining two separate date/time representations.
# Enable chrono date/time support in better-duck-diesel.
[dependencies.better-duck-diesel]
version  = "0.1.0-beta.4"
features = ["chrono"]

Build docs developers (and LLMs) love