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