Skip to main content

common_function/scalars/json/
json_get.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::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
34/// Parses the JSONPath expression accepted by `json_get`.
35/// Keeps the legacy empty path as access to the root value.
36pub 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
45/// Returns object keys for an exact JSON path (e.g., `$.a.b` → `["a", "b"]`),
46/// or `None` for paths containing array access or other selectors.
47pub 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
85// TODO: refactor this to StringLikeArrayBuilder from Arrow 57
86struct 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
327/// Builds a nested struct type for projecting the remaining JSON path.
328///
329/// For example, path `["a", "b"]` with an `Int64` leaf produces
330/// `Struct<a: Struct<b: Int64>>`.
331fn 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/// This function is mostly called as `json_get(value, 'attr')::type` and rewritten by
340/// `json_get_rewriter::JsonGetRewriter` to `json_get(value, 'attr', NULL::type)`. So we
341/// use the third argument's type to determine the return type.
342#[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                // Share integer conversion with JSON2: truncate floats and reject decimal strings.
427                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/// Get the object from JSON value by path.
450#[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    /// Create a JSON object like this (as a one element struct array for testing):
702    ///
703    /// ```JSON
704    /// {
705    ///     "kind": "foo",
706    ///     "payload": {
707    ///         "code": 404,
708    ///         "success": false,
709    ///         "result": {
710    ///             "error": "not found",
711    ///             "time_cost": 1.234
712    ///         }
713    ///     }
714    /// }
715    /// ```
716    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}