Skip to content

Commit 1fee2eb

Browse files
committed
support hugeint
Change-Id: I0162316880d07e8760a749cd9893a9497014e3a5
1 parent 38cd5fe commit 1fee2eb

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

src/row.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ impl<'stmt> Row<'stmt> {
481481
if array.is_null(row) {
482482
return ValueRef::Null;
483483
}
484+
// hugeint: d:38,0
485+
if array.scale() == 0 {
486+
return ValueRef::HugeInt(array.value(row));
487+
}
484488
ValueRef::Decimal(Decimal::from_i128_with_scale(array.value(row), array.scale() as u32))
485489
}
486490
DataType::Timestamp(unit, _) if *unit == TimeUnit::Second => {

src/statement.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,13 @@ impl Statement<'_> {
419419
ValueRef::SmallInt(i) => unsafe { ffi::duckdb_bind_int16(ptr, col as u64, i) },
420420
ValueRef::Int(i) => unsafe { ffi::duckdb_bind_int32(ptr, col as u64, i) },
421421
ValueRef::BigInt(i) => unsafe { ffi::duckdb_bind_int64(ptr, col as u64, i) },
422-
423-
// FIXME
424-
ValueRef::HugeInt(i) => unsafe { ffi::duckdb_bind_int64(ptr, col as u64, i as i64) },
425-
422+
ValueRef::HugeInt(i) => unsafe {
423+
let hi = ffi::duckdb_hugeint {
424+
lower: i as u64,
425+
upper: (i >> 64) as i64,
426+
};
427+
ffi::duckdb_bind_hugeint(ptr, col as u64, hi)
428+
},
426429
ValueRef::Float(r) => unsafe { ffi::duckdb_bind_float(ptr, col as u64, r) },
427430
ValueRef::Double(r) => unsafe { ffi::duckdb_bind_double(ptr, col as u64, r) },
428431
ValueRef::Text(s) => unsafe {

src/types/from_sql.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,20 @@ mod test {
313313
Ok(())
314314
}
315315

316+
// This test asserts that i128s above/below the i64 max/min can written and retrieved properly.
317+
#[test]
318+
fn test_hugeint_max_min() -> Result<()> {
319+
let db = Connection::open_in_memory()?;
320+
db.execute("CREATE TABLE huge_int (u1 hugeint, u2 hugeint);", [])?;
321+
// Min/Max value defined in here: https://duckdb.org/docs/sql/data_types/numeric
322+
let i128max: i128 = i128::MAX;
323+
let i128min: i128 = i128::MIN + 1;
324+
db.execute("INSERT INTO huge_int VALUES (?, ?);", [&i128max, &i128min])?;
325+
let v = db.query_row("SELECT * FROM huge_int", [], |row| <(i128, i128)>::try_from(row))?;
326+
assert_eq!(v, (i128max, i128min));
327+
Ok(())
328+
}
329+
316330
#[test]
317331
fn test_integral_ranges() -> Result<()> {
318332
let db = Connection::open_in_memory()?;

0 commit comments

Comments
 (0)