From fdeabd9eed5497cc6aed9e45c94f8083090bc332 Mon Sep 17 00:00:00 2001 From: luofucong Date: Thu, 23 Apr 2026 19:57:22 +0800 Subject: [PATCH] x Signed-off-by: luofucong --- src/datatypes/src/json.rs | 63 +++++++++++++++++++++------- src/datatypes/src/types/json_type.rs | 9 ++++ src/datatypes/src/value.rs | 2 +- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/datatypes/src/json.rs b/src/datatypes/src/json.rs index 53e722eafd..0555649832 100644 --- a/src/datatypes/src/json.rs +++ b/src/datatypes/src/json.rs @@ -743,7 +743,7 @@ where #[cfg(test)] mod tests { - + use common_base::bytes::Bytes; use serde_json::json; use super::*; @@ -1064,11 +1064,21 @@ mod tests { fn test_encode_json_array_mixed_types() { let json = json!([1, "hello", true, 3.15]); let settings = JsonStructureSettings::Structured(None); - let result = settings.encode_with_type(json, None); - assert_eq!( - result.unwrap_err().to_string(), - "Invalid JSON: all items in json array must have the same type" - ); + let result = settings + .encode_with_type(json, None) + .unwrap() + .into_json_inner() + .unwrap(); + + if let Value::List(list_value) = result { + assert_eq!(list_value.items().len(), 4); + assert_eq!( + list_value.datatype(), + Arc::new(ConcreteDataType::binary_datatype()) + ); + } else { + panic!("Expected List value"); + } } #[test] @@ -1290,12 +1300,12 @@ mod tests { #[test] fn test_encode_json_array_with_item_type() { let json = json!([1, 2, 3]); - let item_type = Arc::new(ConcreteDataType::uint64_datatype()); + let item_type = Arc::new(ConcreteDataType::int64_datatype()); let settings = JsonStructureSettings::Structured(None); let result = settings .encode_with_type( json, - Some(&JsonNativeType::Array(Box::new(JsonNativeType::u64()))), + Some(&JsonNativeType::Array(Box::new(JsonNativeType::i64()))), ) .unwrap() .into_json_inner() @@ -1303,9 +1313,9 @@ mod tests { if let Value::List(list_value) = result { assert_eq!(list_value.items().len(), 3); - assert_eq!(list_value.items()[0], Value::UInt64(1)); - assert_eq!(list_value.items()[1], Value::UInt64(2)); - assert_eq!(list_value.items()[2], Value::UInt64(3)); + assert_eq!(list_value.items()[0], Value::Int64(1)); + assert_eq!(list_value.items()[1], Value::Int64(2)); + assert_eq!(list_value.items()[2], Value::Int64(3)); assert_eq!(list_value.datatype(), item_type); } else { panic!("Expected List value"); @@ -2263,11 +2273,32 @@ mod tests { )])), ); - let decoded_struct = settings.decode_struct(array_struct); - assert_eq!( - decoded_struct.unwrap_err().to_string(), - "Invalid JSON: all items in json array must have the same type" - ); + let decoded_struct = settings.decode_struct(array_struct).unwrap(); + let fields = decoded_struct.struct_type().fields(); + let decoded_fields: Vec<&str> = fields.iter().map(|f| f.name()).collect(); + assert!(decoded_fields.contains(&"value")); + + if let Value::List(list_value) = &decoded_struct.items()[0] { + assert_eq!(list_value.items().len(), 4); + assert_eq!( + list_value.items()[0], + Value::Binary(Bytes::from("1".as_bytes())) + ); + assert_eq!( + list_value.items()[1], + Value::Binary(Bytes::from(r#""hello""#.as_bytes())) + ); + assert_eq!( + list_value.items()[2], + Value::Binary(Bytes::from("true".as_bytes())) + ); + assert_eq!( + list_value.items()[3], + Value::Binary(Bytes::from("3.15".as_bytes())) + ); + } else { + panic!("Expected array to be decoded as ListValue"); + } } #[test] diff --git a/src/datatypes/src/types/json_type.rs b/src/datatypes/src/types/json_type.rs index 0c556d933e..0a4c07d1bf 100644 --- a/src/datatypes/src/types/json_type.rs +++ b/src/datatypes/src/types/json_type.rs @@ -314,6 +314,15 @@ fn merge(this: &JsonNativeType, that: &JsonNativeType) -> JsonNativeType { JsonNativeType::Object(merge_object(this, that)) } (JsonNativeType::Null, x) | (x, JsonNativeType::Null) => x.clone(), + + (JsonNativeType::Number(x), JsonNativeType::Number(y)) => { + JsonNativeType::Number(match (x, y) { + (x, y) if x == y => *x, + (JsonNumberType::F64, _) | (_, JsonNumberType::F64) => JsonNumberType::F64, + _ => JsonNumberType::I64, + }) + } + _ => JsonNativeType::Variant, } } diff --git a/src/datatypes/src/value.rs b/src/datatypes/src/value.rs index 2b50e96075..13193fe0b0 100644 --- a/src/datatypes/src/value.rs +++ b/src/datatypes/src/value.rs @@ -3206,7 +3206,7 @@ pub(crate) mod tests { ] .into(), )), - 56, + 48, ); }