diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs index 8799ebd6f60..b6f3b307b4d 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 @@ -6637,4 +6654,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(()) + } }