use spg_engine::{Engine, QueryResult};
fn count(e: &mut Engine, sql: &str) -> String {
match e.execute(sql) {
Ok(QueryResult::Rows { rows, .. }) => format!("{}", rows.len()),
Ok(o) => format!("{o:?}"),
Err(err) => format!("ERR {err:?}"),
}
}
fn main() {
for n in [5usize, 200, 5000] {
let mut e = Engine::new();
e.execute("SET sql_mode = 'STRICT_TRANS_TABLES'")
.expect("dialect");
e.execute("CREATE TABLE l (id INT, s VARCHAR(20))").unwrap();
e.execute("CREATE TABLE r (id INT, s VARCHAR(20))").unwrap();
e.execute(&format!(
"INSERT INTO l SELECT g, lower(chr(97 + (g % 20))) FROM generate_series(1,{n}) g"
))
.unwrap();
e.execute(&format!(
"INSERT INTO r SELECT g, upper(chr(97 + (g % 20))) FROM generate_series(1,{n}) g"
))
.unwrap();
let joined = count(&mut e, "SELECT l.id FROM l JOIN r ON l.s = r.s");
let crossw = count(&mut e, "SELECT l.id FROM l, r WHERE l.s = r.s");
let subq = count(&mut e, "SELECT id FROM l WHERE s IN (SELECT s FROM r)");
let exists = count(
&mut e,
"SELECT id FROM l WHERE EXISTS (SELECT 1 FROM r WHERE r.s = l.s)",
);
let wherecmp = count(&mut e, "SELECT id FROM l WHERE s = 'A'");
println!(
"rows={n:<5} JOIN..ON -> {joined:<8} cross+WHERE -> {crossw:<8} \
IN(subq) -> {subq:<8} EXISTS -> {exists:<8} control WHERE s='A' -> {wherecmp}"
);
}
}