reifydb_function/text/
replace.rs1use reifydb_core::value::column::data::ColumnData;
5use reifydb_type::value::{constraint::bytes::MaxBytes, container::utf8::Utf8Container, r#type::Type};
6
7use crate::{ScalarFunction, ScalarFunctionContext, error::ScalarFunctionError, propagate_options};
8
9pub struct TextReplace;
10
11impl TextReplace {
12 pub fn new() -> Self {
13 Self
14 }
15}
16
17impl ScalarFunction for TextReplace {
18 fn scalar(&self, ctx: ScalarFunctionContext) -> crate::error::ScalarFunctionResult<ColumnData> {
19 if let Some(result) = propagate_options(self, &ctx) {
20 return result;
21 }
22
23 let columns = ctx.columns;
24 let row_count = ctx.row_count;
25
26 if columns.len() != 3 {
27 return Err(ScalarFunctionError::ArityMismatch {
28 function: ctx.fragment.clone(),
29 expected: 3,
30 actual: columns.len(),
31 });
32 }
33
34 let str_col = columns.get(0).unwrap();
35 let from_col = columns.get(1).unwrap();
36 let to_col = columns.get(2).unwrap();
37
38 match (str_col.data(), from_col.data(), to_col.data()) {
39 (
40 ColumnData::Utf8 {
41 container: str_container,
42 ..
43 },
44 ColumnData::Utf8 {
45 container: from_container,
46 ..
47 },
48 ColumnData::Utf8 {
49 container: to_container,
50 ..
51 },
52 ) => {
53 let mut result_data = Vec::with_capacity(row_count);
54
55 for i in 0..row_count {
56 if str_container.is_defined(i)
57 && from_container.is_defined(i) && to_container.is_defined(i)
58 {
59 let s = &str_container[i];
60 let from = &from_container[i];
61 let to = &to_container[i];
62 result_data.push(s.replace(from.as_str(), to.as_str()));
63 } else {
64 result_data.push(String::new());
65 }
66 }
67
68 Ok(ColumnData::Utf8 {
69 container: Utf8Container::new(result_data),
70 max_bytes: MaxBytes::MAX,
71 })
72 }
73 (
74 ColumnData::Utf8 {
75 ..
76 },
77 ColumnData::Utf8 {
78 ..
79 },
80 other,
81 ) => Err(ScalarFunctionError::InvalidArgumentType {
82 function: ctx.fragment.clone(),
83 argument_index: 2,
84 expected: vec![Type::Utf8],
85 actual: other.get_type(),
86 }),
87 (
88 ColumnData::Utf8 {
89 ..
90 },
91 other,
92 _,
93 ) => Err(ScalarFunctionError::InvalidArgumentType {
94 function: ctx.fragment.clone(),
95 argument_index: 1,
96 expected: vec![Type::Utf8],
97 actual: other.get_type(),
98 }),
99 (other, _, _) => Err(ScalarFunctionError::InvalidArgumentType {
100 function: ctx.fragment.clone(),
101 argument_index: 0,
102 expected: vec![Type::Utf8],
103 actual: other.get_type(),
104 }),
105 }
106 }
107
108 fn return_type(&self, _input_types: &[Type]) -> Type {
109 Type::Utf8
110 }
111}