use rudb::Database;
const SQL: &str = include_str!("../testdata/clickbench.sql");
const GAPS: &[(&str, &str)] = &[];
fn statements() -> Vec<(String, String)> {
let mut found = Vec::new();
let mut name = String::from("hits");
let mut sql = String::new();
for line in SQL.lines() {
let line = line.trim();
if let Some(rest) = line.strip_prefix("--") {
let rest = rest.trim();
if rest.starts_with('q') && rest[1..].chars().all(|c| c.is_ascii_digit()) {
name = rest.to_string();
}
continue;
}
if line.is_empty() {
continue;
}
if !sql.is_empty() {
sql.push(' ');
}
sql.push_str(line);
if let Some(statement) = sql.strip_suffix(';') {
found.push((name.clone(), statement.to_string()));
sql.clear();
}
}
assert!(sql.is_empty(), "a statement in the file does not end with a semicolon");
found
}
fn with_hits() -> Database {
let database = Database::new();
let (name, ddl) = statements().remove(0);
assert_eq!(name, "hits", "the first statement in the file is not the DDL");
database.execute(&ddl).expect("the official hits DDL");
database
}
#[test]
fn the_file_holds_the_whole_benchmark() {
let found = statements();
assert_eq!(found.len(), 44, "the DDL and forty three queries");
let names: Vec<&str> = found[1..].iter().map(|(name, _)| name.as_str()).collect();
let wanted: Vec<String> = (1..=43).map(|at| format!("q{at}")).collect();
assert_eq!(names, wanted, "the queries are not q1 to q43 in order");
}
#[test]
fn the_official_ddl_creates_the_table() {
let database = with_hits();
assert_eq!(database.table_len("hits").expect("hits exists"), 0);
}
#[test]
fn every_query_plans_or_is_a_known_gap() {
let database = with_hits();
let mut failed = Vec::new();
for (name, sql) in statements().into_iter().skip(1) {
if let Err(error) = database.plan(&sql) {
failed.push((name, error.message().to_string()));
}
}
let names: Vec<&str> = failed.iter().map(|(name, _)| name.as_str()).collect();
let known: Vec<&str> = GAPS.iter().map(|(name, _)| *name).collect();
assert_eq!(
names,
known,
"the queries that do not plan are not the ones listed as gaps, which failed like this: {}",
failed
.iter()
.map(|(name, why)| format!("{name}: {why}"))
.collect::<Vec<String>>()
.join(", ")
);
}