common_function/scalars/json/
json_to_string.rs1use std::fmt::{self, Display};
16
17use common_query::error::{InvalidFuncArgsSnafu, Result, UnsupportedInputDataTypeSnafu};
18use datafusion_expr::{Signature, Volatility};
19use datatypes::arrow::datatypes::DataType;
20use datatypes::data_type::ConcreteDataType;
21use datatypes::prelude::VectorRef;
22use datatypes::scalars::ScalarVectorBuilder;
23use datatypes::vectors::{MutableVector, StringVectorBuilder};
24use snafu::ensure;
25
26use crate::function::{Function, FunctionContext};
27
28#[derive(Clone, Debug, Default)]
30pub struct JsonToStringFunction;
31
32const NAME: &str = "json_to_string";
33
34impl Function for JsonToStringFunction {
35 fn name(&self) -> &str {
36 NAME
37 }
38
39 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
40 Ok(DataType::Utf8)
41 }
42
43 fn signature(&self) -> Signature {
44 Signature::exact(vec![DataType::Binary], Volatility::Immutable)
46 }
47
48 fn eval(&self, _func_ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef> {
49 ensure!(
50 columns.len() == 1,
51 InvalidFuncArgsSnafu {
52 err_msg: format!(
53 "The length of the args is not correct, expect exactly one, have: {}",
54 columns.len()
55 ),
56 }
57 );
58 let jsons = &columns[0];
59
60 let size = jsons.len();
61 let datatype = jsons.data_type();
62 let mut results = StringVectorBuilder::with_capacity(size);
63
64 match datatype {
65 ConcreteDataType::Binary(_) => {
67 for i in 0..size {
68 let json = jsons.get_ref(i);
69
70 let json = json.as_binary();
71 let result = match json {
72 Ok(Some(json)) => match jsonb::from_slice(json) {
73 Ok(json) => {
74 let json = json.to_string();
75 Some(json)
76 }
77 Err(_) => {
78 return InvalidFuncArgsSnafu {
79 err_msg: format!("Illegal json binary: {:?}", json),
80 }
81 .fail();
82 }
83 },
84 _ => None,
85 };
86
87 results.push(result.as_deref());
88 }
89 }
90 _ => {
91 return UnsupportedInputDataTypeSnafu {
92 function: NAME,
93 datatypes: columns.iter().map(|c| c.data_type()).collect::<Vec<_>>(),
94 }
95 .fail();
96 }
97 }
98
99 Ok(results.to_vector())
100 }
101}
102
103impl Display for JsonToStringFunction {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "JSON_TO_STRING")
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use std::sync::Arc;
112
113 use datafusion_expr::TypeSignature;
114 use datatypes::scalars::ScalarVector;
115 use datatypes::vectors::BinaryVector;
116
117 use super::*;
118
119 #[test]
120 fn test_json_to_string_function() {
121 let json_to_string = JsonToStringFunction;
122
123 assert_eq!("json_to_string", json_to_string.name());
124 assert_eq!(
125 DataType::Utf8,
126 json_to_string.return_type(&[DataType::Binary]).unwrap()
127 );
128
129 assert!(matches!(json_to_string.signature(),
130 Signature {
131 type_signature: TypeSignature::Exact(valid_types),
132 volatility: Volatility::Immutable
133 } if valid_types == vec![DataType::Binary]
134 ));
135
136 let json_strings = [
137 r#"{"a": {"b": 2}, "b": 2, "c": 3}"#,
138 r#"{"a": 4, "b": {"c": 6}, "c": 6}"#,
139 r#"{"a": 7, "b": 8, "c": {"a": 7}}"#,
140 ];
141
142 let jsonbs = json_strings
143 .iter()
144 .map(|s| {
145 let value = jsonb::parse_value(s.as_bytes()).unwrap();
146 value.to_vec()
147 })
148 .collect::<Vec<_>>();
149
150 let json_vector = BinaryVector::from_vec(jsonbs);
151 let args: Vec<VectorRef> = vec![Arc::new(json_vector)];
152 let vector = json_to_string
153 .eval(&FunctionContext::default(), &args)
154 .unwrap();
155
156 assert_eq!(3, vector.len());
157 for (i, gt) in json_strings.iter().enumerate() {
158 let result = vector.get_ref(i);
159 let result = result.as_string().unwrap().unwrap();
160 assert_eq!(gt.replace(" ", ""), result);
162 }
163
164 let invalid_jsonb = vec![b"invalid json"];
165 let invalid_json_vector = BinaryVector::from_vec(invalid_jsonb);
166 let args: Vec<VectorRef> = vec![Arc::new(invalid_json_vector)];
167 let vector = json_to_string.eval(&FunctionContext::default(), &args);
168 assert!(vector.is_err());
169 }
170}