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