use crate::errors::ExecutorError;
pub(super) fn coalesce(
args: &[vibesql_types::SqlValue],
) -> Result<vibesql_types::SqlValue, ExecutorError> {
if args.len() < 2 {
return Err(ExecutorError::WrongNumberOfArguments {
function_name: "coalesce".to_string(),
});
}
for val in args {
if !matches!(val, vibesql_types::SqlValue::Null) {
return Ok(val.clone());
}
}
Ok(vibesql_types::SqlValue::Null)
}
pub(super) fn nullif(
args: &[vibesql_types::SqlValue],
) -> Result<vibesql_types::SqlValue, ExecutorError> {
if args.len() != 2 {
return Err(ExecutorError::UnsupportedFeature(format!(
"NULLIF requires exactly 2 arguments, got {}",
args.len()
)));
}
let val1 = &args[0];
let val2 = &args[1];
if matches!(val1, vibesql_types::SqlValue::Null)
|| matches!(val2, vibesql_types::SqlValue::Null)
{
return Ok(val1.clone());
}
if values_are_equal(val1, val2) {
Ok(vibesql_types::SqlValue::Null)
} else {
Ok(val1.clone())
}
}
fn values_are_equal(left: &vibesql_types::SqlValue, right: &vibesql_types::SqlValue) -> bool {
use vibesql_types::SqlValue::*;
match (left, right) {
(Integer(a), Integer(b)) => a == b,
(Varchar(a), Varchar(b)) => a == b,
(Character(a), Character(b)) => a == b,
(Character(a), Varchar(b)) | (Varchar(a), Character(b)) => a == b,
(Boolean(a), Boolean(b)) => a == b,
_ => false, }
}