#![cfg(feature = "std")]
use graphitesql::{Connection, Value};
fn ints(conn: &Connection, sql: &str) -> Vec<i64> {
conn.query(sql)
.unwrap()
.rows
.into_iter()
.map(|r| match r[0] {
Value::Integer(i) => i,
ref other => panic!("non-integer: {other:?}"),
})
.collect()
}
fn setup() -> Connection {
let mut conn = Connection::open_memory().unwrap();
conn.execute("CREATE TABLE t(v INTEGER)").unwrap();
conn.execute("INSERT INTO t VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)")
.unwrap();
conn
}
#[test]
fn limit_with_pure_function() {
let conn = setup();
assert_eq!(
ints(&conn, "SELECT v FROM t ORDER BY v LIMIT abs(-3)"),
[1, 2, 3]
);
assert_eq!(
ints(&conn, "SELECT v FROM t ORDER BY v LIMIT round(2.9)"),
[1, 2, 3]
);
assert_eq!(
ints(&conn, "SELECT v FROM t ORDER BY v LIMIT length('abcd')"),
[1, 2, 3, 4]
);
}
#[test]
fn offset_with_pure_function() {
let conn = setup();
assert_eq!(
ints(
&conn,
"SELECT v FROM t ORDER BY v LIMIT length('abcd') OFFSET length('ab')"
),
[3, 4, 5, 6]
);
}
#[test]
fn mixed_arithmetic_and_function() {
let conn = setup();
assert_eq!(
ints(
&conn,
"SELECT v FROM t ORDER BY v LIMIT (2*2)+coalesce(NULL,1)"
),
[1, 2, 3, 4, 5]
);
}
#[test]
fn non_foldable_limit_still_correct() {
let conn = setup();
let err = conn
.query("SELECT v FROM t LIMIT datetime('now')")
.unwrap_err();
assert!(
err.to_string().contains("datatype mismatch"),
"unexpected: {err}"
);
}
#[test]
fn limit_via_vdbe_matches_tree_walker() {
let conn = setup();
let via_vdbe = conn
.query("SELECT v FROM t ORDER BY v LIMIT abs(-4)")
.unwrap();
let via_tree = conn
.query_vdbe("SELECT v FROM t ORDER BY v LIMIT abs(-4)")
.unwrap();
assert_eq!(via_vdbe.rows, via_tree.rows);
assert_eq!(via_vdbe.rows.len(), 4);
}