Skip to content

Commit

Permalink
feat: sqlite decimal
Browse files Browse the repository at this point in the history
  • Loading branch information
aljazerzen committed Feb 21, 2024
1 parent 64a3b7b commit fbf90a7
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 13 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion connector_arrow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ default-features = false
optional = true

[dependencies.duckdb]
version = "0.10"
version = "0.9.2"
default-features = false
optional = true

Expand Down
26 changes: 24 additions & 2 deletions connector_arrow/src/sqlite/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ impl ConsumeTy<NullType> for Vec<Value> {
}
}

impl ConsumeTy<Decimal128Type> for Vec<Value> {
fn consume(&mut self, ty: &DataType, value: i128) {
self.push(Value::Text(crate::util::decimal::decimal128_to_string(
ty, value,
)));
}

fn consume_null(&mut self) {
self.push(Value::Null);
}
}

impl ConsumeTy<Decimal256Type> for Vec<Value> {
fn consume(&mut self, ty: &DataType, value: i256) {
self.push(Value::Text(crate::util::decimal::decimal256_to_string(
ty, value,
)));
}

fn consume_null(&mut self) {
self.push(Value::Null);
}
}

impl_consume_ty!(BooleanType, Value::Integer, i64::from);
impl_consume_ty!(Int8Type, Value::Integer, i64::from);
impl_consume_ty!(Int16Type, Value::Integer, i64::from);
Expand Down Expand Up @@ -164,8 +188,6 @@ impl_consume_unsupported!(
DurationMillisecondType,
DurationMicrosecondType,
DurationNanosecondType,
Decimal128Type,
Decimal256Type,
)
);

Expand Down
2 changes: 2 additions & 0 deletions connector_arrow/src/sqlite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ impl Connection for SQLiteConnection {
DataType::LargeBinary => Some(DataType::LargeBinary),
DataType::Utf8 => Some(DataType::LargeUtf8),
DataType::LargeUtf8 => Some(DataType::LargeUtf8),
DataType::Decimal128(_, _) => Some(DataType::LargeUtf8),
DataType::Decimal256(_, _) => Some(DataType::LargeUtf8),
_ => None,
}
}
Expand Down
33 changes: 33 additions & 0 deletions connector_arrow/src/util/decimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use arrow::datatypes::{i256, DataType};

pub fn decimal128_to_string(ty: &DataType, value: i128) -> String {
let DataType::Decimal128(_, scale) = ty else {
unreachable!();
};
insert_dot(scale, value.to_string())
}

pub fn decimal256_to_string(ty: &DataType, value: i256) -> String {
let DataType::Decimal256(_, scale) = ty else {
unreachable!();
};
insert_dot(scale, value.to_string())
}

fn insert_dot(scale: &i8, value: String) -> String {
if *scale > 0 {
let minus_len: usize = if value.starts_with('-') { 1 } else { 0 };

let fracs = *scale as usize;
if fracs >= value.len() - minus_len {
let (minus, value) = value.split_at(minus_len);
format!("{minus}0.{}{value}", "0".repeat(fracs - value.len()))
} else {
let mut value = value;
value.insert(value.len() - fracs, '.');
value
}
} else {
value
}
}
1 change: 1 addition & 0 deletions connector_arrow/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod arrow_reader;
pub mod coerce;
pub mod decimal;
mod row_collect;
mod row_reader;
mod row_writer;
Expand Down
1 change: 1 addition & 0 deletions connector_arrow/tests/it/test_sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fn query_01() {
#[case::int("roundtrip::int", spec::int())]
#[case::uint("roundtrip::uint", spec::uint())]
#[case::float("roundtrip::float", spec::float())]
#[case::decimal("roundtrip::decimal", spec::decimal())]
fn roundtrip(#[case] table_name: &str, #[case] spec: spec::ArrowGenSpec) {
let mut conn = init();
super::tests::roundtrip(&mut conn, table_name, spec);
Expand Down
17 changes: 11 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
dontCheckPython = drv: drv.overridePythonAttrs (old: { doCheck = false; });

essentials = with pkgs; [
fenix_pkgs.stable.cargo
fenix_pkgs.stable.clippy
fenix_pkgs.stable.rust-src
fenix_pkgs.stable.rustc
fenix_pkgs.stable.rustfmt
fenix_pkgs.stable.rust-analyzer
(fenix_pkgs.complete.withComponents [
"cargo"
"clippy"
"rust-src"
"rustc"
"rustfmt"
"rust-analyzer"
])
clang

# tools
Expand All @@ -50,6 +52,9 @@
{
devShells.default = pkgs.mkShell {
buildInputs = essentials ++ dbs;

# linking duckdb needs this
LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib";
};
});
}

0 comments on commit fbf90a7

Please sign in to comment.