use spg_engine::{Engine, QueryResult};
use spg_storage::Value;
fn row(e: &mut Engine, sql: &str) -> Vec<Value<'static>> {
match e.execute(sql).unwrap_or_else(|err| panic!("{sql}: {err}")) {
QueryResult::Rows { rows, .. } => rows
.first()
.map(|r| r.values.iter().cloned().map(Value::into_owned).collect())
.unwrap_or_default(),
other => panic!("`{sql}` did not return rows: {other:?}"),
}
}
fn err(e: &mut Engine, sql: &str) -> String {
match e.execute(sql) {
Ok(v) => panic!("{sql}: expected an error, got {v:?}"),
Err(x) => format!("{x}"),
}
}
fn mysql() -> Engine {
let mut e = Engine::new();
e.execute("SET sql_mode='STRICT_TRANS_TABLES'").unwrap();
e
}
#[test]
fn mysql_length_counts_bytes() {
let mut e = mysql();
assert_eq!(
row(&mut e, "SELECT LENGTH('héllo'), CHAR_LENGTH('héllo')"),
vec![Value::Int(6), Value::Int(5)],
);
assert_eq!(
row(&mut e, "SELECT LENGTH('日本語'), CHAR_LENGTH('日本語')"),
vec![Value::Int(9), Value::Int(3)],
);
assert_eq!(row(&mut e, "SELECT LENGTH('abc')"), vec![Value::Int(3)]);
assert_eq!(row(&mut e, "SELECT LENGTH('')"), vec![Value::Int(0)]);
assert_eq!(row(&mut e, "SELECT LENGTH(NULL)"), vec![Value::Null]);
}
#[test]
fn pg_length_counts_characters() {
let mut e = Engine::new();
assert_eq!(
row(&mut e, "SELECT length('héllo'), char_length('héllo')"),
vec![Value::Int(5), Value::Int(5)],
);
assert_eq!(row(&mut e, "SELECT length('日本語')"), vec![Value::Int(3)]);
}
#[test]
fn octet_and_bit_length_are_the_same_either_way() {
for mut e in [Engine::new(), mysql()] {
assert_eq!(
row(&mut e, "SELECT OCTET_LENGTH('héllo'), BIT_LENGTH('héllo')"),
vec![Value::Int(6), Value::Int(48)],
);
assert_eq!(
row(&mut e, "SELECT CHARACTER_LENGTH('héllo')"),
vec![Value::Int(5)],
);
}
}
#[test]
fn a_number_argument_splits_by_dialect() {
let mut m = mysql();
assert_eq!(row(&mut m, "SELECT LENGTH(12345)"), vec![Value::Int(5)]);
assert_eq!(row(&mut m, "SELECT LENGTH(1.50)"), vec![Value::Int(4)]);
let mut p = Engine::new();
assert_eq!(
err(&mut p, "SELECT length(12345)"),
"eval: type mismatch: function length(integer) does not exist",
);
}