Skip to content

Commit

Permalink
AVRO-3827: [Rust] Disallow duplicate field names (#2433)
Browse files Browse the repository at this point in the history
* AVRO-3827: [Rust] Disallow duplicate field names

* Reuse BTreeMap.

* Use the returned Option.
  • Loading branch information
sarutak authored Aug 10, 2023
1 parent 7b50d06 commit 3deb73c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
3 changes: 3 additions & 0 deletions lang/rust/avro/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,9 @@ pub enum Error {
#[error("Invalid field name {0}")]
FieldName(String),

#[error("Duplicate field name {0}")]
FieldNameDuplicate(String),

#[error("Invalid schema name {0}. It must match the regex '{1}'")]
InvalidSchemaName(String, &'static str),

Expand Down
71 changes: 70 additions & 1 deletion lang/rust/avro/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,9 @@ impl Parser {
})?;

for field in &fields {
lookup.insert(field.name.clone(), field.position);
if let Some(_old) = lookup.insert(field.name.clone(), field.position) {
return Err(Error::FieldNameDuplicate(field.name.clone()));
}

if let Some(ref field_aliases) = field.aliases {
for alias in field_aliases {
Expand Down Expand Up @@ -5064,4 +5066,71 @@ mod tests {
other => Err(format!("Expected Error::FieldName, got {other:?}").into()),
}
}

#[test]
fn test_avro_3827_disallow_duplicate_field_names() -> TestResult {
let schema_str = r#"
{
"name": "my_schema",
"type": "record",
"fields": [
{
"name": "f1",
"type": {
"name": "a",
"type": "record",
"fields": []
}
}, {
"name": "f1",
"type": {
"name": "b",
"type": "record",
"fields": []
}
}
]
}
"#;

match Schema::parse_str(schema_str) {
Err(Error::FieldNameDuplicate(_)) => (),
other => {
return Err(format!("Expected Error::FieldNameDuplicate, got {other:?}").into())
}
};

let schema_str = r#"
{
"name": "my_schema",
"type": "record",
"fields": [
{
"name": "f1",
"type": {
"name": "a",
"type": "record",
"fields": [
{
"name": "f1",
"type": {
"name": "b",
"type": "record",
"fields": []
}
}
]
}
}
]
}
"#;

let expected = r#"{"name":"my_schema","type":"record","fields":[{"name":"f1","type":{"name":"a","type":"record","fields":[{"name":"f1","type":{"name":"b","type":"record","fields":[]}}]}}]}"#;
let schema = Schema::parse_str(schema_str)?;
let canonical_form = schema.canonical_form();
assert_eq!(canonical_form, expected);

Ok(())
}
}

0 comments on commit 3deb73c

Please sign in to comment.