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()
}
#[test]
fn binary_form() {
let mut e = Engine::new();
let v = one(&mut e, "SELECT B'1010'");
let spg_storage::Value::BitString { nbits, bytes } = v else {
panic!("expected BitString, got {v:?}");
};
assert_eq!(nbits, 4);
assert_eq!(bytes[0] >> 4, 0b1010);
assert!(e.execute("SELECT B'102'").is_err());
}
#[test]
fn hex_form_expands_to_bits() {
let mut e = Engine::new();
let v = one(&mut e, "SELECT X'1F'");
let spg_storage::Value::BitString { nbits, bytes } = v else {
panic!("expected BitString, got {v:?}");
};
assert_eq!(nbits, 8);
assert_eq!(bytes[0], 0x1F);
let v = one(&mut e, "SELECT x'a'");
let spg_storage::Value::BitString { nbits, .. } = v else {
panic!("expected BitString, got {v:?}");
};
assert_eq!(nbits, 4);
assert!(e.execute("SELECT X'G1'").is_err());
}
#[test]
fn bit_concat_yields_bitstring() {
let mut e = Engine::new();
let txt = |e: &mut Engine, sql: &str| -> String {
match one(e, sql) {
spg_storage::Value::Text(s) => s.to_string(),
o => panic!("{sql}: expected Text, got {o:?}"),
}
};
assert!(matches!(
one(&mut e, "SELECT B'10' || B'11'"),
spg_storage::Value::BitString { .. }
));
assert_eq!(txt(&mut e, "SELECT (B'10' || B'11')::text"), "1011");
assert_eq!(txt(&mut e, "SELECT (B'1010' || B'0101')::text"), "10100101");
assert_eq!(txt(&mut e, "SELECT (B'101' || B'1')::text"), "1011");
assert_eq!(
txt(&mut e, "SELECT (B'11111111' || B'0000')::text"),
"111111110000"
);
assert_eq!(txt(&mut e, "SELECT (B'' || B'11')::text"), "11");
assert_eq!(
one(&mut e, "SELECT (B'101' || B'1') = B'1011'"),
spg_storage::Value::Bool(true)
);
}
#[test]
fn pg_typeof_bit_reports_bit_varying_not_unknown() {
let mut e = Engine::new();
let t = |e: &mut Engine, sql: &str| -> String {
match one(e, sql) {
spg_storage::Value::Text(s) => s.to_string(),
o => panic!("{o:?}"),
}
};
assert_eq!(
t(&mut e, "SELECT pg_typeof('101'::varbit)::text"),
"bit varying"
);
assert_eq!(
t(&mut e, "SELECT pg_typeof(B'10' || B'11')::text"),
"bit varying"
);
assert_eq!(t(&mut e, "SELECT pg_typeof(B'101')::text"), "bit varying");
}
#[test]
fn bit_concat_projected_column_type_is_bit_varying() {
use spg_storage::DataType;
let mut e = Engine::new();
let QueryResult::Rows { columns, .. } = e.execute("SELECT B'10' || B'11'").unwrap() else {
panic!("expected Rows");
};
assert_eq!(
columns[0].ty,
DataType::BitVarying(0),
"bit concat projects a bit varying column, not {:?}",
columns[0].ty
);
}