use crate::errors::ExecutorError;
use crate::evaluator::functions::coercion::coerce_to_string;
pub(in crate::evaluator::functions) fn char_length(
args: &[vibesql_types::SqlValue],
name: &str,
character_unit: &Option<vibesql_ast::CharacterUnit>,
) -> Result<vibesql_types::SqlValue, ExecutorError> {
if args.len() != 1 {
return Err(ExecutorError::UnsupportedFeature(format!(
"{} requires exactly 1 argument, got {}",
name,
args.len()
)));
}
match coerce_to_string(&args[0]) {
None => Ok(vibesql_types::SqlValue::Null),
Some(s) => {
let length = match character_unit {
Some(vibesql_ast::CharacterUnit::Octets) => {
s.len() as i64
}
Some(vibesql_ast::CharacterUnit::Characters) | None => {
s.chars().count() as i64
}
};
Ok(vibesql_types::SqlValue::Integer(length))
}
}
}
pub(in crate::evaluator::functions) fn octet_length(
args: &[vibesql_types::SqlValue],
) -> Result<vibesql_types::SqlValue, ExecutorError> {
if args.len() != 1 {
return Err(ExecutorError::UnsupportedFeature(format!(
"OCTET_LENGTH requires exactly 1 argument, got {}",
args.len()
)));
}
match coerce_to_string(&args[0]) {
None => Ok(vibesql_types::SqlValue::Null),
Some(s) => Ok(vibesql_types::SqlValue::Integer(s.len() as i64)),
}
}
pub(in crate::evaluator::functions) fn length(
args: &[vibesql_types::SqlValue],
) -> Result<vibesql_types::SqlValue, ExecutorError> {
if args.len() != 1 {
return Err(ExecutorError::WrongNumberOfArguments { function_name: "length".to_string() });
}
match &args[0] {
vibesql_types::SqlValue::Null => Ok(vibesql_types::SqlValue::Null),
vibesql_types::SqlValue::Varchar(s) | vibesql_types::SqlValue::Character(s) => {
Ok(vibesql_types::SqlValue::Integer(s.chars().count() as i64))
}
vibesql_types::SqlValue::Integer(n) => {
Ok(vibesql_types::SqlValue::Integer(n.to_string().len() as i64))
}
vibesql_types::SqlValue::Smallint(n) => {
Ok(vibesql_types::SqlValue::Integer(n.to_string().len() as i64))
}
vibesql_types::SqlValue::Bigint(n) => {
Ok(vibesql_types::SqlValue::Integer(n.to_string().len() as i64))
}
vibesql_types::SqlValue::Unsigned(n) => {
Ok(vibesql_types::SqlValue::Integer(n.to_string().len() as i64))
}
vibesql_types::SqlValue::Float(f) => {
Ok(vibesql_types::SqlValue::Integer(f.to_string().len() as i64))
}
vibesql_types::SqlValue::Real(f) => {
Ok(vibesql_types::SqlValue::Integer(f.to_string().len() as i64))
}
vibesql_types::SqlValue::Double(f) => {
Ok(vibesql_types::SqlValue::Integer(f.to_string().len() as i64))
}
vibesql_types::SqlValue::Numeric(f) => {
Ok(vibesql_types::SqlValue::Integer(f.to_string().len() as i64))
}
vibesql_types::SqlValue::Boolean(b) => {
let s = if *b { "1" } else { "0" };
Ok(vibesql_types::SqlValue::Integer(s.len() as i64))
}
vibesql_types::SqlValue::Date(d) => {
Ok(vibesql_types::SqlValue::Integer(d.to_string().len() as i64))
}
vibesql_types::SqlValue::Timestamp(ts) => {
Ok(vibesql_types::SqlValue::Integer(ts.to_string().len() as i64))
}
vibesql_types::SqlValue::Time(t) => {
Ok(vibesql_types::SqlValue::Integer(t.to_string().len() as i64))
}
vibesql_types::SqlValue::Interval(i) => {
Ok(vibesql_types::SqlValue::Integer(i.to_string().len() as i64))
}
vibesql_types::SqlValue::Vector(v) => {
Ok(vibesql_types::SqlValue::Integer(v.len() as i64))
}
vibesql_types::SqlValue::Blob(b) => {
Ok(vibesql_types::SqlValue::Integer(b.len() as i64))
}
}
}