From 112e89da38153cc7b67558669e371420f93579fe Mon Sep 17 00:00:00 2001 From: luofucong Date: Fri, 3 Jul 2026 20:02:32 +0800 Subject: [PATCH] fix Signed-off-by: luofucong --- src/datatypes/src/json/value.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/datatypes/src/json/value.rs b/src/datatypes/src/json/value.rs index 8718d399fd..7ad223ef99 100644 --- a/src/datatypes/src/json/value.rs +++ b/src/datatypes/src/json/value.rs @@ -160,6 +160,16 @@ impl JsonVariant { } } + fn contains_empty_object(&self) -> bool { + match self { + JsonVariant::Array(array) => array.iter().any(JsonVariant::contains_empty_object), + JsonVariant::Object(object) => { + object.is_empty() || object.values().any(JsonVariant::contains_empty_object) + } + _ => false, + } + } + fn as_ref(&self) -> JsonVariantRef<'_> { match self { JsonVariant::Null => JsonVariantRef::Null, @@ -433,7 +443,7 @@ impl JsonValue { /// Returns an error if the value cannot be aligned without losing existing object fields or /// when a scalar type conversion is incompatible. pub(crate) fn try_align(&mut self, expected: &JsonNativeType) -> Result<()> { - if is_include(expected, self.json_type()) { + if is_include(expected, self.json_type()) && !self.json_variant.contains_empty_object() { return Ok(()); } @@ -896,6 +906,23 @@ mod tests { ]))) ); + // Empty objects have native type Null, but the value still needs alignment + // before converting into a typed struct value. + let expected = JsonNativeType::Object(JsonObjectType::from([( + "empty".to_string(), + JsonNativeType::Null, + )])); + let mut value = parse_json_value(r#"{"empty":{}}"#); + assert_eq!(value.json_type(), &expected); + value.try_align(&expected)?; + assert_eq!( + value, + JsonValue::from(JsonVariant::Object(BTreeMap::from([( + "empty".to_string(), + JsonVariant::Null, + )]))) + ); + // Object alignment should fail if the expected type misses any field from the value. let expected = JsonNativeType::Object(JsonObjectType::from([( "items".to_string(),