use spg_engine::{Engine, QueryResult};
fn text_of(e: &mut Engine, sql: &str) -> String {
match e.execute(sql).unwrap() {
QueryResult::Rows { rows, .. } => spg_engine::eval::value_to_text(&rows[0].values[0]),
other => panic!("{sql}: {other:?}"),
}
}
fn row_of(e: &mut Engine, sql: &str) -> Vec<String> {
match e.execute(sql).unwrap() {
QueryResult::Rows { rows, .. } => rows[0]
.values
.iter()
.map(spg_engine::eval::value_to_text)
.collect(),
other => panic!("{sql}: {other:?}"),
}
}
#[test]
fn enum_first_last_range() {
let mut e = Engine::new();
e.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')")
.unwrap();
assert_eq!(
row_of(
&mut e,
"SELECT enum_first(NULL::mood), enum_last(NULL::mood)"
),
vec!["sad", "happy"]
);
assert_eq!(
text_of(&mut e, "SELECT enum_range(NULL::mood)"),
"{sad,ok,happy}"
);
assert_eq!(
text_of(&mut e, "SELECT enum_range('ok'::mood, NULL)"),
"{ok,happy}"
);
assert_eq!(
text_of(&mut e, "SELECT enum_range(NULL, 'ok'::mood)"),
"{sad,ok}"
);
}
#[test]
fn enum_range_sees_add_value_before() {
let mut e = Engine::new();
e.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')")
.unwrap();
e.execute("ALTER TYPE mood ADD VALUE 'meh' BEFORE 'ok'")
.unwrap();
assert_eq!(
text_of(&mut e, "SELECT enum_range(NULL::mood)"),
"{sad,meh,ok,happy}"
);
assert_eq!(text_of(&mut e, "SELECT enum_first(NULL::mood)"), "sad");
}
#[test]
fn enum_introspection_from_column_reference() {
let mut e = Engine::new();
e.execute("CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')")
.unwrap();
e.execute("CREATE TABLE p (id INT NOT NULL, m mood)")
.unwrap();
e.execute("INSERT INTO p VALUES (1, 'ok')").unwrap();
assert_eq!(text_of(&mut e, "SELECT enum_last(m) FROM p"), "happy");
}
#[test]
fn degree_trig_exact_at_standard_angles() {
let mut e = Engine::new();
assert_eq!(
row_of(&mut e, "SELECT sind(30), cosd(60), tand(45), cotd(45)"),
vec!["0.5", "0.5", "1", "1"]
);
assert_eq!(
row_of(
&mut e,
"SELECT sind(90), cosd(0), sind(150), cosd(120), tand(135)"
),
vec!["1", "1", "0.5", "-0.5", "-1"]
);
assert_eq!(
row_of(
&mut e,
"SELECT asind(0.5), acosd(0.5), atand(1), asind(-0.5), acosd(-1)"
),
vec!["30", "60", "45", "-30", "180"]
);
assert_eq!(
row_of(&mut e, "SELECT cotd(90), tand(90), cotd(0)"),
vec!["0", "Infinity", "Infinity"]
);
}
#[test]
fn inverse_trig_domain_error() {
let mut e = Engine::new();
let err = e.execute("SELECT asind(2)").unwrap_err();
assert!(
format!("{err}").contains("input is out of range"),
"PG's 22003 message, got: {err}"
);
assert_eq!(text_of(&mut e, "SELECT asind('NaN'::float8)"), "NaN");
}