#![cfg(feature = "std")]
use std::process::Command;
fn sqlite3_available() -> bool {
Command::new("sqlite3").arg("--version").output().is_ok()
}
fn out(bin: &str, sql: &str) -> String {
let o = Command::new(bin).arg(":memory:").arg(sql).output().unwrap();
String::from_utf8_lossy(&o.stdout).into_owned()
}
#[test]
fn compensated_and_exact_integer_sum() {
if !sqlite3_available() {
eprintln!("sqlite3 CLI not found; skipping");
return;
}
let g = env!("CARGO_BIN_EXE_graphitesql");
let cases = [
"CREATE TABLE t(x);INSERT INTO t VALUES(1e308),(3),(-1e308);\
SELECT sum(x),total(x),avg(x) FROM t;",
"CREATE TABLE t(x);\
INSERT INTO t VALUES(-1),(1),(9223372036854775807),(-9223372036854775808),('2.5');\
SELECT quote(sum(x)),quote(avg(x)) FROM t;",
"CREATE TABLE t(x);\
INSERT INTO t VALUES(9223372036854775807),(-9223372036854775808),(0.5);\
SELECT quote(total(x)) FROM t;",
"CREATE TABLE t(x);\
INSERT INTO t VALUES(9223372036854775807),(9223372036854775807),(1.5);\
SELECT quote(sum(x)) FROM t;",
"CREATE TABLE t(x);INSERT INTO t VALUES(1),(2),(3);\
SELECT sum(x),typeof(sum(x)),total(x),avg(x) FROM t;",
"CREATE TABLE t(x);INSERT INTO t VALUES('5'),(2.5),(3),('abc'),(NULL);\
SELECT quote(sum(x)),quote(avg(x)),quote(total(x)) FROM t;",
"CREATE TABLE t(x);INSERT INTO t VALUES(NULL),(NULL);\
SELECT quote(sum(x)),quote(avg(x)),quote(total(x)) FROM t;",
];
for sql in cases {
assert_eq!(out("sqlite3", sql), out(g, sql), "for `{sql}`");
}
let ov =
"CREATE TABLE t(x);INSERT INTO t VALUES(9223372036854775807),(1);SELECT sum(x) FROM t;";
assert!(out("sqlite3", ov).is_empty());
let e = Command::new(g).arg(":memory:").arg(ov).output().unwrap();
assert!(
String::from_utf8_lossy(&e.stderr).contains("integer overflow"),
"graphite should report integer overflow"
);
}