Skip to content

Commit

Permalink
Add replace
Browse files Browse the repository at this point in the history
  • Loading branch information
mediuminvader committed Feb 26, 2024
1 parent 072b43e commit a39a5d0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
18 changes: 17 additions & 1 deletion dozer-sql/expression/src/scalar/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use dozer_types::types::Record;
use dozer_types::types::{Field, FieldType, Schema};
use std::fmt::{Display, Formatter};

use super::string::{evaluate_chr, evaluate_substr, validate_substr};
use super::string::{
evaluate_chr, evaluate_replace, evaluate_substr, validate_replace, validate_substr,
};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
pub enum ScalarFunctionType {
Expand All @@ -24,6 +26,7 @@ pub enum ScalarFunctionType {
Chr,
Substr,
Nvl,
Replace,
}

impl Display for ScalarFunctionType {
Expand All @@ -38,6 +41,7 @@ impl Display for ScalarFunctionType {
ScalarFunctionType::Chr => f.write_str("CHR"),
ScalarFunctionType::Substr => f.write_str("SUBSTR"),
ScalarFunctionType::Nvl => f.write_str("NVL"),
ScalarFunctionType::Replace => f.write_str("REPLACE"),
}
}
}
Expand Down Expand Up @@ -87,6 +91,7 @@ pub(crate) fn get_scalar_function_type(
ScalarFunctionType::Nvl => {
Ok(validate_two_arguments(args, schema, ScalarFunctionType::Nvl)?.0)
}
ScalarFunctionType::Replace => validate_replace(args, schema),
}
}

Expand All @@ -101,6 +106,7 @@ impl ScalarFunctionType {
"to_char" => Some(ScalarFunctionType::ToChar),
"chr" => Some(ScalarFunctionType::Chr),
"substr" => Some(ScalarFunctionType::Substr),
"replace" => Some(ScalarFunctionType::Replace),
"nvl" => Some(ScalarFunctionType::Nvl),
_ => None,
}
Expand Down Expand Up @@ -155,6 +161,16 @@ impl ScalarFunctionType {
validate_two_arguments(args, schema, ScalarFunctionType::Nvl)?;
evaluate_nvl(schema, &mut args[0].clone(), &mut args[1].clone(), record)
}
ScalarFunctionType::Replace => {
validate_replace(args, schema)?;
evaluate_replace(
schema,
&mut args[0].clone(),
&mut args[1].clone(),
&mut args[2].clone(),
record,
)
}
}
}
}
52 changes: 52 additions & 0 deletions dozer-sql/expression/src/scalar/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,58 @@ pub(crate) fn evaluate_substr(
Ok(Field::String(result))
}

pub fn validate_replace(args: &[Expression], schema: &Schema) -> Result<ExpressionType, Error> {
if args.len() != 3 {
return Err(Error::InvalidFunctionArgument {
function_name: ScalarFunctionType::Replace.to_string(),
argument_index: 0,
argument: Field::Null,
});
}

let mut ret_type = FieldType::String;
for exp in args {
let r = validate_arg_type(
exp,
vec![FieldType::String, FieldType::Text],
schema,
ScalarFunctionType::Replace,
0,
)?;
if matches!(r.return_type, FieldType::Text) {
ret_type = FieldType::Text;
}
}

Ok(ExpressionType::new(
ret_type,
false,
dozer_types::types::SourceDefinition::Dynamic,
false,
))
}

pub(crate) fn evaluate_replace(
schema: &Schema,
arg: &mut Expression,
search: &mut Expression,
replace: &mut Expression,
record: &Record,
) -> Result<Field, Error> {
let arg_field = arg.evaluate(record, schema)?;
let arg_value = arg_field.to_string();

let search_field = search.evaluate(record, schema)?;
let search_value = search_field.to_string();

let replace_field = replace.evaluate(record, schema)?;
let replace_value = replace_field.to_string();

let result = arg_value.replace(search_value.as_str(), replace_value.as_str());

Ok(Field::String(result))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit a39a5d0

Please sign in to comment.