use spg_engine::{Engine, QueryResult};
use spg_storage::Value;
fn rows(r: QueryResult) -> Vec<Vec<Value<'static>>> {
match r {
QueryResult::Rows { rows, .. } => rows.into_iter().map(|r| r.values).collect(),
_ => panic!("expected rows"),
}
}
fn setup(e: &mut Engine) {
e.execute(
"CREATE TABLE orders (id INT NOT NULL, customer_id INT NOT NULL, amount INT NOT NULL)",
)
.unwrap();
e.execute("CREATE TABLE customers (id INT NOT NULL, name TEXT NOT NULL)")
.unwrap();
e.execute(
"INSERT INTO orders VALUES \
(1, 1, 100), (2, 1, 200), (3, 2, 50), (4, 2, 80), (5, 2, 30)",
)
.unwrap();
e.execute("INSERT INTO customers VALUES (1, 'alice'), (2, 'bob')")
.unwrap();
}
#[test]
fn join_with_window_returns_correct_rows() {
let mut e = Engine::new();
setup(&mut e);
let r = rows(
e.execute(
"SELECT c.name, row_number() OVER (PARTITION BY c.id ORDER BY o.amount) AS rn \
FROM orders o JOIN customers c ON c.id = o.customer_id \
ORDER BY c.id, rn",
)
.unwrap(),
);
assert_eq!(r.len(), 5);
assert_eq!(r[0][0], Value::text("alice"));
assert_eq!(r[0][1], Value::BigInt(1));
assert_eq!(r[1][0], Value::text("alice"));
assert_eq!(r[1][1], Value::BigInt(2));
assert_eq!(r[2][0], Value::text("bob"));
assert_eq!(r[2][1], Value::BigInt(1));
assert_eq!(r[3][0], Value::text("bob"));
assert_eq!(r[3][1], Value::BigInt(2));
assert_eq!(r[4][0], Value::text("bob"));
assert_eq!(r[4][1], Value::BigInt(3));
}
#[test]
fn window_in_cte_subquery_workaround() {
let mut e = Engine::new();
setup(&mut e);
let r = e.execute(
"WITH joined AS (\
SELECT c.name AS cname, o.amount AS amt \
FROM orders o JOIN customers c ON c.id = o.customer_id\
) \
SELECT cname, amt, row_number() OVER (PARTITION BY cname ORDER BY amt) AS rn \
FROM joined",
);
match r {
Ok(QueryResult::Rows { rows: out, .. }) => {
assert_eq!(out.len(), 5);
}
Err(e) => {
eprintln!("CTE-workaround result: {e:?}");
}
_ => panic!(),
}
}
#[test]
fn bare_window_over_single_table_still_works() {
let mut e = Engine::new();
setup(&mut e);
let r = rows(
e.execute("SELECT amount, row_number() OVER (ORDER BY amount) FROM orders")
.unwrap(),
);
assert_eq!(r.len(), 5);
}