You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@avro.apache.org by "Evan Blackwell (Jira)" <ji...@apache.org> on 2023/06/23 21:00:00 UTC
[jira] [Updated] (AVRO-3785) [Rust] Deserialization if reader schema has a namespace and a nullable record with a reference type
[ https://issues.apache.org/jira/browse/AVRO-3785?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Evan Blackwell updated AVRO-3785:
---------------------------------
Description:
When providing from_avro_datum with a reader schema that has a namespace defined and contains a type that is nullable or a record with an enum that is defined elsewhere in the schema, a SchemaResolutionError is returned because the namespace gets lost somewhere along the way.
Likely related to AVRO 3755
Example test where this fails
{code:java}
#[test]
fn deserialize_namespace_with_nullable_type_containing_reference_type() -> TestResult {
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct BarUseParent {
#[serde(rename = "barUse")]
pub bar_use: Bar,
}
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, serde::Deserialize, serde::Serialize)]
pub enum Bar {
#[serde(rename = "bar0")]
Bar0,
#[serde(rename = "bar1")]
Bar1,
#[serde(rename = "bar2")]
Bar2,
}
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct Foo {
#[serde(rename = "barInit")]
pub bar_init: Bar,
#[serde(rename = "barUseParent")]
pub bar_use_parent: Option<BarUseParent>,
}
let writer_schema = r#"{
"type": "record",
"name": "Foo",
"namespace": "name.space",
"fields":
[
{
"name": "barInit",
"type":
{
"type": "enum",
"name": "Bar",
"symbols":
[
"bar0",
"bar1",
"bar2"
]
}
},
{
"name": "barUseParent",
"type": [
"null",
{
"type": "record",
"name": "BarUseParent",
"fields": [
{
"name": "barUse",
"type": "Bar"
}
]
}
]
}
]
}"#;
let reader_schema = r#"{
"type": "record",
"name": "Foo",
"namespace": "name.space",
"fields":
[
{
"name": "barInit",
"type":
{
"type": "enum",
"name": "Bar",
"symbols":
[
"bar0",
"bar1"
]
}
},
{
"name": "barUseParent",
"type": [
"null",
{
"type": "record",
"name": "BarUseParent",
"fields": [
{
"name": "barUse",
"type": "Bar"
}
]
}
]
}
]
}"#;
let writer_schema = Schema::parse_str(writer_schema)?;
let foo = Foo {
bar_init: Bar::Bar0,
bar_use_parent: Some(BarUseParent { bar_use: Bar::Bar1} ),
};
let avro_value = crate::to_value(foo)?;
assert!(
avro_value.validate(&writer_schema),
"value is valid for schema",
);
let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
let mut x = &datum[..];
let reader_schema = Schema::parse_str(reader_schema)?;
let deser_value = crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema))?;
match deser_value {
types::Value::Record(fields) => {
assert_eq!(fields.len(), 2);
}
_ => panic!("Expected Value::Record"),
}
Ok(()) } {code}
Error returned: Schema didn't successfully parse: SchemaResolutionError(Name \{ name: "Bar", namespace: None })
was:
When providing from_avro_datum with a reader schema that has a namespace defined and contains a type that is nullable or a record with an enum that is defined elsewhere in the schema, a SchemaResolutionError is returned because the namespace gets lost somewhere along the way.
Likely related to AVRO 3755
Example test where this fails
{code:java}
#[test]
fn deserialize_namespace_with_nullable_type_containing_reference_type() -> TestResult {
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct BarUseParent {
#[serde(rename = "barUse")]
pub bar_use: Bar,
}
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, serde::Deserialize, serde::Serialize)]
pub enum Bar {
#[serde(rename = "bar0")]
Bar0,
#[serde(rename = "bar1")]
Bar1,
#[serde(rename = "bar2")]
Bar2,
}
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct Foo {
#[serde(rename = "barInit")]
pub bar_init: Bar,
#[serde(rename = "barUseParent")]
pub bar_use_parent: Option<BarUseParent>,
}
let writer_schema = r#"{
"type": "record",
"name": "Foo",
"namespace": "name.space",
"fields":
[
{
"name": "barInit",
"type":
{
"type": "enum",
"name": "Bar",
"symbols":
[
"bar0",
"bar1",
"bar2"
]
}
},
{
"name": "barUseParent",
"type": [
"null",
{
"type": "record",
"name": "BarUseParent",
"fields": [
{
"name": "barUse",
"type": "Bar"
}
]
}
]
}
]
}"#;
let reader_schema = r#"{
"type": "record",
"name": "Foo",
"namespace": "name.space",
"fields":
[
{
"name": "barInit",
"type":
{
"type": "enum",
"name": "Bar",
"symbols":
[
"bar0",
"bar1"
]
}
},
{
"name": "barUseParent",
"type": [
"null",
{
"type": "record",
"name": "BarUseParent",
"fields": [
{
"name": "barUse",
"type": "Bar"
}
]
}
]
}
]
}"#;
let writer_schema = Schema::parse_str(writer_schema)?;
let foo = Foo {
bar_init: Bar::Bar0,
bar_use_parent: Some(BarUseParent { bar_use: Bar::Bar1} ),
};
let avro_value = crate::to_value(foo)?;
assert!(
avro_value.validate(&writer_schema),
"value is valid for schema",
);
let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
let mut x = &datum[..];
let reader_schema = Schema::parse_str(reader_schema)?;
let deser_value = crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema))?;
match deser_value {
types::Value::Record(fields) => {
assert_eq!(fields.len(), 2);
assert_eq!(fields[0].0, "barInit");
assert_eq!(fields[0].1, types::Value::Enum(0, "bar0".to_string()));
assert_eq!(fields[1].0, "barUse");
assert_eq!(fields[1].1, types::Value::Enum(1, "bar1".to_string()));
}
_ => panic!("Expected Value::Record"),
}
Ok(()) } {code}
Error returned: Schema didn't successfully parse: SchemaResolutionError(Name \{ name: "Bar", namespace: None })
> [Rust] Deserialization if reader schema has a namespace and a nullable record with a reference type
> ---------------------------------------------------------------------------------------------------
>
> Key: AVRO-3785
> URL: https://issues.apache.org/jira/browse/AVRO-3785
> Project: Apache Avro
> Issue Type: Bug
> Components: rust
> Reporter: Evan Blackwell
> Priority: Major
>
> When providing from_avro_datum with a reader schema that has a namespace defined and contains a type that is nullable or a record with an enum that is defined elsewhere in the schema, a SchemaResolutionError is returned because the namespace gets lost somewhere along the way.
>
> Likely related to AVRO 3755
>
> Example test where this fails
>
> {code:java}
> #[test]
> fn deserialize_namespace_with_nullable_type_containing_reference_type() -> TestResult {
> #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
> pub struct BarUseParent {
> #[serde(rename = "barUse")]
> pub bar_use: Bar,
> }
> #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, serde::Deserialize, serde::Serialize)]
> pub enum Bar {
> #[serde(rename = "bar0")]
> Bar0,
> #[serde(rename = "bar1")]
> Bar1,
> #[serde(rename = "bar2")]
> Bar2,
> }
> #[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
> pub struct Foo {
> #[serde(rename = "barInit")]
> pub bar_init: Bar,
> #[serde(rename = "barUseParent")]
> pub bar_use_parent: Option<BarUseParent>,
> }
> let writer_schema = r#"{
> "type": "record",
> "name": "Foo",
> "namespace": "name.space",
> "fields":
> [
> {
> "name": "barInit",
> "type":
> {
> "type": "enum",
> "name": "Bar",
> "symbols":
> [
> "bar0",
> "bar1",
> "bar2"
> ]
> }
> },
> {
> "name": "barUseParent",
> "type": [
> "null",
> {
> "type": "record",
> "name": "BarUseParent",
> "fields": [
> {
> "name": "barUse",
> "type": "Bar"
> }
> ]
> }
> ]
> }
> ]
> }"#;
> let reader_schema = r#"{
> "type": "record",
> "name": "Foo",
> "namespace": "name.space",
> "fields":
> [
> {
> "name": "barInit",
> "type":
> {
> "type": "enum",
> "name": "Bar",
> "symbols":
> [
> "bar0",
> "bar1"
> ]
> }
> },
> {
> "name": "barUseParent",
> "type": [
> "null",
> {
> "type": "record",
> "name": "BarUseParent",
> "fields": [
> {
> "name": "barUse",
> "type": "Bar"
> }
> ]
> }
> ]
> }
> ]
> }"#;
> let writer_schema = Schema::parse_str(writer_schema)?;
> let foo = Foo {
> bar_init: Bar::Bar0,
> bar_use_parent: Some(BarUseParent { bar_use: Bar::Bar1} ),
> };
> let avro_value = crate::to_value(foo)?;
> assert!(
> avro_value.validate(&writer_schema),
> "value is valid for schema",
> );
> let datum = crate::to_avro_datum(&writer_schema, avro_value)?;
> let mut x = &datum[..];
> let reader_schema = Schema::parse_str(reader_schema)?;
> let deser_value = crate::from_avro_datum(&writer_schema, &mut x, Some(&reader_schema))?;
> match deser_value {
> types::Value::Record(fields) => {
> assert_eq!(fields.len(), 2);
> }
> _ => panic!("Expected Value::Record"),
> }
> Ok(()) } {code}
>
> Error returned: Schema didn't successfully parse: SchemaResolutionError(Name \{ name: "Bar", namespace: None })
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)