use spg_engine::{Engine, QueryResult};
use spg_storage::Value;
fn seed() -> Engine {
let mut e = Engine::new();
e.execute("CREATE TABLE t (g INT, k INT, label TEXT)")
.unwrap();
e.execute(
"INSERT INTO t VALUES \
(1,3,'c'),(1,1,'a'),(1,2,'b'), \
(2,5,'x'),(2,5,'y'),(2,5,'z'), \
(3,NULL,'n'),(3,2,'p'), \
(4,9,NULL),(4,1,'q')",
)
.unwrap();
e
}
fn col1_by_group(r: QueryResult) -> Vec<Value> {
match r {
QueryResult::Rows { rows, .. } => rows
.into_iter()
.map(|row| row.values.into_iter().nth(1).unwrap())
.collect(),
other => panic!("expected Rows, got {other:?}"),
}
}
fn t(s: &str) -> Value {
Value::Text(s.to_string())
}
#[test]
fn argmax_desc_nulls_last() {
let mut e = seed();
let r = e
.execute(
"SELECT g, (array_agg(label ORDER BY k DESC NULLS LAST))[1] \
FROM t GROUP BY g ORDER BY g",
)
.unwrap();
assert_eq!(col1_by_group(r), vec![t("c"), t("x"), t("p"), Value::Null]);
}
#[test]
fn argmin_asc() {
let mut e = seed();
let r = e
.execute("SELECT g, (array_agg(label ORDER BY k ASC))[1] FROM t GROUP BY g ORDER BY g")
.unwrap();
assert_eq!(col1_by_group(r), vec![t("a"), t("x"), t("p"), t("q")]);
}
#[test]
fn argmax_desc_nulls_first_picks_the_null_keyed_row() {
let mut e = seed();
let r = e
.execute(
"SELECT g, (array_agg(label ORDER BY k DESC NULLS FIRST))[1] \
FROM t GROUP BY g ORDER BY g",
)
.unwrap();
assert_eq!(col1_by_group(r), vec![t("c"), t("x"), t("n"), Value::Null]);
}
#[test]
fn empty_group_is_null() {
let mut e = seed();
let r = e
.execute(
"SELECT g, (array_agg(label ORDER BY k DESC))[1] \
FROM t WHERE g = 99 GROUP BY g",
)
.unwrap();
match r {
QueryResult::Rows { rows, .. } => assert!(rows.is_empty()),
other => panic!("{other:?}"),
}
}
#[test]
fn coalesced_argmax_matches_inbox_shape() {
let mut e = seed();
let r = e
.execute(
"SELECT g, COALESCE((array_agg(label ORDER BY k DESC NULLS LAST))[1], 'def') \
FROM t GROUP BY g ORDER BY g",
)
.unwrap();
assert_eq!(col1_by_group(r), vec![t("c"), t("x"), t("p"), t("def")]);
}