1use std::sync::Arc;
16
17use arrow::array::{ArrayRef, BinaryViewArray, new_null_array};
18use arrow::compute;
19use arrow_schema::Field;
20use datafusion_common::arrow::array::{
21 Array, AsArray, BinaryViewBuilder, BooleanBuilder, Float64Builder, Int64Builder,
22 StringViewBuilder,
23};
24use datafusion_common::arrow::datatypes::DataType;
25use datafusion_common::{DataFusionError, Result, ScalarValue, exec_datafusion_err, exec_err};
26use datafusion_expr::{ColumnarValue, ScalarFunctionArgs, Signature, Volatility};
27use datatypes::extension::json::is_json2_extension_type;
28use datatypes::vectors::json::array::JsonArray;
29use derive_more::Display;
30
31use crate::function::{Function, extract_args};
32use crate::helper;
33
34fn get_json_by_path(json: &[u8], path: &str) -> Option<Vec<u8>> {
35 let json_path = jsonb::jsonpath::parse_json_path(path.as_bytes());
36 match json_path {
37 Ok(json_path) => {
38 let mut sub_jsonb = Vec::new();
39 let mut sub_offsets = Vec::new();
40 match jsonb::get_by_path(json, json_path, &mut sub_jsonb, &mut sub_offsets) {
41 Ok(_) => Some(sub_jsonb),
42 Err(_) => None,
43 }
44 }
45 _ => None,
46 }
47}
48
49trait JsonGetResultBuilder {
50 fn append_value(&mut self, value: &[u8]) -> Result<()>;
51
52 fn append_null(&mut self);
53
54 fn build(&mut self) -> ArrayRef;
55}
56
57fn result_builder(len: usize, with_type: &DataType) -> Result<Box<dyn JsonGetResultBuilder>> {
58 let builder = match with_type {
59 DataType::Utf8 | DataType::LargeUtf8 | DataType::Utf8View => {
60 Box::new(StringResultBuilder(StringViewBuilder::with_capacity(len)))
61 as Box<dyn JsonGetResultBuilder>
62 }
63 DataType::Int64 => Box::new(IntResultBuilder(Int64Builder::with_capacity(len))),
64 DataType::Float64 => Box::new(FloatResultBuilder(Float64Builder::with_capacity(len))),
65 DataType::Boolean => Box::new(BoolResultBuilder(BooleanBuilder::with_capacity(len))),
66 t => {
67 return exec_err!("json_get with unknown type {t}");
68 }
69 };
70 Ok(builder)
71}
72
73struct StringResultBuilder(StringViewBuilder);
75
76impl JsonGetResultBuilder for StringResultBuilder {
77 fn append_value(&mut self, value: &[u8]) -> Result<()> {
78 self.0.append_option(jsonb::to_str(value).ok());
79 Ok(())
80 }
81
82 fn append_null(&mut self) {
83 self.0.append_null();
84 }
85
86 fn build(&mut self) -> ArrayRef {
87 Arc::new(self.0.finish())
88 }
89}
90
91#[derive(Default, Display, Debug)]
92#[display("{}", Self::NAME.to_ascii_uppercase())]
93pub struct JsonGetString(JsonGetWithType);
94
95impl JsonGetString {
96 pub const NAME: &'static str = "json_get_string";
97}
98
99impl Function for JsonGetString {
100 fn name(&self) -> &str {
101 Self::NAME
102 }
103
104 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
105 Ok(DataType::Utf8View)
106 }
107
108 fn signature(&self) -> &Signature {
109 &self.0.signature
110 }
111
112 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
113 args.args
114 .push(ColumnarValue::Scalar(ScalarValue::Utf8View(None)));
115 self.0.invoke_with_args(args)
116 }
117}
118
119struct IntResultBuilder(Int64Builder);
120
121impl JsonGetResultBuilder for IntResultBuilder {
122 fn append_value(&mut self, value: &[u8]) -> Result<()> {
123 self.0.append_option(jsonb::to_i64(value).ok());
124 Ok(())
125 }
126
127 fn append_null(&mut self) {
128 self.0.append_null();
129 }
130
131 fn build(&mut self) -> ArrayRef {
132 Arc::new(self.0.finish())
133 }
134}
135
136#[derive(Default, Display, Debug)]
137#[display("{}", Self::NAME.to_ascii_uppercase())]
138pub struct JsonGetInt(JsonGetWithType);
139
140impl JsonGetInt {
141 pub const NAME: &'static str = "json_get_int";
142}
143
144impl Function for JsonGetInt {
145 fn name(&self) -> &str {
146 Self::NAME
147 }
148
149 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
150 Ok(DataType::Int64)
151 }
152
153 fn signature(&self) -> &Signature {
154 &self.0.signature
155 }
156
157 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
158 args.args
159 .push(ColumnarValue::Scalar(ScalarValue::Int64(None)));
160 self.0.invoke_with_args(args)
161 }
162}
163
164struct FloatResultBuilder(Float64Builder);
165
166impl JsonGetResultBuilder for FloatResultBuilder {
167 fn append_value(&mut self, value: &[u8]) -> Result<()> {
168 self.0.append_option(jsonb::to_f64(value).ok());
169 Ok(())
170 }
171
172 fn append_null(&mut self) {
173 self.0.append_null();
174 }
175
176 fn build(&mut self) -> ArrayRef {
177 Arc::new(self.0.finish())
178 }
179}
180
181#[derive(Default, Display, Debug)]
182#[display("{}", Self::NAME.to_ascii_uppercase())]
183pub struct JsonGetFloat(JsonGetWithType);
184
185impl JsonGetFloat {
186 pub const NAME: &'static str = "json_get_float";
187}
188
189impl Function for JsonGetFloat {
190 fn name(&self) -> &str {
191 Self::NAME
192 }
193
194 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
195 Ok(DataType::Float64)
196 }
197
198 fn signature(&self) -> &Signature {
199 &self.0.signature
200 }
201
202 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
203 args.args
204 .push(ColumnarValue::Scalar(ScalarValue::Float64(None)));
205 self.0.invoke_with_args(args)
206 }
207}
208
209struct BoolResultBuilder(BooleanBuilder);
210
211impl JsonGetResultBuilder for BoolResultBuilder {
212 fn append_value(&mut self, value: &[u8]) -> Result<()> {
213 self.0.append_option(jsonb::to_bool(value).ok());
214 Ok(())
215 }
216
217 fn append_null(&mut self) {
218 self.0.append_null();
219 }
220
221 fn build(&mut self) -> ArrayRef {
222 Arc::new(self.0.finish())
223 }
224}
225
226#[derive(Default, Display, Debug)]
227#[display("{}", Self::NAME.to_ascii_uppercase())]
228pub struct JsonGetBool(JsonGetWithType);
229
230impl JsonGetBool {
231 pub const NAME: &'static str = "json_get_bool";
232}
233
234impl Function for JsonGetBool {
235 fn name(&self) -> &str {
236 Self::NAME
237 }
238
239 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
240 Ok(DataType::Boolean)
241 }
242
243 fn signature(&self) -> &Signature {
244 &self.0.signature
245 }
246
247 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
248 args.args
249 .push(ColumnarValue::Scalar(ScalarValue::Boolean(None)));
250 self.0.invoke_with_args(args)
251 }
252}
253
254fn jsonb_get(
255 jsons: &BinaryViewArray,
256 path: &str,
257 builder: &mut dyn JsonGetResultBuilder,
258) -> Result<()> {
259 let size = jsons.len();
260 for i in 0..size {
261 let json = jsons.is_valid(i).then(|| jsons.value(i));
262 let result = match json {
263 Some(json) => get_json_by_path(json, path),
264 _ => None,
265 };
266 if let Some(v) = result {
267 builder.append_value(&v)?;
268 } else {
269 builder.append_null();
270 }
271 }
272 Ok(())
273}
274
275fn json_struct_get(array: &ArrayRef, path: &str, with_type: &DataType) -> Result<ArrayRef> {
276 let segments = path
277 .trim_start_matches("$")
278 .split('.')
279 .filter(|segment| !segment.is_empty())
280 .collect::<Vec<_>>();
281
282 let mut curr = array.clone();
283
284 for (idx, segment) in segments.iter().enumerate() {
285 if curr.data_type().is_binary() {
286 let target = nested_projection_type(&segments[idx..], with_type);
287 curr = JsonArray::from(&curr)
288 .project_to(&target)
289 .map_err(|e| exec_datafusion_err!("{e}"))?;
290 }
291
292 let Some(json) = curr.as_struct_opt() else {
293 return exec_err!("unknown JSON array datatype: {}", curr.data_type());
294 };
295 let Some(sub_json) = json.column_by_name(segment) else {
296 return Ok(new_null_array(with_type, array.len()));
297 };
298 curr = sub_json.clone();
299 }
300
301 if curr.data_type() == with_type {
302 Ok(curr)
303 } else {
304 JsonArray::from(&curr)
305 .project_to(with_type)
306 .map_err(|e| exec_datafusion_err!("{e}"))
307 }
308}
309
310fn nested_projection_type(path: &[&str], leaf_type: &DataType) -> DataType {
315 path.iter()
316 .rev()
317 .fold(leaf_type.clone(), |data_type, name| {
318 DataType::Struct(vec![Arc::new(Field::new(*name, data_type, true))].into())
319 })
320}
321
322#[derive(Debug, Display)]
326#[display("{}", Self::NAME.to_ascii_uppercase())]
327pub struct JsonGetWithType {
328 signature: Signature,
329}
330
331impl JsonGetWithType {
332 pub const NAME: &'static str = "json_get";
333}
334
335impl Default for JsonGetWithType {
336 fn default() -> Self {
337 Self {
338 signature: Signature::variadic_any(Volatility::Immutable),
339 }
340 }
341}
342
343impl Function for JsonGetWithType {
344 fn name(&self) -> &str {
345 Self::NAME
346 }
347
348 fn return_type(&self, _input_types: &[DataType]) -> datafusion_common::Result<DataType> {
349 Err(DataFusionError::Internal(
350 "This method isn't meant to be called".to_string(),
351 ))
352 }
353
354 fn return_field_from_args(
355 &self,
356 args: datafusion_expr::ReturnFieldArgs<'_>,
357 ) -> datafusion_common::Result<Arc<Field>> {
358 match args.scalar_arguments.get(2) {
359 Some(Some(v)) => {
360 let mut data_type = v.data_type();
361 if matches!(data_type, DataType::Utf8 | DataType::LargeUtf8) {
362 data_type = DataType::Utf8View;
363 }
364
365 Ok(Arc::new(Field::new(self.name(), data_type, true)))
366 }
367 _ => Ok(Arc::new(Field::new(self.name(), DataType::Utf8View, true))),
368 }
369 }
370
371 fn signature(&self) -> &Signature {
372 &self.signature
373 }
374
375 fn invoke_with_args(
376 &self,
377 args: ScalarFunctionArgs,
378 ) -> datafusion_common::Result<ColumnarValue> {
379 let args_len = args.args.len();
380 if args_len != 2 && args_len != 3 {
381 return exec_err!("json_get expects 2 or 3 arguments, got {args_len}");
382 }
383
384 let arg0 = args.args[0].to_array(args.number_rows)?;
385 let len = arg0.len();
386
387 let path = if let ColumnarValue::Scalar(path) = &args.args[1]
388 && let Some(Some(path)) = path.try_as_str()
389 {
390 path
391 } else {
392 return exec_err!(
393 r#"json_get expects a string literal "path" argument, got {}"#,
394 args.args[1]
395 );
396 };
397
398 let with_type = args
399 .args
400 .get(2)
401 .map(|x| x.data_type())
402 .unwrap_or(DataType::Utf8View);
403
404 let result = match arg0.data_type() {
405 DataType::Binary | DataType::LargeBinary | DataType::BinaryView => {
406 let arg0 = compute::cast(&arg0, &DataType::BinaryView)?;
407
408 if args.arg_fields.first().is_some_and(is_json2_extension_type) {
409 JsonArray::from(&arg0)
413 .project_to(&with_type)
414 .map_err(|e| exec_datafusion_err!("{e:?}"))?
415 } else {
416 let jsons = arg0.as_binary_view();
417 let mut builder = result_builder(len, &with_type)?;
418 jsonb_get(jsons, path, builder.as_mut())?;
419 builder.build()
420 }
421 }
422 DataType::Struct(_) => json_struct_get(&arg0, path, &with_type)?,
423 _ => {
424 return exec_err!("JSON_GET not supported argument type {}", arg0.data_type());
425 }
426 };
427
428 Ok(ColumnarValue::Array(result))
429 }
430}
431
432#[derive(Display, Debug)]
434#[display("{}", Self::NAME.to_ascii_uppercase())]
435pub(super) struct JsonGetObject {
436 signature: Signature,
437}
438
439impl JsonGetObject {
440 const NAME: &'static str = "json_get_object";
441}
442
443impl Default for JsonGetObject {
444 fn default() -> Self {
445 Self {
446 signature: helper::one_of_sigs2(
447 vec![
448 DataType::Binary,
449 DataType::LargeBinary,
450 DataType::BinaryView,
451 ],
452 vec![DataType::UInt8, DataType::LargeUtf8, DataType::Utf8View],
453 ),
454 }
455 }
456}
457
458impl Function for JsonGetObject {
459 fn name(&self) -> &str {
460 Self::NAME
461 }
462
463 fn return_type(&self, _: &[DataType]) -> datafusion_common::Result<DataType> {
464 Ok(DataType::BinaryView)
465 }
466
467 fn signature(&self) -> &Signature {
468 &self.signature
469 }
470
471 fn invoke_with_args(
472 &self,
473 args: ScalarFunctionArgs,
474 ) -> datafusion_common::Result<ColumnarValue> {
475 let [arg0, arg1] = extract_args(self.name(), &args)?;
476 let arg0 = compute::cast(&arg0, &DataType::BinaryView)?;
477 let jsons = arg0.as_binary_view();
478 let arg1 = compute::cast(&arg1, &DataType::Utf8View)?;
479 let paths = arg1.as_string_view();
480
481 let len = jsons.len();
482 let mut builder = BinaryViewBuilder::with_capacity(len);
483
484 for i in 0..len {
485 let json = jsons.is_valid(i).then(|| jsons.value(i));
486 let path = paths.is_valid(i).then(|| paths.value(i));
487 let result = if let (Some(json), Some(path)) = (json, path) {
488 let result = jsonb::jsonpath::parse_json_path(path.as_bytes()).and_then(|path| {
489 let mut data = Vec::new();
490 let mut offset = Vec::new();
491 jsonb::get_by_path(json, path, &mut data, &mut offset)
492 .map(|()| jsonb::is_object(&data).then_some(data))
493 });
494 result.map_err(|e| DataFusionError::Execution(e.to_string()))?
495 } else {
496 None
497 };
498 builder.append_option(result);
499 }
500
501 Ok(ColumnarValue::Array(Arc::new(builder.finish())))
502 }
503}
504
505#[cfg(test)]
506mod tests {
507 use std::sync::Arc;
508
509 use arrow::array::{BooleanArray, Int64Array, StructArray};
510 use arrow_schema::{Field, Fields};
511 use datafusion_common::ScalarValue;
512 use datafusion_common::arrow::array::{BinaryArray, BinaryViewArray, StringArray};
513 use datafusion_common::arrow::datatypes::{Float64Type, Int64Type};
514 use datatypes::types::parse_string_to_jsonb;
515 use serde_json::json;
516
517 use super::*;
518
519 fn test_json_struct() -> ArrayRef {
535 let payload_fields = Fields::from(vec![
536 Field::new("code", DataType::Int64, true),
537 Field::new("success", DataType::Boolean, true),
538 Field::new("result", DataType::Binary, true),
539 ]);
540 Arc::new(StructArray::new(
541 vec![
542 Field::new("kind", DataType::Utf8, true),
543 Field::new("payload", DataType::Struct(payload_fields.clone()), true),
544 ]
545 .into(),
546 vec![
547 Arc::new(StringArray::from_iter([Some("foo")])) as ArrayRef,
548 Arc::new(StructArray::new(
549 payload_fields,
550 vec![
551 Arc::new(Int64Array::from_iter([Some(404)])) as ArrayRef,
552 Arc::new(BooleanArray::from_iter([Some(false)])),
553 Arc::new(BinaryArray::from_iter([Some(
554 json!({
555 "error": "not found",
556 "time_cost": 1.234
557 })
558 .to_string()
559 .as_bytes(),
560 )])),
561 ],
562 None,
563 )),
564 ],
565 None,
566 ))
567 }
568
569 #[test]
570 fn test_json_get_int() {
571 let json_get_int = JsonGetInt::default();
572
573 assert_eq!("json_get_int", json_get_int.name());
574 assert_eq!(
575 DataType::Int64,
576 json_get_int
577 .return_type(&[DataType::Binary, DataType::Utf8])
578 .unwrap()
579 );
580
581 let json_strings = [
582 r#"{"a": {"b": 2}, "b": 2, "c": 3}"#,
583 r#"{"a": 4, "b": {"c": 6}, "c": 6}"#,
584 r#"{"a": 7, "b": 8, "c": {"a": 7}}"#,
585 ];
586 let json_struct = test_json_struct();
587
588 let path_expects = vec![
589 ("$.a.b", Some(2)),
590 ("$.a", Some(4)),
591 ("$.c", None),
592 ("$.kind", None),
593 ("$.payload.code", Some(404)),
594 ("$.payload.success", Some(0)),
595 ("$.payload.result.time_cost", Some(1)),
596 ("$.payload.not-exists", None),
597 ("$.not-exists", None),
598 ("$", None),
599 ];
600
601 let mut jsons = json_strings
602 .iter()
603 .map(|s| {
604 let value = jsonb::parse_value(s.as_bytes()).unwrap();
605 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
606 })
607 .collect::<Vec<_>>();
608 let json_struct_arrays =
609 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
610 jsons.extend(json_struct_arrays);
611
612 for i in 0..jsons.len() {
613 let json = &jsons[i];
614 let (path, expect) = path_expects[i];
615
616 let args = ScalarFunctionArgs {
617 args: vec![
618 ColumnarValue::Array(json.clone()),
619 ColumnarValue::Scalar(path.into()),
620 ],
621 arg_fields: vec![],
622 number_rows: 1,
623 return_field: Arc::new(Field::new("x", DataType::Int64, false)),
624 config_options: Arc::new(Default::default()),
625 };
626 let result = json_get_int
627 .invoke_with_args(args)
628 .and_then(|x| x.to_array(1))
629 .unwrap();
630
631 let result = result.as_primitive::<Int64Type>();
632 assert_eq!(1, result.len());
633 let actual = result.is_valid(0).then(|| result.value(0));
634 assert_eq!(actual, expect);
635 }
636 }
637
638 #[test]
639 fn test_json_get_float() {
640 let json_get_float = JsonGetFloat::default();
641
642 assert_eq!("json_get_float", json_get_float.name());
643 assert_eq!(
644 DataType::Float64,
645 json_get_float
646 .return_type(&[DataType::Binary, DataType::Utf8])
647 .unwrap()
648 );
649
650 let json_strings = [
651 r#"{"a": {"b": 2.1}, "b": 2.2, "c": 3.3}"#,
652 r#"{"a": 4.4, "b": {"c": 6.6}, "c": 6.6}"#,
653 r#"{"a": 7.7, "b": 8.8, "c": {"a": 7.7}}"#,
654 ];
655 let json_struct = test_json_struct();
656
657 let path_expects = vec![
658 ("$.a.b", Some(2.1)),
659 ("$.a", Some(4.4)),
660 ("$.c", None),
661 ("$.kind", None),
662 ("$.payload.code", Some(404.0)),
663 ("$.payload.success", Some(0.0)),
664 ("$.payload.result.time_cost", Some(1.234)),
665 ("$.payload.not-exists", None),
666 ("$.not-exists", None),
667 ("$", None),
668 ];
669
670 let mut jsons = json_strings
671 .iter()
672 .map(|s| {
673 let value = jsonb::parse_value(s.as_bytes()).unwrap();
674 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
675 })
676 .collect::<Vec<_>>();
677 let json_struct_arrays =
678 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
679 jsons.extend(json_struct_arrays);
680
681 for i in 0..jsons.len() {
682 let json = &jsons[i];
683 let (path, expect) = path_expects[i];
684
685 let args = ScalarFunctionArgs {
686 args: vec![
687 ColumnarValue::Array(json.clone()),
688 ColumnarValue::Scalar(path.into()),
689 ],
690 arg_fields: vec![],
691 number_rows: 1,
692 return_field: Arc::new(Field::new("x", DataType::Float64, false)),
693 config_options: Arc::new(Default::default()),
694 };
695 let result = json_get_float
696 .invoke_with_args(args)
697 .and_then(|x| x.to_array(1))
698 .unwrap();
699
700 let result = result.as_primitive::<Float64Type>();
701 assert_eq!(1, result.len());
702 let actual = result.is_valid(0).then(|| result.value(0));
703 assert_eq!(actual, expect);
704 }
705 }
706
707 #[test]
708 fn test_json_get_bool() {
709 let json_get_bool = JsonGetBool::default();
710
711 assert_eq!("json_get_bool", json_get_bool.name());
712 assert_eq!(
713 DataType::Boolean,
714 json_get_bool
715 .return_type(&[DataType::Binary, DataType::Utf8])
716 .unwrap()
717 );
718
719 let json_strings = [
720 r#"{"a": {"b": true}, "b": false, "c": true}"#,
721 r#"{"a": false, "b": {"c": true}, "c": false}"#,
722 r#"{"a": true, "b": false, "c": {"a": true}}"#,
723 ];
724 let json_struct = test_json_struct();
725
726 let path_expects = vec![
727 ("$.a.b", Some(true)),
728 ("$.a", Some(false)),
729 ("$.c", None),
730 ("$.kind", None),
731 ("$.payload.code", Some(true)),
732 ("$.payload.success", Some(false)),
733 ("$.payload.result.time_cost", Some(true)),
734 ("$.payload.not-exists", None),
735 ("$.not-exists", None),
736 ("$", None),
737 ];
738
739 let mut jsons = json_strings
740 .iter()
741 .map(|s| {
742 let value = jsonb::parse_value(s.as_bytes()).unwrap();
743 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
744 })
745 .collect::<Vec<_>>();
746 let json_struct_arrays =
747 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
748 jsons.extend(json_struct_arrays);
749
750 for i in 0..jsons.len() {
751 let json = &jsons[i];
752 let (path, expect) = path_expects[i];
753
754 let args = ScalarFunctionArgs {
755 args: vec![
756 ColumnarValue::Array(json.clone()),
757 ColumnarValue::Scalar(path.into()),
758 ],
759 arg_fields: vec![],
760 number_rows: 1,
761 return_field: Arc::new(Field::new("x", DataType::Boolean, false)),
762 config_options: Arc::new(Default::default()),
763 };
764 let result = json_get_bool
765 .invoke_with_args(args)
766 .and_then(|x| x.to_array(1))
767 .unwrap();
768
769 let result = result.as_boolean();
770 assert_eq!(1, result.len());
771 let actual = result.is_valid(0).then(|| result.value(0));
772 assert_eq!(actual, expect);
773 }
774 }
775
776 #[test]
777 fn test_json_get_string() {
778 let json_get_string = JsonGetString::default();
779
780 assert_eq!("json_get_string", json_get_string.name());
781 assert_eq!(
782 DataType::Utf8View,
783 json_get_string
784 .return_type(&[DataType::Binary, DataType::Utf8])
785 .unwrap()
786 );
787
788 let json_strings = [
789 r#"{"a": {"b": "a"}, "b": "b", "c": "c"}"#,
790 r#"{"a": "d", "b": {"c": "e"}, "c": "f"}"#,
791 r#"{"a": "g", "b": "h", "c": {"a": "g"}}"#,
792 ];
793 let json_struct = test_json_struct();
794
795 let paths = vec![
796 "$.a.b",
797 "$.a",
798 "",
799 "$.kind",
800 "$.payload.code",
801 "$.payload.result.time_cost",
802 "$.payload",
803 "$.payload.success",
804 "$.payload.result",
805 "$.payload.result.error",
806 "$.payload.result.not-exists",
807 "$.payload.not-exists",
808 "$.not-exists",
809 "$",
810 ];
811 let expects = [
812 Some("a"),
813 Some("d"),
814 None,
815 Some("foo"),
816 Some("404"),
817 Some("1.234"),
818 Some(
819 r#"{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}"#,
820 ),
821 Some("false"),
822 Some(r#"{"error":"not found","time_cost":1.234}"#),
823 Some("not found"),
824 None,
825 None,
826 None,
827 Some(
828 r#"{"kind":"foo","payload":{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}}"#,
829 ),
830 ];
831
832 let mut jsons = json_strings
833 .iter()
834 .map(|s| {
835 let value = jsonb::parse_value(s.as_bytes()).unwrap();
836 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
837 })
838 .collect::<Vec<_>>();
839 let json_struct_arrays =
840 std::iter::repeat_n(json_struct, expects.len() - jsons.len()).collect::<Vec<_>>();
841 jsons.extend(json_struct_arrays);
842
843 for i in 0..jsons.len() {
844 let json = &jsons[i];
845 let path = paths[i];
846 let expect = expects[i];
847
848 let args = ScalarFunctionArgs {
849 args: vec![
850 ColumnarValue::Array(json.clone()),
851 ColumnarValue::Scalar(path.into()),
852 ],
853 arg_fields: vec![],
854 number_rows: 1,
855 return_field: Arc::new(Field::new("x", DataType::Utf8View, false)),
856 config_options: Arc::new(Default::default()),
857 };
858 let result = json_get_string
859 .invoke_with_args(args)
860 .and_then(|x| x.to_array(1))
861 .unwrap();
862
863 let result = result.as_string_view();
864 assert_eq!(1, result.len());
865 let actual = result.is_valid(0).then(|| result.value(0));
866 assert_eq!(actual, expect);
867 }
868 }
869
870 #[test]
871 fn test_json_get_object() -> Result<()> {
872 let udf = JsonGetObject::default();
873 assert_eq!("json_get_object", udf.name());
874 assert_eq!(
875 DataType::BinaryView,
876 udf.return_type(&[DataType::BinaryView, DataType::Utf8View])?
877 );
878
879 let json_value = parse_string_to_jsonb(r#"{"a": {"b": {"c": {"d": 1}}}}"#).unwrap();
880 let paths = vec!["$", "$.a", "$.a.b", "$.a.b.c", "$.a.b.c.d", "$.e", "$.a.e"];
881 let number_rows = paths.len();
882
883 let args = ScalarFunctionArgs {
884 args: vec![
885 ColumnarValue::Scalar(ScalarValue::Binary(Some(json_value))),
886 ColumnarValue::Array(Arc::new(StringArray::from_iter_values(paths))),
887 ],
888 arg_fields: vec![],
889 number_rows,
890 return_field: Arc::new(Field::new("x", DataType::Binary, false)),
891 config_options: Arc::new(Default::default()),
892 };
893 let result = udf
894 .invoke_with_args(args)
895 .and_then(|x| x.to_array(number_rows))?;
896 let result = result.as_binary_view();
897
898 let expected = &BinaryViewArray::from_iter(
899 vec![
900 Some(r#"{"a": {"b": {"c": {"d": 1}}}}"#),
901 Some(r#"{"b": {"c": {"d": 1}}}"#),
902 Some(r#"{"c": {"d": 1}}"#),
903 Some(r#"{"d": 1}"#),
904 None,
905 None,
906 None,
907 ]
908 .into_iter()
909 .map(|x| x.and_then(|s| parse_string_to_jsonb(s).ok())),
910 );
911 assert_eq!(result, expected);
912 Ok(())
913 }
914
915 #[test]
916 fn test_json_get_with_type() {
917 let json_get_with_type = JsonGetWithType::default();
918
919 assert_eq!("json_get", json_get_with_type.name());
920
921 let json_strings = [
922 r#"{"a": {"b": "a"}, "b": "b", "c": "c"}"#,
923 r#"{"a": "d", "b": {"c": "e"}, "c": "f"}"#,
924 r#"{"a": "g", "b": "h", "c": {"a": "g"}}"#,
925 ];
926 let json_struct = test_json_struct();
927
928 let paths = vec![
929 "$.a.b",
930 "$.a",
931 "",
932 "$.kind",
933 "$.payload.code",
934 "$.payload.result.time_cost",
935 "$.payload",
936 "$.payload.success",
937 "$.payload.result",
938 "$.payload.result.error",
939 "$.payload.result.not-exists",
940 "$.payload.not-exists",
941 "$.not-exists",
942 "$",
943 ];
944 let expects = [
945 Some("a"),
946 Some("d"),
947 None,
948 Some("foo"),
949 Some("404"),
950 Some("1.234"),
951 Some(
952 r#"{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}"#,
953 ),
954 Some("false"),
955 Some(r#"{"error":"not found","time_cost":1.234}"#),
956 Some("not found"),
957 None,
958 None,
959 None,
960 Some(
961 r#"{"kind":"foo","payload":{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}}"#,
962 ),
963 ];
964
965 let mut jsons = json_strings
966 .iter()
967 .map(|s| {
968 let value = jsonb::parse_value(s.as_bytes()).unwrap();
969 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
970 })
971 .collect::<Vec<_>>();
972 let json_struct_arrays =
973 std::iter::repeat_n(json_struct, expects.len() - jsons.len()).collect::<Vec<_>>();
974 jsons.extend(json_struct_arrays);
975
976 for i in 0..jsons.len() {
977 let json = &jsons[i];
978 let path = paths[i];
979 let expect = expects[i];
980
981 let args = ScalarFunctionArgs {
982 args: vec![
983 ColumnarValue::Array(json.clone()),
984 ColumnarValue::Scalar(path.into()),
985 ColumnarValue::Scalar(ScalarValue::Utf8View(None)),
986 ],
987 arg_fields: vec![],
988 number_rows: 1,
989 return_field: Arc::new(Field::new("x", DataType::Utf8View, false)),
990 config_options: Arc::new(Default::default()),
991 };
992 let result = json_get_with_type
993 .invoke_with_args(args)
994 .and_then(|x| x.to_array(1))
995 .unwrap();
996
997 let result = result.as_string_view();
998 assert_eq!(1, result.len());
999 let actual = result.is_valid(0).then(|| result.value(0));
1000 assert_eq!(actual, expect);
1001 }
1002
1003 let json_strings = [
1004 r#"{"a": {"b": 2}, "b": 2, "c": 3}"#,
1005 r#"{"a": 4, "b": {"c": 6}, "c": 6}"#,
1006 r#"{"a": 7, "b": 8, "c": {"a": 7}}"#,
1007 ];
1008 let paths = ["$.a.b", "$.a", "$.c", "$.payload.code"];
1009 let expects = [Some(2), Some(4), None, Some(404)];
1010
1011 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1012 let json = if i < json_strings.len() {
1013 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1014 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1015 } else {
1016 test_json_struct()
1017 };
1018
1019 let args = ScalarFunctionArgs {
1020 args: vec![
1021 ColumnarValue::Array(json),
1022 ColumnarValue::Scalar((*path).into()),
1023 ColumnarValue::Scalar(ScalarValue::Int64(None)),
1024 ],
1025 arg_fields: vec![],
1026 number_rows: 1,
1027 return_field: Arc::new(Field::new("x", DataType::Int64, false)),
1028 config_options: Arc::new(Default::default()),
1029 };
1030 let result = json_get_with_type
1031 .invoke_with_args(args)
1032 .and_then(|x| x.to_array(1))
1033 .unwrap();
1034
1035 let result = result.as_primitive::<Int64Type>();
1036 assert_eq!(1, result.len());
1037 let actual = result.is_valid(0).then(|| result.value(0));
1038 assert_eq!(actual, *expect);
1039 }
1040
1041 let json_strings = [
1042 r#"{"a": {"b": 2.1}, "b": 2.2, "c": 3.3}"#,
1043 r#"{"a": 4.4, "b": {"c": 6.6}, "c": 6.6}"#,
1044 r#"{"a": 7.7, "b": 8.8, "c": {"a": 7.7}}"#,
1045 ];
1046 let paths = ["$.a.b", "$.a", "$.c", "$.payload.result.time_cost"];
1047 let expects = [Some(2.1), Some(4.4), None, Some(1.234)];
1048
1049 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1050 let json = if i < json_strings.len() {
1051 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1052 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1053 } else {
1054 test_json_struct()
1055 };
1056
1057 let args = ScalarFunctionArgs {
1058 args: vec![
1059 ColumnarValue::Array(json),
1060 ColumnarValue::Scalar((*path).into()),
1061 ColumnarValue::Scalar(ScalarValue::Float64(None)),
1062 ],
1063 arg_fields: vec![],
1064 number_rows: 1,
1065 return_field: Arc::new(Field::new("x", DataType::Float64, false)),
1066 config_options: Arc::new(Default::default()),
1067 };
1068 let result = json_get_with_type
1069 .invoke_with_args(args)
1070 .and_then(|x| x.to_array(1))
1071 .unwrap();
1072
1073 let result = result.as_primitive::<Float64Type>();
1074 assert_eq!(1, result.len());
1075 let actual = result.is_valid(0).then(|| result.value(0));
1076 assert_eq!(actual, *expect);
1077 }
1078
1079 let json_strings = [
1080 r#"{"a": {"b": true}, "b": false, "c": true}"#,
1081 r#"{"a": false, "b": {"c": true}, "c": false}"#,
1082 r#"{"a": true, "b": false, "c": {"a": true}}"#,
1083 ];
1084 let paths = ["$.a.b", "$.a", "$.c", "$.payload.success"];
1085 let expects = [Some(true), Some(false), None, Some(false)];
1086
1087 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1088 let json = if i < json_strings.len() {
1089 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1090 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1091 } else {
1092 test_json_struct()
1093 };
1094
1095 let args = ScalarFunctionArgs {
1096 args: vec![
1097 ColumnarValue::Array(json),
1098 ColumnarValue::Scalar((*path).into()),
1099 ColumnarValue::Scalar(ScalarValue::Boolean(None)),
1100 ],
1101 arg_fields: vec![],
1102 number_rows: 1,
1103 return_field: Arc::new(Field::new("x", DataType::Boolean, false)),
1104 config_options: Arc::new(Default::default()),
1105 };
1106 let result = json_get_with_type
1107 .invoke_with_args(args)
1108 .and_then(|x| x.to_array(1))
1109 .unwrap();
1110
1111 let result = result.as_boolean();
1112 assert_eq!(1, result.len());
1113 let actual = result.is_valid(0).then(|| result.value(0));
1114 assert_eq!(actual, *expect);
1115 }
1116 }
1117}