risingwave_expr_impl/scalar/
concat_ws.rs1use risingwave_common::row::Row;
16use risingwave_common::types::ToText;
17use risingwave_expr::function;
18
19#[function("concat_ws(varchar, variadic anyarray) -> varchar")]
36fn concat_ws(sep: &str, vals: impl Row, writer: &mut impl std::fmt::Write) {
37 let mut string_iter = vals.iter().flatten();
38 if let Some(string) = string_iter.next() {
39 string.write(writer).unwrap();
40 }
41 for string in string_iter {
42 write!(writer, "{}", sep).unwrap();
43 string.write(writer).unwrap();
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use risingwave_common::array::DataChunk;
50 use risingwave_common::row::Row;
51 use risingwave_common::test_prelude::DataChunkTestExt;
52 use risingwave_common::types::ToOwnedDatum;
53 use risingwave_common::util::iter_util::ZipEqDebug;
54 use risingwave_expr::expr::build_from_pretty;
55
56 #[tokio::test]
57 async fn test_concat_ws() {
58 let concat_ws =
59 build_from_pretty("(concat_ws:varchar $0:varchar $1:varchar $2:varchar $3:varchar)");
60 let (input, expected) = DataChunk::from_pretty(
61 "T T T T T
62 , a b c a,b,c
63 , . b c b,c
64 . a b c .
65 , . . . (empty)
66 . . . . .",
67 )
68 .split_column_at(4);
69
70 let output = concat_ws.eval(&input).await.unwrap();
72 assert_eq!(&output, expected.column_at(0));
73
74 for (row, expected) in input.rows().zip_eq_debug(expected.rows()) {
76 let result = concat_ws.eval_row(&row.to_owned_row()).await.unwrap();
77 assert_eq!(result, expected.datum_at(0).to_owned_datum());
78 }
79 }
80}