use std::borrow::Cow;
use vibesql_types::SqlValue;
pub fn normalize_for_comparison(value: &SqlValue) -> SqlValue {
match value {
SqlValue::Integer(i) => SqlValue::Double(*i as f64),
SqlValue::Smallint(i) => SqlValue::Double(*i as f64),
SqlValue::Bigint(i) => SqlValue::Double(*i as f64),
SqlValue::Unsigned(u) => SqlValue::Double(*u as f64),
SqlValue::Float(f) => SqlValue::Double(*f as f64),
SqlValue::Real(r) => SqlValue::Double(*r as f64),
SqlValue::Double(d) => SqlValue::Double(*d),
SqlValue::Numeric(n) => SqlValue::Double(*n),
SqlValue::Varchar(s) | SqlValue::Character(s) => {
if let Ok(n) = s.trim().parse::<f64>() {
SqlValue::Double(n)
} else {
value.clone()
}
}
other => other.clone(),
}
}
#[inline]
pub fn normalize_cow(value: &SqlValue) -> Cow<'_, SqlValue> {
match value {
SqlValue::Integer(i) => Cow::Owned(SqlValue::Double(*i as f64)),
SqlValue::Smallint(i) => Cow::Owned(SqlValue::Double(*i as f64)),
SqlValue::Bigint(i) => Cow::Owned(SqlValue::Double(*i as f64)),
SqlValue::Unsigned(u) => Cow::Owned(SqlValue::Double(*u as f64)),
SqlValue::Float(f) => Cow::Owned(SqlValue::Double(*f as f64)),
SqlValue::Real(r) => Cow::Owned(SqlValue::Double(*r as f64)),
SqlValue::Double(d) => Cow::Owned(SqlValue::Double(*d)),
SqlValue::Numeric(n) => Cow::Owned(SqlValue::Double(*n)),
SqlValue::Varchar(s) | SqlValue::Character(s) => {
if let Ok(n) = s.trim().parse::<f64>() {
Cow::Owned(SqlValue::Double(n))
} else {
Cow::Borrowed(value)
}
}
other => Cow::Borrowed(other),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_normalize_for_comparison_numeric_types() {
assert_eq!(normalize_for_comparison(&SqlValue::Integer(42)), SqlValue::Double(42.0));
assert_eq!(normalize_for_comparison(&SqlValue::Smallint(10)), SqlValue::Double(10.0));
assert_eq!(normalize_for_comparison(&SqlValue::Bigint(1000)), SqlValue::Double(1000.0));
assert_eq!(normalize_for_comparison(&SqlValue::Unsigned(99)), SqlValue::Double(99.0));
assert_eq!(
normalize_for_comparison(&SqlValue::Float(3.14)),
SqlValue::Double(3.14f32 as f64)
);
assert_eq!(normalize_for_comparison(&SqlValue::Real(2.5)), SqlValue::Double(2.5));
assert_eq!(normalize_for_comparison(&SqlValue::Numeric(123.45)), SqlValue::Double(123.45));
assert_eq!(normalize_for_comparison(&SqlValue::Double(7.89)), SqlValue::Double(7.89));
}
#[test]
fn test_normalize_for_comparison_non_numeric() {
let text_val = SqlValue::Varchar(arcstr::ArcStr::from("test"));
assert_eq!(normalize_for_comparison(&text_val), text_val);
let null_val = SqlValue::Null;
assert_eq!(normalize_for_comparison(&null_val), null_val);
let bool_val = SqlValue::Boolean(true);
assert_eq!(normalize_for_comparison(&bool_val), bool_val);
}
}