use vibesql_types::SqlValue;
use super::coerce_numeric_values;
use crate::errors::ExecutorError;
pub struct Multiplication;
impl Multiplication {
#[inline]
pub fn multiply(left: &SqlValue, right: &SqlValue) -> Result<SqlValue, ExecutorError> {
use SqlValue::*;
if matches!(left, Null) || matches!(right, Null) {
return Ok(Null);
}
if let (Integer(a), Integer(b)) = (left, right) {
return Ok(a
.checked_mul(*b)
.map(Integer)
.unwrap_or_else(|| Double(*a as f64 * *b as f64)));
}
match coerce_numeric_values(left, right, "*")? {
super::CoercedValues::ExactNumeric(a, b) => Ok(a
.checked_mul(b)
.map(Integer)
.unwrap_or_else(|| super::nan_to_null(Double(a as f64 * b as f64)))),
super::CoercedValues::ApproximateNumeric(a, b) => {
Ok(super::nan_to_null(Float((a * b) as f32)))
}
super::CoercedValues::Numeric(a, b) => Ok(super::nan_to_null(Numeric(a * b))),
}
}
}