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