use spg_engine::{Engine, QueryResult};
fn one(e: &mut Engine, sql: &str) -> spg_storage::Value<'static> {
let r = e
.execute(sql)
.unwrap_or_else(|err| panic!("{sql}: {err:?}"));
let QueryResult::Rows { rows, .. } = r else {
panic!("expected Rows");
};
rows[0].values[0].clone()
}
fn text(e: &mut Engine, sql: &str) -> String {
match one(e, sql) {
spg_storage::Value::Text(s) => s.to_string(),
v => panic!("{sql}: expected Text, got {v:?}"),
}
}
#[test]
fn bare_paren_row_constructor_is_a_value() {
let mut e = Engine::new();
assert_eq!(text(&mut e, "SELECT (1,'a')::text"), "(1,a)");
assert_eq!(text(&mut e, "SELECT (1,2,3)::text"), "(1,2,3)");
assert_eq!(
text(&mut e, "SELECT row_to_json((1,'a'))::text"),
"{\"f1\":1,\"f2\":\"a\"}"
);
assert_eq!(one(&mut e, "SELECT (1,'a').f1"), spg_storage::Value::Int(1));
assert!(survives(&mut e, "(1,2) = (1,2)"));
assert!(survives(&mut e, "(1,2) IN ((1,2),(3,4))"));
assert!(survives(&mut e, "(1,2) < (1,3)"));
assert!(!survives(&mut e, "(1,2) IS NULL"));
assert_eq!(one(&mut e, "SELECT (5)"), spg_storage::Value::Int(5));
assert_eq!(one(&mut e, "SELECT (1+2)*3"), spg_storage::Value::Int(9));
}
fn survives(e: &mut Engine, cond: &str) -> bool {
let sql = alloc_sql(cond);
let r = e
.execute(&sql)
.unwrap_or_else(|err| panic!("{sql}: {err:?}"));
let QueryResult::Rows { rows, .. } = r else {
panic!("expected Rows");
};
!rows.is_empty()
}
fn alloc_sql(cond: &str) -> String {
format!("SELECT 1 WHERE {cond}")
}
#[test]
fn bare_row_renders_record_text() {
let mut e = Engine::new();
let spg_storage::Value::Text(s) = one(&mut e, "SELECT (ROW(1, 'a'))::text") else {
panic!("expected Text");
};
assert_eq!(s.as_ref(), "(1,a)");
let spg_storage::Value::Text(s) = one(&mut e, "SELECT (ROW(1, NULL, 'x,y'))::text") else {
panic!("expected Text");
};
assert_eq!(s.as_ref(), "(1,,\"x,y\")");
let spg_storage::Value::Text(s) = one(&mut e, "SELECT (ROW(7))::text") else {
panic!("expected Text");
};
assert_eq!(s.as_ref(), "(7)");
assert!(matches!(
one(&mut e, "SELECT ROW(1, 'a')"),
spg_storage::Value::Composite(_)
));
}
#[test]
fn row_keyword_comparisons() {
let mut e = Engine::new();
assert!(survives(&mut e, "ROW(1, 2) = ROW(1, 2)"));
assert!(!survives(&mut e, "ROW(1, 2) = ROW(1, 3)"));
assert!(survives(&mut e, "ROW(1, 2) < ROW(1, 3)"));
assert!(survives(&mut e, "ROW(1, 2) < (2, 0)"));
assert!(survives(&mut e, "ROW(1, 2) IN ((3, 4), ROW(1, 2))"));
assert!(!survives(&mut e, "ROW(1, 2) NOT IN ((1, 2))"));
assert!(e.execute("SELECT 1 WHERE ROW(1, 2) = ROW(1)").is_err());
}