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, StringViewBuilder,
22};
23use datafusion_common::arrow::datatypes::DataType;
24use datafusion_common::{DataFusionError, Result, ScalarValue, exec_datafusion_err, exec_err};
25use datafusion_expr::{ColumnarValue, ScalarFunctionArgs, Signature, Volatility};
26use datatypes::extension::json::is_json2_extension_type;
27use datatypes::vectors::json::array::JsonArray;
28use derive_more::Display;
29use jsonb::jsonpath::{JsonPath, Path, parse_json_path};
30
31use crate::function::{Function, extract_args};
32use crate::helper;
33
34pub fn parse_json_get_path(path: &str) -> std::result::Result<JsonPath<'_>, jsonb::Error> {
37 if path.is_empty() {
38 return Ok(JsonPath {
39 paths: vec![Path::Root],
40 });
41 }
42 parse_json_path(path.as_bytes())
43}
44
45fn json_object_path(path: &str) -> Result<Option<Vec<String>>> {
46 Ok(parse_json_get_path(path)
47 .map_err(|e| exec_datafusion_err!("Invalid JSONPath {path:?}: {e}"))?
48 .paths
49 .into_iter()
50 .filter_map(|segment| match segment {
51 Path::Root => None,
52 Path::DotField(name) | Path::ColonField(name) | Path::ObjectField(name) => {
53 Some(Some(name.into_owned()))
54 }
55 _ => Some(None),
56 })
57 .collect())
58}
59
60trait JsonGetResultBuilder {
61 fn append_value(&mut self, value: &[u8]) -> Result<()>;
62
63 fn append_null(&mut self);
64
65 fn build(&mut self) -> ArrayRef;
66}
67
68fn result_builder(len: usize, with_type: &DataType) -> Result<Box<dyn JsonGetResultBuilder>> {
69 let builder = match with_type {
70 DataType::Utf8 | DataType::LargeUtf8 | DataType::Utf8View => Box::new(StringResultBuilder {
71 inner: StringViewBuilder::with_capacity(len),
72 })
73 as Box<dyn JsonGetResultBuilder>,
74 DataType::Float64 => Box::new(FloatResultBuilder(Float64Builder::with_capacity(len))),
75 DataType::Boolean => Box::new(BoolResultBuilder(BooleanBuilder::with_capacity(len))),
76 t => {
77 return exec_err!("json_get with unknown type {t}");
78 }
79 };
80 Ok(builder)
81}
82
83struct StringResultBuilder {
85 inner: StringViewBuilder,
86}
87
88impl JsonGetResultBuilder for StringResultBuilder {
89 fn append_value(&mut self, value: &[u8]) -> Result<()> {
90 self.inner
91 .append_option(jsonb::RawJsonb::new(value).to_str().ok());
92 Ok(())
93 }
94
95 fn append_null(&mut self) {
96 self.inner.append_null();
97 }
98
99 fn build(&mut self) -> ArrayRef {
100 Arc::new(self.inner.finish())
101 }
102}
103
104impl JsonGetResultBuilder for BinaryViewBuilder {
105 fn append_value(&mut self, value: &[u8]) -> Result<()> {
106 BinaryViewBuilder::append_value(self, value);
107 Ok(())
108 }
109
110 fn append_null(&mut self) {
111 BinaryViewBuilder::append_null(self);
112 }
113
114 fn build(&mut self) -> ArrayRef {
115 Arc::new(self.finish())
116 }
117}
118
119#[derive(Default, Display, Debug)]
120#[display("{}", Self::NAME.to_ascii_uppercase())]
121pub struct JsonGetString(JsonGetWithType);
122
123impl JsonGetString {
124 pub const NAME: &'static str = "json_get_string";
125}
126
127impl Function for JsonGetString {
128 fn name(&self) -> &str {
129 Self::NAME
130 }
131
132 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
133 Ok(DataType::Utf8View)
134 }
135
136 fn signature(&self) -> &Signature {
137 &self.0.signature
138 }
139
140 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
141 args.args
142 .push(ColumnarValue::Scalar(ScalarValue::Utf8View(None)));
143 self.0.invoke_with_args(args)
144 }
145}
146
147#[derive(Default, Display, Debug)]
148#[display("{}", Self::NAME.to_ascii_uppercase())]
149pub struct JsonGetInt(JsonGetWithType);
150
151impl JsonGetInt {
152 pub const NAME: &'static str = "json_get_int";
153}
154
155impl Function for JsonGetInt {
156 fn name(&self) -> &str {
157 Self::NAME
158 }
159
160 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
161 Ok(DataType::Int64)
162 }
163
164 fn signature(&self) -> &Signature {
165 &self.0.signature
166 }
167
168 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
169 args.args
170 .push(ColumnarValue::Scalar(ScalarValue::Int64(None)));
171 self.0.invoke_with_args(args)
172 }
173}
174
175struct FloatResultBuilder(Float64Builder);
176
177impl JsonGetResultBuilder for FloatResultBuilder {
178 fn append_value(&mut self, value: &[u8]) -> Result<()> {
179 self.0
180 .append_option(jsonb::RawJsonb::new(value).to_f64().ok());
181 Ok(())
182 }
183
184 fn append_null(&mut self) {
185 self.0.append_null();
186 }
187
188 fn build(&mut self) -> ArrayRef {
189 Arc::new(self.0.finish())
190 }
191}
192
193#[derive(Default, Display, Debug)]
194#[display("{}", Self::NAME.to_ascii_uppercase())]
195pub struct JsonGetFloat(JsonGetWithType);
196
197impl JsonGetFloat {
198 pub const NAME: &'static str = "json_get_float";
199}
200
201impl Function for JsonGetFloat {
202 fn name(&self) -> &str {
203 Self::NAME
204 }
205
206 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
207 Ok(DataType::Float64)
208 }
209
210 fn signature(&self) -> &Signature {
211 &self.0.signature
212 }
213
214 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
215 args.args
216 .push(ColumnarValue::Scalar(ScalarValue::Float64(None)));
217 self.0.invoke_with_args(args)
218 }
219}
220
221struct BoolResultBuilder(BooleanBuilder);
222
223impl JsonGetResultBuilder for BoolResultBuilder {
224 fn append_value(&mut self, value: &[u8]) -> Result<()> {
225 self.0
226 .append_option(jsonb::RawJsonb::new(value).to_bool().ok());
227 Ok(())
228 }
229
230 fn append_null(&mut self) {
231 self.0.append_null();
232 }
233
234 fn build(&mut self) -> ArrayRef {
235 Arc::new(self.0.finish())
236 }
237}
238
239#[derive(Default, Display, Debug)]
240#[display("{}", Self::NAME.to_ascii_uppercase())]
241pub struct JsonGetBool(JsonGetWithType);
242
243impl JsonGetBool {
244 pub const NAME: &'static str = "json_get_bool";
245}
246
247impl Function for JsonGetBool {
248 fn name(&self) -> &str {
249 Self::NAME
250 }
251
252 fn return_type(&self, _: &[DataType]) -> Result<DataType> {
253 Ok(DataType::Boolean)
254 }
255
256 fn signature(&self) -> &Signature {
257 &self.0.signature
258 }
259
260 fn invoke_with_args(&self, mut args: ScalarFunctionArgs) -> Result<ColumnarValue> {
261 args.args
262 .push(ColumnarValue::Scalar(ScalarValue::Boolean(None)));
263 self.0.invoke_with_args(args)
264 }
265}
266
267fn jsonb_get(
268 jsons: &BinaryViewArray,
269 path: &str,
270 builder: &mut dyn JsonGetResultBuilder,
271) -> Result<()> {
272 let json_path = parse_json_get_path(path)
273 .map_err(|e| exec_datafusion_err!("Invalid JSONPath {path:?}: {e}"))?;
274 let size = jsons.len();
275 for i in 0..size {
276 if jsons.is_null(i) {
277 builder.append_null();
278 continue;
279 }
280 let value = jsonb::RawJsonb::new(jsons.value(i))
281 .select_value_by_path(&json_path)
282 .map_err(|e| exec_datafusion_err!("Failed to evaluate JSONPath {path:?}: {e}"))?;
283 if let Some(value) = value {
284 builder.append_value(value.as_ref())?;
285 } else {
286 builder.append_null();
287 }
288 }
289 Ok(())
290}
291
292fn json_struct_get(array: &ArrayRef, path: &str, with_type: &DataType) -> Result<ArrayRef> {
293 let Some(segments) = json_object_path(path)? else {
294 return exec_err!("JSONPath {path:?} is not supported for Struct input");
295 };
296
297 let mut curr = array.clone();
298
299 for (idx, segment) in segments.iter().enumerate() {
300 if curr.data_type().is_binary() {
301 let target = nested_projection_type(&segments[idx..], with_type);
302 curr = JsonArray::from(&curr)
303 .project_to(&target)
304 .map_err(|e| exec_datafusion_err!("{e}"))?;
305 }
306
307 let Some(json) = curr.as_struct_opt() else {
308 return exec_err!("unknown JSON array datatype: {}", curr.data_type());
309 };
310 let Some(sub_json) = json.column_by_name(segment.as_ref()) else {
311 return Ok(new_null_array(with_type, array.len()));
312 };
313 curr = sub_json.clone();
314 }
315
316 if curr.data_type() == with_type {
317 Ok(curr)
318 } else {
319 JsonArray::from(&curr)
320 .project_to(with_type)
321 .map_err(|e| exec_datafusion_err!("{e}"))
322 }
323}
324
325fn nested_projection_type(path: &[String], leaf_type: &DataType) -> DataType {
330 path.iter()
331 .rev()
332 .fold(leaf_type.clone(), |data_type, name| {
333 DataType::Struct(vec![Arc::new(Field::new(name.as_str(), data_type, true))].into())
334 })
335}
336
337#[derive(Debug, Display)]
341#[display("{}", Self::NAME.to_ascii_uppercase())]
342pub struct JsonGetWithType {
343 signature: Signature,
344}
345
346impl JsonGetWithType {
347 pub const NAME: &'static str = "json_get";
348}
349
350impl Default for JsonGetWithType {
351 fn default() -> Self {
352 Self {
353 signature: Signature::variadic_any(Volatility::Immutable),
354 }
355 }
356}
357
358impl Function for JsonGetWithType {
359 fn name(&self) -> &str {
360 Self::NAME
361 }
362
363 fn return_type(&self, _input_types: &[DataType]) -> datafusion_common::Result<DataType> {
364 Err(DataFusionError::Internal(
365 "This method isn't meant to be called".to_string(),
366 ))
367 }
368
369 fn return_field_from_args(
370 &self,
371 args: datafusion_expr::ReturnFieldArgs<'_>,
372 ) -> datafusion_common::Result<Arc<Field>> {
373 match args.scalar_arguments.get(2) {
374 Some(Some(v)) => {
375 let mut data_type = v.data_type();
376 if matches!(data_type, DataType::Utf8 | DataType::LargeUtf8) {
377 data_type = DataType::Utf8View;
378 }
379
380 Ok(Arc::new(Field::new(self.name(), data_type, true)))
381 }
382 _ => Ok(Arc::new(Field::new(self.name(), DataType::Utf8View, true))),
383 }
384 }
385
386 fn signature(&self) -> &Signature {
387 &self.signature
388 }
389
390 fn invoke_with_args(
391 &self,
392 args: ScalarFunctionArgs,
393 ) -> datafusion_common::Result<ColumnarValue> {
394 let args_len = args.args.len();
395 if args_len != 2 && args_len != 3 {
396 return exec_err!("json_get expects 2 or 3 arguments, got {args_len}");
397 }
398
399 let arg0 = args.args[0].to_array(args.number_rows)?;
400 let len = arg0.len();
401
402 let path = if let ColumnarValue::Scalar(path) = &args.args[1]
403 && let Some(Some(path)) = path.try_as_str()
404 {
405 path
406 } else {
407 return exec_err!(
408 r#"json_get expects a string literal "path" argument, got {}"#,
409 args.args[1]
410 );
411 };
412
413 let with_type = args
414 .args
415 .get(2)
416 .map(|x| x.data_type())
417 .unwrap_or(DataType::Utf8View);
418
419 let result = match arg0.data_type() {
420 DataType::Binary | DataType::LargeBinary | DataType::BinaryView => {
421 let arg0 = compute::cast(&arg0, &DataType::BinaryView)?;
422 let is_json2 = args.arg_fields.first().is_some_and(is_json2_extension_type);
423
424 if is_json2 || with_type == DataType::Int64 {
426 let mut builder = BinaryViewBuilder::with_capacity(len);
427 jsonb_get(arg0.as_binary_view(), path, &mut builder)?;
428 JsonArray::from(&builder.build())
429 .project_to(&with_type)
430 .map_err(|e| exec_datafusion_err!("{e}"))?
431 } else {
432 let mut builder = result_builder(len, &with_type)?;
433 jsonb_get(arg0.as_binary_view(), path, builder.as_mut())?;
434 builder.build()
435 }
436 }
437 DataType::Struct(_) => json_struct_get(&arg0, path, &with_type)?,
438 _ => {
439 return exec_err!("JSON_GET not supported argument type {}", arg0.data_type());
440 }
441 };
442
443 Ok(ColumnarValue::Array(result))
444 }
445}
446
447#[derive(Display, Debug)]
449#[display("{}", Self::NAME.to_ascii_uppercase())]
450pub(super) struct JsonGetObject {
451 signature: Signature,
452}
453
454impl JsonGetObject {
455 const NAME: &'static str = "json_get_object";
456}
457
458impl Default for JsonGetObject {
459 fn default() -> Self {
460 Self {
461 signature: helper::one_of_sigs2(
462 vec![
463 DataType::Binary,
464 DataType::LargeBinary,
465 DataType::BinaryView,
466 ],
467 vec![DataType::UInt8, DataType::LargeUtf8, DataType::Utf8View],
468 ),
469 }
470 }
471}
472
473impl Function for JsonGetObject {
474 fn name(&self) -> &str {
475 Self::NAME
476 }
477
478 fn return_type(&self, _: &[DataType]) -> datafusion_common::Result<DataType> {
479 Ok(DataType::BinaryView)
480 }
481
482 fn signature(&self) -> &Signature {
483 &self.signature
484 }
485
486 fn invoke_with_args(
487 &self,
488 args: ScalarFunctionArgs,
489 ) -> datafusion_common::Result<ColumnarValue> {
490 let [arg0, arg1] = extract_args(self.name(), &args)?;
491 let arg0 = compute::cast(&arg0, &DataType::BinaryView)?;
492 let jsons = arg0.as_binary_view();
493 let arg1 = compute::cast(&arg1, &DataType::Utf8View)?;
494 let paths = arg1.as_string_view();
495
496 let len = jsons.len();
497 let mut builder = BinaryViewBuilder::with_capacity(len);
498
499 for i in 0..len {
500 let json = jsons.is_valid(i).then(|| jsons.value(i));
501 let path = paths.is_valid(i).then(|| paths.value(i));
502 let result = if let (Some(json), Some(path)) = (json, path) {
503 let result = jsonb::jsonpath::parse_json_path(path.as_bytes()).and_then(|path| {
504 let Some(value) = jsonb::RawJsonb::new(json).select_value_by_path(&path)?
505 else {
506 return Ok(None);
507 };
508 value
509 .as_raw()
510 .is_object()
511 .map(|is_object| is_object.then(|| value.to_vec()))
512 });
513 result.map_err(|e| DataFusionError::Execution(e.to_string()))?
514 } else {
515 None
516 };
517 builder.append_option(result);
518 }
519
520 Ok(ColumnarValue::Array(Arc::new(builder.finish())))
521 }
522}
523
524#[cfg(test)]
525mod tests {
526 use std::sync::Arc;
527
528 use arrow::array::{BooleanArray, Int64Array, StructArray};
529 use arrow_schema::{Field, Fields};
530 use datafusion_common::ScalarValue;
531 use datafusion_common::arrow::array::{BinaryArray, BinaryViewArray, StringArray};
532 use datafusion_common::arrow::datatypes::{Float64Type, Int64Type};
533 use datatypes::extension::json::Json2ExtensionType;
534 use datatypes::types::parse_string_to_jsonb;
535 use serde_json::{Value, json};
536
537 use super::*;
538
539 #[test]
540 fn test_json_get_int_conversion() -> Result<()> {
541 let cases = [
542 ("1", Some(1)),
543 ("1.0", Some(1)),
544 ("1.5", Some(1)),
545 ("-1.5", Some(-1)),
546 ("9223372036854775807", Some(i64::MAX)),
547 ("-9223372036854775808", Some(i64::MIN)),
548 ("18446744073709551615", None),
549 (r#""42""#, Some(42)),
550 (r#""1.5""#, None),
551 ("true", Some(1)),
552 ("null", None),
553 ];
554 let jsons = cases
555 .iter()
556 .map(|(input, _)| {
557 jsonb::parse_value_standard_mode(input.as_bytes())
558 .map(|value| value.to_vec())
559 .map_err(|e| exec_datafusion_err!("{e}"))
560 })
561 .collect::<Result<Vec<_>>>()?;
562 let array: ArrayRef = Arc::new(BinaryArray::from_iter_values(jsons));
563 for is_json2 in [false, true] {
564 let result = JsonGetInt::default()
565 .invoke_with_args(ScalarFunctionArgs {
566 args: vec![
567 ColumnarValue::Array(array.clone()),
568 ColumnarValue::Scalar("$".into()),
569 ],
570 arg_fields: vec![test_json_field(&array, is_json2)],
571 number_rows: array.len(),
572 return_field: Arc::new(Field::new("x", DataType::Int64, true)),
573 config_options: Arc::new(Default::default()),
574 })?
575 .into_array(array.len())?;
576 let actual = result.as_primitive::<Int64Type>();
577 for (i, (input, expected)) in cases.iter().enumerate() {
578 assert_eq!(
579 actual.is_valid(i).then(|| actual.value(i)),
580 *expected,
581 "{input}, is_json2={is_json2}"
582 );
583 }
584 }
585 Ok(())
586 }
587
588 #[test]
589 fn test_parse_json_get_path_expression() -> std::result::Result<(), Box<dyn std::error::Error>>
590 {
591 for expression in [
592 "$.l[0]",
593 "$.l[*]",
594 "$.o.*",
595 "$.l[0 to 2]",
596 "$.l ? (@.a == 1)",
597 ] {
598 let parsed = parse_json_get_path(expression).map_err(|e| e.to_string())?;
599 assert_eq!(
600 parsed,
601 parse_json_path(expression.as_bytes()).map_err(|e| e.to_string())?
602 );
603 assert_eq!(json_object_path(expression)?, None);
604 }
605 Ok(())
606 }
607
608 #[test]
609 fn test_json_object_path() -> Result<()> {
610 for path in ["a.b", "$.a.b", r#"$ ."a"."b""#, r#"["a"]["b"]"#] {
611 assert_eq!(json_object_path(path)?, Some(vec!["a".into(), "b".into()]));
612 }
613 for (path, field) in [
614 (r#"$."a.b""#, "a.b"),
615 (r#"$."a\"b""#, "a\"b"),
616 (r#"$."a\\b""#, "a\\b"),
617 (r#"["a.b"]"#, "a.b"),
618 (r#"["a\"b"]"#, "a\"b"),
619 (r#"["a\\b"]"#, "a\\b"),
620 (r#"["a[0]"]"#, "a[0]"),
621 ] {
622 assert_eq!(json_object_path(path)?, Some(vec![field.into()]), "{path}");
623 }
624 for path in ["a[0]", "a[*]", "a.*", "$ ? (@.a == 1)"] {
625 assert_eq!(json_object_path(path)?, None, "{path}");
626 }
627 assert!(json_object_path("a[").is_err());
628 assert_eq!(json_object_path("$")?, Some(vec![]));
629 Ok(())
630 }
631
632 #[test]
633 fn test_parse_json_get_path_unterminated_quotes() {
634 for path in [
635 r#"$."a"#,
636 r#""a"#,
637 r#"$["a"#,
638 r#"$."a\""#,
639 r#"$."a\\"#,
640 r#"$."\u0061"#,
641 r#"$."䏿–‡"#,
642 r#"$.a ? (@ == "value"#,
643 ] {
644 assert!(
645 matches!(
646 parse_json_get_path(path),
647 Err(jsonb::Error::InvalidJsonPath)
648 ),
649 "{path}",
650 );
651 }
652 }
653
654 #[test]
655 fn test_parse_json_get_path_quoted_keys() {
656 for path in [
657 r#"$."a.b""#,
658 r#""a.b""#,
659 r#""a\"b""#,
660 r#""a\\b""#,
661 r#"$["a\"b"]"#,
662 r#"["a\\b"]"#,
663 r#"$.a."""#,
664 r#"$."""#,
665 r#"$[""]"#,
666 ] {
667 assert_eq!(
668 parse_json_get_path(path),
669 parse_json_path(path.as_bytes()),
670 "{path}",
671 );
672 }
673 }
674
675 #[test]
676 fn test_json_struct_get_object_paths() -> std::result::Result<(), Box<dyn std::error::Error>> {
677 for path in [
678 "payload.code",
679 r#"$."payload"."code""#,
680 r#"["payload"]["code"]"#,
681 ] {
682 let result = json_struct_get(&test_json_struct(), path, &DataType::Int64)?;
683 assert_eq!(result.as_primitive::<Int64Type>().value(0), 404);
684 }
685 let nested: ArrayRef = Arc::new(StructArray::from(vec![(
686 Arc::new(Field::new("a.b", DataType::Binary, true)),
687 Arc::new(BinaryArray::from_iter_values([parse_string_to_jsonb(
688 r#"{"c.d": 7}"#,
689 )?])) as ArrayRef,
690 )]));
691 for path in [r#"$."a.b"."c.d""#, r#"$["a.b"]["c.d"]"#] {
692 let result = json_struct_get(&nested, path, &DataType::Int64)?;
693 assert!(!result.is_null(0), "{path}");
694 assert_eq!(result.as_primitive::<Int64Type>().value(0), 7, "{path}");
695 }
696 Ok(())
697 }
698
699 fn test_json_struct() -> ArrayRef {
715 let payload_fields = Fields::from(vec![
716 Field::new("code", DataType::Int64, true),
717 Field::new("success", DataType::Boolean, true),
718 Field::new("result", DataType::Binary, true),
719 ]);
720 Arc::new(StructArray::new(
721 vec![
722 Field::new("kind", DataType::Utf8, true),
723 Field::new("payload", DataType::Struct(payload_fields.clone()), true),
724 ]
725 .into(),
726 vec![
727 Arc::new(StringArray::from_iter([Some("foo")])) as ArrayRef,
728 Arc::new(StructArray::new(
729 payload_fields,
730 vec![
731 Arc::new(Int64Array::from_iter([Some(404)])) as ArrayRef,
732 Arc::new(BooleanArray::from_iter([Some(false)])),
733 Arc::new(BinaryArray::from_iter([Some(
734 json!({
735 "error": "not found",
736 "time_cost": 1.234
737 })
738 .to_string()
739 .as_bytes(),
740 )])),
741 ],
742 None,
743 )),
744 ],
745 None,
746 ))
747 }
748
749 fn test_json_field(json: &ArrayRef, is_json2: bool) -> Arc<Field> {
750 let field = Field::new("json", json.data_type().clone(), true);
751 Arc::new(if is_json2 {
752 field.with_extension_type(Json2ExtensionType::default())
753 } else {
754 field
755 })
756 }
757
758 fn assert_json_or_string_eq(actual: Option<&str>, expected: Option<&str>) {
759 let is_json_container = |value: &str| {
760 matches!(
761 serde_json::from_str::<Value>(value),
762 Ok(Value::Object(_) | Value::Array(_))
763 )
764 };
765
766 match (actual, expected) {
767 (Some(actual), Some(expected))
768 if is_json_container(actual) || is_json_container(expected) =>
769 {
770 let actual_value = serde_json::from_str::<Value>(actual).unwrap_or_else(|error| {
771 panic!("failed to parse actual JSON result {actual:?}: {error}")
772 });
773 let expected_value =
774 serde_json::from_str::<Value>(expected).unwrap_or_else(|error| {
775 panic!("failed to parse expected JSON result {expected:?}: {error}")
776 });
777 assert_eq!(
778 actual_value, expected_value,
779 "JSON result mismatch: actual {actual:?}, expected {expected:?}"
780 );
781 }
782 _ => assert_eq!(actual, expected),
783 }
784 }
785
786 #[test]
787 fn test_json_get_invalid_path() -> std::result::Result<(), Box<dyn std::error::Error>> {
788 let json = parse_string_to_jsonb(r#"{"a": 1}"#)?;
789 let arrays: Vec<ArrayRef> = vec![
790 Arc::new(BinaryArray::from_iter_values([json])),
791 Arc::new(BinaryArray::from(vec![None::<&[u8]>])),
792 Arc::new(BinaryArray::from(Vec::<Option<&[u8]>>::new())),
793 test_json_struct(),
794 ];
795 for array in arrays {
796 for is_json2 in [false, true] {
797 for path in ["$.a[", "..", "$$"] {
798 let args = ScalarFunctionArgs {
799 args: vec![
800 ColumnarValue::Array(array.clone()),
801 ColumnarValue::Scalar(path.into()),
802 ],
803 arg_fields: vec![test_json_field(&array, is_json2)],
804 number_rows: array.len(),
805 return_field: Arc::new(Field::new("x", DataType::Int64, true)),
806 config_options: Arc::new(Default::default()),
807 };
808 let err = JsonGetInt::default().invoke_with_args(args).unwrap_err();
809 assert!(err.to_string().contains("Invalid JSONPath"), "{err}");
810 }
811 }
812 }
813 Ok(())
814 }
815
816 #[test]
817 fn test_jsonb_get_evaluation_error() -> std::result::Result<(), Box<dyn std::error::Error>> {
818 let json = parse_string_to_jsonb(r#"{"a": 1}"#)?;
819 let truncated = BinaryViewArray::from_iter_values([&json[..1]]);
820 let mut builder = BinaryViewBuilder::new();
821 let err = jsonb_get(&truncated, "$.a", &mut builder).unwrap_err();
822 assert!(
823 err.to_string().contains("Failed to evaluate JSONPath"),
824 "{err}"
825 );
826 Ok(())
827 }
828
829 #[test]
830 fn test_json_get_int() {
831 let json_get_int = JsonGetInt::default();
832
833 assert_eq!("json_get_int", json_get_int.name());
834 assert_eq!(
835 DataType::Int64,
836 json_get_int
837 .return_type(&[DataType::Binary, DataType::Utf8])
838 .unwrap()
839 );
840
841 let json_strings = [
842 r#"{"a": {"b": 2}, "b": 2, "c": 3}"#,
843 r#"{"a": 4, "b": {"c": 6}, "c": 6}"#,
844 r#"{"a": 7, "b": 8, "c": {"a": 7}}"#,
845 ];
846 let json_struct = test_json_struct();
847
848 let path_expects = vec![
849 ("$.a.b", Some(2)),
850 ("$.a", Some(4)),
851 ("$.c", None),
852 ("$.kind", None),
853 ("$.payload.code", Some(404)),
854 ("$.payload.success", Some(0)),
855 ("$.payload.result.time_cost", Some(1)),
856 ("$.payload.not_exists", None),
857 ("$.not_exists", None),
858 ("$", None),
859 ];
860
861 let mut jsons = json_strings
862 .iter()
863 .map(|s| {
864 let value = jsonb::parse_value(s.as_bytes()).unwrap();
865 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
866 })
867 .collect::<Vec<_>>();
868 let json_struct_arrays =
869 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
870 jsons.extend(json_struct_arrays);
871
872 for i in 0..jsons.len() {
873 let json = &jsons[i];
874 let (path, expect) = path_expects[i];
875
876 let args = ScalarFunctionArgs {
877 args: vec![
878 ColumnarValue::Array(json.clone()),
879 ColumnarValue::Scalar(path.into()),
880 ],
881 arg_fields: vec![],
882 number_rows: 1,
883 return_field: Arc::new(Field::new("x", DataType::Int64, false)),
884 config_options: Arc::new(Default::default()),
885 };
886 let result = json_get_int
887 .invoke_with_args(args)
888 .and_then(|x| x.to_array(1))
889 .unwrap();
890
891 let result = result.as_primitive::<Int64Type>();
892 assert_eq!(1, result.len());
893 let actual = result.is_valid(0).then(|| result.value(0));
894 assert_eq!(actual, expect);
895 }
896 }
897
898 #[test]
899 fn test_json_get_float() {
900 let json_get_float = JsonGetFloat::default();
901
902 assert_eq!("json_get_float", json_get_float.name());
903 assert_eq!(
904 DataType::Float64,
905 json_get_float
906 .return_type(&[DataType::Binary, DataType::Utf8])
907 .unwrap()
908 );
909
910 let json_strings = [
911 r#"{"a": {"b": 2.1}, "b": 2.2, "c": 3.3}"#,
912 r#"{"a": 4.4, "b": {"c": 6.6}, "c": 6.6}"#,
913 r#"{"a": 7.7, "b": 8.8, "c": {"a": 7.7}}"#,
914 ];
915 let json_struct = test_json_struct();
916
917 let path_expects = vec![
918 ("$.a.b", Some(2.1)),
919 ("$.a", Some(4.4)),
920 ("$.c", None),
921 ("$.kind", None),
922 ("$.payload.code", Some(404.0)),
923 ("$.payload.success", Some(0.0)),
924 ("$.payload.result.time_cost", Some(1.234)),
925 ("$.payload.not_exists", None),
926 ("$.not_exists", None),
927 ("$", None),
928 ];
929
930 let mut jsons = json_strings
931 .iter()
932 .map(|s| {
933 let value = jsonb::parse_value(s.as_bytes()).unwrap();
934 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
935 })
936 .collect::<Vec<_>>();
937 let json_struct_arrays =
938 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
939 jsons.extend(json_struct_arrays);
940
941 for i in 0..jsons.len() {
942 let json = &jsons[i];
943 let (path, expect) = path_expects[i];
944
945 let args = ScalarFunctionArgs {
946 args: vec![
947 ColumnarValue::Array(json.clone()),
948 ColumnarValue::Scalar(path.into()),
949 ],
950 arg_fields: vec![],
951 number_rows: 1,
952 return_field: Arc::new(Field::new("x", DataType::Float64, false)),
953 config_options: Arc::new(Default::default()),
954 };
955 let result = json_get_float
956 .invoke_with_args(args)
957 .and_then(|x| x.to_array(1))
958 .unwrap();
959
960 let result = result.as_primitive::<Float64Type>();
961 assert_eq!(1, result.len());
962 let actual = result.is_valid(0).then(|| result.value(0));
963 assert_eq!(actual, expect);
964 }
965 }
966
967 #[test]
968 fn test_json_get_bool() -> Result<()> {
969 let json_get_bool = JsonGetBool::default();
970
971 assert_eq!("json_get_bool", json_get_bool.name());
972 assert_eq!(
973 DataType::Boolean,
974 json_get_bool.return_type(&[DataType::Binary, DataType::Utf8])?
975 );
976
977 let json_strings = [
978 r#"{"a": {"b": true}, "b": false, "c": true}"#,
979 r#"{"a": false, "b": {"c": true}, "c": false}"#,
980 r#"{"a": true, "b": false, "c": {"a": true}}"#,
981 r#""yes""#,
982 r#""no""#,
983 r#""YeS""#,
984 r#""nO""#,
985 r#""invalid""#,
986 r#""""#,
987 ];
988 let json_struct = test_json_struct();
989
990 let path_expects = vec![
991 ("$.a.b", Some(true)),
992 ("$.a", Some(false)),
993 ("$.c", None),
994 ("$", Some(true)),
995 ("$", Some(false)),
996 ("$", Some(true)),
997 ("$", Some(false)),
998 ("$", None),
999 ("$", None),
1000 ("$.kind", None),
1001 ("$.payload.code", Some(true)),
1002 ("$.payload.success", Some(false)),
1003 ("$.payload.result.time_cost", Some(true)),
1004 ("$.payload.not_exists", None),
1005 ("$.not_exists", None),
1006 ("$", None),
1007 ];
1008
1009 let mut jsons = json_strings
1010 .iter()
1011 .map(|s| {
1012 let value = jsonb::parse_value_standard_mode(s.as_bytes())
1013 .map_err(|e| exec_datafusion_err!("{e}"))?;
1014 Ok(Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef)
1015 })
1016 .collect::<Result<Vec<_>>>()?;
1017 let json_struct_arrays =
1018 std::iter::repeat_n(json_struct, path_expects.len() - jsons.len()).collect::<Vec<_>>();
1019 jsons.extend(json_struct_arrays);
1020
1021 for i in 0..jsons.len() {
1022 let json = &jsons[i];
1023 let (path, expect) = path_expects[i];
1024
1025 let args = ScalarFunctionArgs {
1026 args: vec![
1027 ColumnarValue::Array(json.clone()),
1028 ColumnarValue::Scalar(path.into()),
1029 ],
1030 arg_fields: vec![],
1031 number_rows: 1,
1032 return_field: Arc::new(Field::new("x", DataType::Boolean, false)),
1033 config_options: Arc::new(Default::default()),
1034 };
1035 let result = json_get_bool
1036 .invoke_with_args(args)
1037 .and_then(|x| x.to_array(1))?;
1038
1039 let result = result.as_boolean();
1040 assert_eq!(1, result.len());
1041 let actual = result.is_valid(0).then(|| result.value(0));
1042 assert_eq!(actual, expect);
1043 }
1044 Ok(())
1045 }
1046
1047 #[test]
1048 fn test_json_get_string() {
1049 let json_get_string = JsonGetString::default();
1050
1051 assert_eq!("json_get_string", json_get_string.name());
1052 assert_eq!(
1053 DataType::Utf8View,
1054 json_get_string
1055 .return_type(&[DataType::Binary, DataType::Utf8])
1056 .unwrap()
1057 );
1058
1059 let json_strings = [
1060 r#"{"a": {"b": "a"}, "b": "b", "c": "c"}"#,
1061 r#"{"a": "d", "b": {"c": "e"}, "c": "f"}"#,
1062 r#"{"a": "g", "b": "h", "c": {"a": "g"}}"#,
1063 ];
1064 let json_struct = test_json_struct();
1065
1066 let paths = vec![
1067 "$.a.b",
1068 "$.a",
1069 "",
1070 "$.kind",
1071 "$.payload.code",
1072 "$.payload.result.time_cost",
1073 "$.payload",
1074 "$.payload.success",
1075 "$.payload.result",
1076 "$.payload.result.error",
1077 "$.payload.result.not_exists",
1078 "$.payload.not_exists",
1079 "$.not_exists",
1080 "$",
1081 ];
1082 let expects = [
1083 Some("a"),
1084 Some("d"),
1085 None,
1086 Some("foo"),
1087 Some("404"),
1088 Some("1.234"),
1089 Some(
1090 r#"{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}"#,
1091 ),
1092 Some("false"),
1093 Some(r#"{"error":"not found","time_cost":1.234}"#),
1094 Some("not found"),
1095 None,
1096 None,
1097 None,
1098 Some(
1099 r#"{"kind":"foo","payload":{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}}"#,
1100 ),
1101 ];
1102
1103 let mut jsons = json_strings
1104 .iter()
1105 .map(|s| {
1106 let value = jsonb::parse_value(s.as_bytes()).unwrap();
1107 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1108 })
1109 .collect::<Vec<_>>();
1110 let json_struct_arrays =
1111 std::iter::repeat_n(json_struct, expects.len() - jsons.len()).collect::<Vec<_>>();
1112 jsons.extend(json_struct_arrays);
1113
1114 for i in 0..jsons.len() {
1115 let json = &jsons[i];
1116 let path = paths[i];
1117 let expect = expects[i];
1118
1119 let args = ScalarFunctionArgs {
1120 args: vec![
1121 ColumnarValue::Array(json.clone()),
1122 ColumnarValue::Scalar(path.into()),
1123 ],
1124 arg_fields: vec![
1125 test_json_field(json, i >= json_strings.len()),
1126 Arc::new(Field::new("path", DataType::Utf8, false)),
1127 ],
1128 number_rows: 1,
1129 return_field: Arc::new(Field::new("x", DataType::Utf8View, false)),
1130 config_options: Arc::new(Default::default()),
1131 };
1132 let result = json_get_string
1133 .invoke_with_args(args)
1134 .and_then(|x| x.to_array(1))
1135 .unwrap();
1136
1137 let result = result.as_string_view();
1138 assert_eq!(1, result.len());
1139 let actual = result.is_valid(0).then(|| result.value(0));
1140 assert_json_or_string_eq(actual, expect);
1141 }
1142 }
1143
1144 #[test]
1145 fn test_json_get_object() -> Result<()> {
1146 let udf = JsonGetObject::default();
1147 assert_eq!("json_get_object", udf.name());
1148 assert_eq!(
1149 DataType::BinaryView,
1150 udf.return_type(&[DataType::BinaryView, DataType::Utf8View])?
1151 );
1152
1153 let json_value = parse_string_to_jsonb(r#"{"a": {"b": {"c": {"d": 1}}}}"#).unwrap();
1154 let paths = vec!["$", "$.a", "$.a.b", "$.a.b.c", "$.a.b.c.d", "$.e", "$.a.e"];
1155 let number_rows = paths.len();
1156
1157 let args = ScalarFunctionArgs {
1158 args: vec![
1159 ColumnarValue::Scalar(ScalarValue::Binary(Some(json_value))),
1160 ColumnarValue::Array(Arc::new(StringArray::from_iter_values(paths))),
1161 ],
1162 arg_fields: vec![],
1163 number_rows,
1164 return_field: Arc::new(Field::new("x", DataType::Binary, false)),
1165 config_options: Arc::new(Default::default()),
1166 };
1167 let result = udf
1168 .invoke_with_args(args)
1169 .and_then(|x| x.to_array(number_rows))?;
1170 let result = result.as_binary_view();
1171
1172 let expected = &BinaryViewArray::from_iter(
1173 vec![
1174 Some(r#"{"a": {"b": {"c": {"d": 1}}}}"#),
1175 Some(r#"{"b": {"c": {"d": 1}}}"#),
1176 Some(r#"{"c": {"d": 1}}"#),
1177 Some(r#"{"d": 1}"#),
1178 None,
1179 None,
1180 None,
1181 ]
1182 .into_iter()
1183 .map(|x| x.and_then(|s| parse_string_to_jsonb(s).ok())),
1184 );
1185 assert_eq!(result, expected);
1186 Ok(())
1187 }
1188
1189 #[test]
1190 fn test_json_get_with_type() {
1191 let json_get_with_type = JsonGetWithType::default();
1192
1193 assert_eq!("json_get", json_get_with_type.name());
1194
1195 let json_strings = [
1196 r#"{"a": {"b": "a"}, "b": "b", "c": "c"}"#,
1197 r#"{"a": "d", "b": {"c": "e"}, "c": "f"}"#,
1198 r#"{"a": "g", "b": "h", "c": {"a": "g"}}"#,
1199 ];
1200 let json_struct = test_json_struct();
1201
1202 let paths = vec![
1203 "$.a.b",
1204 "$.a",
1205 "",
1206 "$.kind",
1207 "$.payload.code",
1208 "$.payload.result.time_cost",
1209 "$.payload",
1210 "$.payload.success",
1211 "$.payload.result",
1212 "$.payload.result.error",
1213 "$.payload.result.not_exists",
1214 "$.payload.not_exists",
1215 "$.not_exists",
1216 "$",
1217 ];
1218 let expects = [
1219 Some("a"),
1220 Some("d"),
1221 None,
1222 Some("foo"),
1223 Some("404"),
1224 Some("1.234"),
1225 Some(
1226 r#"{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}"#,
1227 ),
1228 Some("false"),
1229 Some(r#"{"error":"not found","time_cost":1.234}"#),
1230 Some("not found"),
1231 None,
1232 None,
1233 None,
1234 Some(
1235 r#"{"kind":"foo","payload":{"code":404,"result":{"error":"not found","time_cost":1.234},"success":false}}"#,
1236 ),
1237 ];
1238
1239 let mut jsons = json_strings
1240 .iter()
1241 .map(|s| {
1242 let value = jsonb::parse_value(s.as_bytes()).unwrap();
1243 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1244 })
1245 .collect::<Vec<_>>();
1246 let json_struct_arrays =
1247 std::iter::repeat_n(json_struct, expects.len() - jsons.len()).collect::<Vec<_>>();
1248 jsons.extend(json_struct_arrays);
1249
1250 for i in 0..jsons.len() {
1251 let json = &jsons[i];
1252 let path = paths[i];
1253 let expect = expects[i];
1254
1255 let args = ScalarFunctionArgs {
1256 args: vec![
1257 ColumnarValue::Array(json.clone()),
1258 ColumnarValue::Scalar(path.into()),
1259 ColumnarValue::Scalar(ScalarValue::Utf8View(None)),
1260 ],
1261 arg_fields: vec![
1262 test_json_field(json, i >= json_strings.len()),
1263 Arc::new(Field::new("path", DataType::Utf8, false)),
1264 Arc::new(Field::new("with_type", DataType::Utf8View, true)),
1265 ],
1266 number_rows: 1,
1267 return_field: Arc::new(Field::new("x", DataType::Utf8View, false)),
1268 config_options: Arc::new(Default::default()),
1269 };
1270 let result = json_get_with_type
1271 .invoke_with_args(args)
1272 .and_then(|x| x.to_array(1))
1273 .unwrap();
1274
1275 let result = result.as_string_view();
1276 assert_eq!(1, result.len());
1277 let actual = result.is_valid(0).then(|| result.value(0));
1278 assert_json_or_string_eq(actual, expect);
1279 }
1280
1281 let json_strings = [
1282 r#"{"a": {"b": 2}, "b": 2, "c": 3}"#,
1283 r#"{"a": 4, "b": {"c": 6}, "c": 6}"#,
1284 r#"{"a": 7, "b": 8, "c": {"a": 7}}"#,
1285 ];
1286 let paths = ["$.a.b", "$.a", "$.c", "$.payload.code"];
1287 let expects = [Some(2), Some(4), None, Some(404)];
1288
1289 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1290 let json = if i < json_strings.len() {
1291 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1292 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1293 } else {
1294 test_json_struct()
1295 };
1296
1297 let args = ScalarFunctionArgs {
1298 args: vec![
1299 ColumnarValue::Array(json),
1300 ColumnarValue::Scalar((*path).into()),
1301 ColumnarValue::Scalar(ScalarValue::Int64(None)),
1302 ],
1303 arg_fields: vec![],
1304 number_rows: 1,
1305 return_field: Arc::new(Field::new("x", DataType::Int64, false)),
1306 config_options: Arc::new(Default::default()),
1307 };
1308 let result = json_get_with_type
1309 .invoke_with_args(args)
1310 .and_then(|x| x.to_array(1))
1311 .unwrap();
1312
1313 let result = result.as_primitive::<Int64Type>();
1314 assert_eq!(1, result.len());
1315 let actual = result.is_valid(0).then(|| result.value(0));
1316 assert_eq!(actual, *expect);
1317 }
1318
1319 let json_strings = [
1320 r#"{"a": {"b": 2.1}, "b": 2.2, "c": 3.3}"#,
1321 r#"{"a": 4.4, "b": {"c": 6.6}, "c": 6.6}"#,
1322 r#"{"a": 7.7, "b": 8.8, "c": {"a": 7.7}}"#,
1323 ];
1324 let paths = ["$.a.b", "$.a", "$.c", "$.payload.result.time_cost"];
1325 let expects = [Some(2.1), Some(4.4), None, Some(1.234)];
1326
1327 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1328 let json = if i < json_strings.len() {
1329 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1330 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1331 } else {
1332 test_json_struct()
1333 };
1334
1335 let args = ScalarFunctionArgs {
1336 args: vec![
1337 ColumnarValue::Array(json),
1338 ColumnarValue::Scalar((*path).into()),
1339 ColumnarValue::Scalar(ScalarValue::Float64(None)),
1340 ],
1341 arg_fields: vec![],
1342 number_rows: 1,
1343 return_field: Arc::new(Field::new("x", DataType::Float64, false)),
1344 config_options: Arc::new(Default::default()),
1345 };
1346 let result = json_get_with_type
1347 .invoke_with_args(args)
1348 .and_then(|x| x.to_array(1))
1349 .unwrap();
1350
1351 let result = result.as_primitive::<Float64Type>();
1352 assert_eq!(1, result.len());
1353 let actual = result.is_valid(0).then(|| result.value(0));
1354 assert_eq!(actual, *expect);
1355 }
1356
1357 let json_strings = [
1358 r#"{"a": {"b": true}, "b": false, "c": true}"#,
1359 r#"{"a": false, "b": {"c": true}, "c": false}"#,
1360 r#"{"a": true, "b": false, "c": {"a": true}}"#,
1361 ];
1362 let paths = ["$.a.b", "$.a", "$.c", "$.payload.success"];
1363 let expects = [Some(true), Some(false), None, Some(false)];
1364
1365 for (i, (path, expect)) in paths.iter().zip(expects.iter()).enumerate() {
1366 let json = if i < json_strings.len() {
1367 let value = jsonb::parse_value(json_strings[i].as_bytes()).unwrap();
1368 Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef
1369 } else {
1370 test_json_struct()
1371 };
1372
1373 let args = ScalarFunctionArgs {
1374 args: vec![
1375 ColumnarValue::Array(json),
1376 ColumnarValue::Scalar((*path).into()),
1377 ColumnarValue::Scalar(ScalarValue::Boolean(None)),
1378 ],
1379 arg_fields: vec![],
1380 number_rows: 1,
1381 return_field: Arc::new(Field::new("x", DataType::Boolean, false)),
1382 config_options: Arc::new(Default::default()),
1383 };
1384 let result = json_get_with_type
1385 .invoke_with_args(args)
1386 .and_then(|x| x.to_array(1))
1387 .unwrap();
1388
1389 let result = result.as_boolean();
1390 assert_eq!(1, result.len());
1391 let actual = result.is_valid(0).then(|| result.value(0));
1392 assert_eq!(actual, *expect);
1393 }
1394 }
1395
1396 #[test]
1397 fn test_json_get_json2_root() -> std::result::Result<(), Box<dyn std::error::Error>> {
1398 for (input, expected) in [
1399 ("42", ScalarValue::Int64(Some(42))),
1400 ("42", ScalarValue::Int32(Some(42))),
1401 ("18446744073709551615", ScalarValue::UInt64(Some(u64::MAX))),
1402 ("1.5", ScalarValue::Float64(Some(1.5))),
1403 ("true", ScalarValue::Boolean(Some(true))),
1404 (r#""text""#, ScalarValue::Utf8View(Some("text".into()))),
1405 ("null", ScalarValue::Utf8View(None)),
1406 (
1407 r#"{"a":1}"#,
1408 ScalarValue::Utf8View(Some(r#"{"a":1}"#.into())),
1409 ),
1410 ("[1,2]", ScalarValue::Utf8View(Some("[1,2]".into()))),
1411 ] {
1412 let json = parse_string_to_jsonb(input)?;
1413 let array: ArrayRef = Arc::new(BinaryArray::from_iter_values([json]));
1414 for path in ["", "$", " $ "] {
1415 let args = ScalarFunctionArgs {
1416 args: vec![
1417 ColumnarValue::Array(array.clone()),
1418 ColumnarValue::Scalar(path.into()),
1419 ColumnarValue::Scalar(ScalarValue::try_new_null(&expected.data_type())?),
1420 ],
1421 arg_fields: vec![test_json_field(&array, true)],
1422 number_rows: 1,
1423 return_field: Arc::new(Field::new("x", expected.data_type(), true)),
1424 config_options: Arc::new(Default::default()),
1425 };
1426 let result = JsonGetWithType::default()
1427 .invoke_with_args(args)?
1428 .to_array(1)?;
1429 assert_eq!(
1430 ScalarValue::try_from_array(&result, 0)?,
1431 expected,
1432 "{path:?}: {input}"
1433 );
1434 }
1435 }
1436 Ok(())
1437 }
1438
1439 #[test]
1440 fn test_json_get_json2_quoted_root_field() -> std::result::Result<(), Box<dyn std::error::Error>>
1441 {
1442 for key in ["a.b", "a\"b", "a\\b"] {
1443 let input = json!({key: 42}).to_string();
1444 let value = jsonb::parse_value(input.as_bytes()).map_err(|e| e.to_string())?;
1445 let json = Arc::new(BinaryArray::from_iter_values([value.to_vec()])) as ArrayRef;
1446 let args = ScalarFunctionArgs {
1447 args: vec![
1448 ColumnarValue::Array(json.clone()),
1449 ColumnarValue::Scalar(ScalarValue::Utf8(Some(format!(
1450 "[{}]",
1451 serde_json::to_string(key)?
1452 )))),
1453 ColumnarValue::Scalar(ScalarValue::Int64(None)),
1454 ],
1455 arg_fields: vec![
1456 test_json_field(&json, true),
1457 Arc::new(Field::new("path", DataType::Utf8, false)),
1458 Arc::new(Field::new("with_type", DataType::Int64, true)),
1459 ],
1460 number_rows: 1,
1461 return_field: Arc::new(Field::new("x", DataType::Int64, true)),
1462 config_options: Arc::new(Default::default()),
1463 };
1464
1465 let result = JsonGetWithType::default()
1466 .invoke_with_args(args)
1467 .and_then(|x| x.to_array(1))?;
1468 assert_eq!(result.as_primitive::<Int64Type>().value(0), 42);
1469 assert!(!result.is_null(0));
1470 }
1471 Ok(())
1472 }
1473}