common_function/scalars/vector/convert/
vector_to_string.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16
17use common_query::error::{InvalidFuncArgsSnafu, Result};
18use common_query::prelude::{Signature, Volatility};
19use datatypes::prelude::ConcreteDataType;
20use datatypes::scalars::ScalarVectorBuilder;
21use datatypes::types::vector_type_value_to_string;
22use datatypes::value::Value;
23use datatypes::vectors::{MutableVector, StringVectorBuilder, VectorRef};
24use snafu::ensure;
25
26use crate::function::{Function, FunctionContext};
27
28const NAME: &str = "vec_to_string";
29
30#[derive(Debug, Clone, Default)]
31pub struct VectorToStringFunction;
32
33impl Function for VectorToStringFunction {
34    fn name(&self) -> &str {
35        NAME
36    }
37
38    fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result<ConcreteDataType> {
39        Ok(ConcreteDataType::string_datatype())
40    }
41
42    fn signature(&self) -> Signature {
43        Signature::exact(
44            vec![ConcreteDataType::binary_datatype()],
45            Volatility::Immutable,
46        )
47    }
48
49    fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef> {
50        ensure!(
51            columns.len() == 1,
52            InvalidFuncArgsSnafu {
53                err_msg: format!(
54                    "The length of the args is not correct, expect exactly one, have: {}",
55                    columns.len()
56                ),
57            }
58        );
59
60        let column = &columns[0];
61        let size = column.len();
62
63        let mut result = StringVectorBuilder::with_capacity(size);
64        for i in 0..size {
65            let value = column.get(i);
66            match value {
67                Value::Binary(bytes) => {
68                    let len = bytes.len();
69                    if len % std::mem::size_of::<f32>() != 0 {
70                        return InvalidFuncArgsSnafu {
71                            err_msg: format!("Invalid binary length of vector: {}", len),
72                        }
73                        .fail();
74                    }
75
76                    let dim = len / std::mem::size_of::<f32>();
77                    // Safety: `dim` is calculated from the length of `bytes` and is guaranteed to be valid
78                    let res = vector_type_value_to_string(&bytes, dim as _).unwrap();
79                    result.push(Some(&res));
80                }
81                Value::Null => {
82                    result.push_null();
83                }
84                _ => {
85                    return InvalidFuncArgsSnafu {
86                        err_msg: format!("Invalid value type: {:?}", value.data_type()),
87                    }
88                    .fail();
89                }
90            }
91        }
92
93        Ok(result.to_vector())
94    }
95}
96
97impl Display for VectorToStringFunction {
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        write!(f, "{}", NAME.to_ascii_uppercase())
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use datatypes::value::Value;
106    use datatypes::vectors::BinaryVectorBuilder;
107
108    use super::*;
109
110    #[test]
111    fn test_vector_to_string() {
112        let func = VectorToStringFunction;
113
114        let mut builder = BinaryVectorBuilder::with_capacity(3);
115        builder.push(Some(
116            [1.0f32, 2.0, 3.0]
117                .iter()
118                .flat_map(|e| e.to_le_bytes())
119                .collect::<Vec<_>>()
120                .as_slice(),
121        ));
122        builder.push(Some(
123            [4.0f32, 5.0, 6.0]
124                .iter()
125                .flat_map(|e| e.to_le_bytes())
126                .collect::<Vec<_>>()
127                .as_slice(),
128        ));
129        builder.push_null();
130        let vector = builder.to_vector();
131
132        let result = func.eval(&FunctionContext::default(), &[vector]).unwrap();
133
134        assert_eq!(result.len(), 3);
135        assert_eq!(result.get(0), Value::String("[1,2,3]".to_string().into()));
136        assert_eq!(result.get(1), Value::String("[4,5,6]".to_string().into()));
137        assert_eq!(result.get(2), Value::Null);
138    }
139}