Skip to content

Commit f0c84c5

Browse files
committed
Union types, refactoring, etc
1 parent c56e458 commit f0c84c5

29 files changed

+3230
-1214
lines changed

.rustfmt.toml

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1-
max_width = 120
2-
imports_granularity = "Crate"
1+
max_width=120
2+
imports_granularity = "Crate"
3+
reorder_imports = true
4+
fn_call_width=72
5+
# indent_style = "Block"
6+
# tab_spaces = 2
7+
# group_imports="StdExternalCrate"

Cargo.toml

+11-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ duckdb-loadable-macros = { version = "0.1.1", path = "crates/duckdb-loadable-mac
2525
autocfg = "1.0"
2626
bindgen = { version = "0.69", default-features = false }
2727
byteorder = "1.3"
28-
calamine = "0.22.0"
28+
calamine = "0.22"
2929
cast = "0.3"
3030
cc = "1.0"
3131
chrono = "0.4.22"
@@ -34,13 +34,15 @@ doc-comment = "0.3"
3434
fallible-iterator = "0.3"
3535
fallible-streaming-iterator = "0.1"
3636
flate2 = "1.0"
37-
hashlink = "0.8"
37+
hashlink = "0.9"
3838
lazy_static = "1.4"
3939
memchr = "2.3"
4040
num = { version = "0.4", default-features = false }
41+
num-integer = "0.1.46"
4142
pkg-config = "0.3.24"
42-
polars = "0.35.4"
43-
polars-core = "0.35.4"
43+
polars = "0.38"
44+
polars-core = "0.38"
45+
derive_more = "0.99"
4446
pretty_assertions = "1.4.0"
4547
proc-macro2 = "1.0.56"
4648
quote = "1.0.21"
@@ -55,9 +57,14 @@ strum = "0.25"
5557
syn = "2.0.15"
5658
tar = "0.4.38"
5759
tempdir = "0.3.7"
60+
thiserror = "1.0"
5861
tempfile = "3.1.0"
5962
unicase = "2.6.0"
6063
url = "2.1"
6164
uuid = "1.0"
6265
vcpkg = "0.2"
6366
arrow = { version = "52", default-features = false }
67+
rusqlite = "0.31"
68+
arrow_convert = "0.6"
69+
itertools = "0.13"
70+
criterion = { version = "0.5", features = [ "html_reports"] }

crates/duckdb/Cargo.toml

+17-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ description = "Ergonomic wrapper for DuckDB"
1616

1717
[lib]
1818
name = "duckdb"
19+
bench = false
1920

2021
[features]
2122
default = []
@@ -58,9 +59,13 @@ strum = { workspace = true, features = ["derive"] }
5859
r2d2 = { workspace = true, optional = true }
5960
calamine = { workspace = true, optional = true }
6061
num = { workspace = true, features = ["std"], optional = true }
62+
derive_more = { workspace = true }
6163
duckdb-loadable-macros = { workspace = true, optional = true }
6264
polars = { workspace = true, features = ["dtype-full"], optional = true }
63-
num-integer = {version = "0.1.46"}
65+
num-integer = { workspace = true }
66+
thiserror = { workspace = true }
67+
arrow_convert = { workspace = true }
68+
itertools = { workspace = true }
6469

6570
[dev-dependencies]
6671
doc-comment = { workspace = true }
@@ -73,13 +78,13 @@ rand = { workspace = true }
7378
tempdir = { workspace = true }
7479
polars-core = { workspace = true }
7580
pretty_assertions = { workspace = true }
76-
# criterion = "0.3"
81+
rusqlite = { workspace = true }
82+
criterion = { workspace = true }
7783

7884
# [[bench]]
7985
# name = "data_types"
8086
# harness = false
8187

82-
8388
[package.metadata.docs.rs]
8489
features = []
8590
all-features = false
@@ -94,3 +99,12 @@ all-features = false
9499
name = "hello-ext"
95100
crate-type = ["cdylib"]
96101
required-features = ["vtab-loadable"]
102+
103+
[[example]]
104+
name = "appender"
105+
crate-type = ["cdylib"]
106+
required-features = ["appender-arrow"]
107+
108+
[[bench]]
109+
name = "issue-282"
110+
harness = false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
db.*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# SQLite
4+
sqlite3 data/db.sqlite <<EOF
5+
CREATE TABLE IF NOT EXISTS income (
6+
id INTEGER,
7+
created_at INTEGER,
8+
amount REAL,
9+
category_id INTEGER,
10+
wallet_id INTEGER,
11+
meta TEXT
12+
);
13+
.mode csv
14+
.import output.csv income
15+
EOF
16+
17+
# DuckDB
18+
echo "CREATE TABLE income (id INTEGER, created_at INTEGER, amount REAL, category_id INTEGER, wallet_id INTEGER, meta TEXT);" | duckdb data/db.duckdb
19+
echo "COPY income FROM 'output.csv' (HEADER);" | duckdb data/db.duckdb
+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//! ensure that the databases are generated using the `generate-database.sh` utility
2+
use arrow_convert::{ArrowDeserialize, ArrowField, ArrowSerialize};
3+
use criterion::{criterion_group, criterion_main, Criterion};
4+
5+
pub fn sqlite_db() -> rusqlite::Connection {
6+
let db_path = concat!(env!("CARGO_MANIFEST_DIR"), "/benches/issue-282/data/db.sqlite");
7+
rusqlite::Connection::open(db_path).unwrap()
8+
}
9+
10+
pub fn duck_db() -> duckdb::Connection {
11+
let db_path = concat!(env!("CARGO_MANIFEST_DIR"), "/benches/issue-282/data/db.duckdb");
12+
duckdb::Connection::open(db_path).unwrap()
13+
}
14+
15+
#[derive(Debug, ArrowField, ArrowSerialize, ArrowDeserialize)]
16+
struct Income {
17+
created_at: Option<i32>,
18+
amount: Option<f32>,
19+
category_id: i32,
20+
wallet_id: Option<i32>,
21+
meta: Option<String>,
22+
}
23+
24+
impl Income {
25+
fn select_duckdb_arrow(
26+
conn: &duckdb::Connection,
27+
start: u32,
28+
end: u32,
29+
) -> Result<Vec<Self>, Box<dyn std::error::Error>> {
30+
let sql = format!(
31+
"SELECT created_at, amount, category_id, wallet_id, meta \
32+
FROM 'income' \
33+
WHERE created_at >= {} AND created_at <= {}",
34+
start, end
35+
);
36+
let mut stmt = conn.prepare_cached(&sql)?;
37+
let result = stmt.query_arrow_deserialized::<Income>([])?;
38+
Ok(result)
39+
}
40+
41+
fn select_duckdb(conn: &duckdb::Connection, start: u32, end: u32) -> Result<Vec<Self>, Box<dyn std::error::Error>> {
42+
let mut arr = Vec::new();
43+
let sql = format!(
44+
"SELECT created_at, amount, category_id, wallet_id, meta \
45+
FROM 'income' \
46+
WHERE created_at >= {} AND created_at <= {}",
47+
start, end
48+
);
49+
let mut stmt = conn.prepare_cached(&sql)?;
50+
let result_iter = stmt.query_map([], |row| {
51+
Ok(Self {
52+
created_at: row.get(0)?,
53+
amount: row.get(1)?,
54+
category_id: row.get(2)?,
55+
wallet_id: row.get(3)?,
56+
meta: row.get(4)?,
57+
})
58+
})?;
59+
for result in result_iter {
60+
arr.push(result?);
61+
}
62+
Ok(arr)
63+
}
64+
65+
fn select_sqlite(
66+
conn: &rusqlite::Connection,
67+
start: u32,
68+
end: u32,
69+
) -> Result<Vec<Self>, Box<dyn std::error::Error>> {
70+
let mut arr = Vec::new();
71+
let sql = format!(
72+
"SELECT created_at, amount, category_id, wallet_id, meta \
73+
FROM 'income' \
74+
WHERE created_at >= {} AND created_at <= {}",
75+
start, end
76+
);
77+
let mut stmt = conn.prepare(&sql)?;
78+
let result_iter = stmt.query_map([], |row| {
79+
Ok(Self {
80+
created_at: row.get(0)?,
81+
amount: row.get(1)?,
82+
category_id: row.get(2)?,
83+
wallet_id: row.get(3)?,
84+
meta: row.get(4)?,
85+
})
86+
})?;
87+
for result in result_iter {
88+
arr.push(result?);
89+
}
90+
Ok(arr)
91+
}
92+
}
93+
94+
fn bench_sqlite(c: &mut Criterion) {
95+
let sqlite_conn = sqlite_db();
96+
c.bench_function("sqlite_test", |b| {
97+
b.iter(|| {
98+
let out = Income::select_sqlite(&sqlite_conn, 1709292049, 1711375239).unwrap();
99+
out.len()
100+
})
101+
});
102+
}
103+
104+
fn bench_duckdb(c: &mut Criterion) {
105+
let duckdb_conn = duck_db();
106+
c.bench_function("duckdb_test", |b| {
107+
b.iter(|| {
108+
let out = Income::select_duckdb(&duckdb_conn, 1709292049, 1711375239).unwrap();
109+
out.len()
110+
})
111+
});
112+
}
113+
114+
fn bench_duckdb_arrow(c: &mut Criterion) {
115+
let duckdb_conn = duck_db();
116+
c.bench_function("duckdb_test_arrow", |b| {
117+
b.iter(|| {
118+
let out = Income::select_duckdb_arrow(&duckdb_conn, 1709292049, 1711375239).unwrap();
119+
out.len()
120+
})
121+
});
122+
}
123+
124+
// criterion_group!(benches, bench_duckdb_arrow);
125+
criterion_group!(benches, bench_sqlite, bench_duckdb, bench_duckdb_arrow);
126+
criterion_main!(benches);

0 commit comments

Comments
 (0)