From db6cbe1fcf4b095d82cd11edcb702ae01afffcb3 Mon Sep 17 00:00:00 2001 From: Martin Grigorov Date: Mon, 26 Feb 2024 14:26:57 +0200 Subject: [PATCH] AVRO-3946: [Rust] Log warning/error for strange union types (#2767) A Union schema without any variants will log an ERROR from now on. A Union schema with a single variant will log a WARN suggesting to drop the union. Signed-off-by: Martin Tzvetanov Grigorov --- lang/rust/avro/src/schema.rs | 71 +++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs index 58bdc6ab1e6..f16b002ae18 100644 --- a/lang/rust/avro/src/schema.rs +++ b/lang/rust/avro/src/schema.rs @@ -1606,6 +1606,8 @@ impl Parser { self.register_resolving_schema(&fully_qualified_name, &aliases); + debug!("Going to parse record schema: {:?}", &fully_qualified_name); + let fields: Vec = fields_opt .and_then(|fields| fields.as_array()) .ok_or(Error::GetRecordFieldsJson) @@ -1786,7 +1788,22 @@ impl Parser { .iter() .map(|v| self.parse(v, enclosing_namespace)) .collect::, _>>() - .and_then(|schemas| Ok(Schema::Union(UnionSchema::new(schemas)?))) + .and_then(|schemas| { + if schemas.is_empty() { + error!( + "Union schemas should have at least two members! \ + Please enable debug logging to find out which Record schema \ + declares the union with 'RUST_LOG=apache_avro::schema=debug'." + ); + } else if schemas.len() == 1 { + warn!( + "Union schema with just one member! Consider dropping the union! \ + Please enable debug logging to find out which Record schema \ + declares the union with 'RUST_LOG=apache_avro::schema=debug'." + ); + } + Ok(Schema::Union(UnionSchema::new(schemas)?)) + }) } /// Parse a `serde_json::Value` representing a Avro fixed type into a @@ -6639,4 +6656,56 @@ mod tests { Ok(()) } + + #[test] + fn avro_3946_union_with_single_type() -> TestResult { + let schema = r#" + { + "type": "record", + "name": "Issue", + "namespace": "invalid.example", + "fields": [ + { + "name": "myField", + "type": ["long"] + } + ] + }"#; + + let _ = Schema::parse_str(schema)?; + + assert_logged( + "Union schema with just one member! Consider dropping the union! \ + Please enable debug logging to find out which Record schema \ + declares the union with 'RUST_LOG=apache_avro::schema=debug'.", + ); + + Ok(()) + } + + #[test] + fn avro_3946_union_without_any_types() -> TestResult { + let schema = r#" + { + "type": "record", + "name": "Issue", + "namespace": "invalid.example", + "fields": [ + { + "name": "myField", + "type": [] + } + ] + }"#; + + let _ = Schema::parse_str(schema)?; + + assert_logged( + "Union schemas should have at least two members! \ + Please enable debug logging to find out which Record schema \ + declares the union with 'RUST_LOG=apache_avro::schema=debug'.", + ); + + Ok(()) + } }