use spg_engine::Engine;
#[test]
fn repeat_prepare_returns_cached_plan() {
let mut eng = Engine::new();
eng.execute("CREATE TABLE t1 (id INT, name TEXT)")
.expect("create");
eng.execute("INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c')")
.expect("insert");
assert_eq!(eng.plan_cache().len(), 0, "cache starts empty");
let _stmt1 = eng
.prepare_cached("SELECT * FROM t1 WHERE id = 1")
.expect("first prepare");
assert_eq!(eng.plan_cache().len(), 1, "first prepare populates");
let _stmt2 = eng
.prepare_cached("SELECT * FROM t1 WHERE id = 1")
.expect("second prepare");
assert_eq!(
eng.plan_cache().len(),
1,
"second prepare hits cache, doesn't add a duplicate"
);
let _stmt3 = eng
.prepare_cached("SELECT * FROM t1 WHERE id = 2")
.expect("different sql");
assert_eq!(
eng.plan_cache().len(),
2,
"different SQL string adds a new entry"
);
}
#[test]
fn lru_evicts_oldest_at_cap() {
let mut eng = Engine::new();
eng.execute("CREATE TABLE t1 (id INT)").expect("create");
for i in 0..300_u32 {
let sql = alloc_sql(i);
eng.prepare_cached(&sql).expect("prepare");
}
assert_eq!(
eng.plan_cache().len(),
256,
"cache stays at cap regardless of how many distinct SQLs we prepared"
);
}
fn alloc_sql(i: u32) -> String {
format!("SELECT * FROM t1 WHERE id = {i}")
}
#[test]
fn prepared_plan_runs_correctly_after_cache_hit() {
let mut eng = Engine::new();
eng.execute("CREATE TABLE t1 (id INT, name TEXT)")
.expect("create");
eng.execute("INSERT INTO t1 VALUES (1, 'a'), (2, 'b')")
.expect("insert");
let r1 = eng
.execute("SELECT name FROM t1 WHERE id = 1")
.expect("exec1");
let stmt_a = eng
.prepare_cached("SELECT name FROM t1 WHERE id = 2")
.expect("first prepare");
let stmt_b = eng
.prepare_cached("SELECT name FROM t1 WHERE id = 2")
.expect("second prepare (hit)");
assert_eq!(stmt_a, stmt_b, "cached AST must equal the first parse");
let r2 = eng.execute_prepared(stmt_b, &[]).expect("exec via cached");
match (r1, r2) {
(
spg_engine::QueryResult::Rows { rows: r1_rows, .. },
spg_engine::QueryResult::Rows { rows: r2_rows, .. },
) => {
assert_eq!(r1_rows.len(), 1, "id=1 → one row");
assert_eq!(r2_rows.len(), 1, "id=2 → one row");
}
_ => panic!("expected Rows results from both selects"),
}
}