You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2022/09/07 08:20:17 UTC
[avro] 01/01: AVRO-3625: [Rust] UnionSchema is nullable if any of its variants is Null
This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch avro-3625-union-schema-is-nullable
in repository https://gitbox.apache.org/repos/asf/avro.git
commit 9b968c4726c8c660195146c118131825cbdd6ba0
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Wed Sep 7 11:19:25 2022 +0300
AVRO-3625: [Rust] UnionSchema is nullable if any of its variants is Null
Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
lang/rust/Cargo.lock | 2 +-
lang/rust/avro/Cargo.toml | 2 +-
lang/rust/avro/src/schema.rs | 114 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 114 insertions(+), 4 deletions(-)
diff --git a/lang/rust/Cargo.lock b/lang/rust/Cargo.lock
index 24c4024cc..794a8b74f 100644
--- a/lang/rust/Cargo.lock
+++ b/lang/rust/Cargo.lock
@@ -31,7 +31,7 @@ checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
[[package]]
name = "apache-avro"
-version = "0.14.0"
+version = "0.15.0"
dependencies = [
"anyhow",
"apache-avro-derive",
diff --git a/lang/rust/avro/Cargo.toml b/lang/rust/avro/Cargo.toml
index 4cca09d4d..e65a30bc4 100644
--- a/lang/rust/avro/Cargo.toml
+++ b/lang/rust/avro/Cargo.toml
@@ -17,7 +17,7 @@
[package]
name = "apache-avro"
-version = "0.14.0"
+version = "0.15.0"
authors = ["Apache Avro team <de...@avro.apache.org>"]
description = "A library for working with Apache Avro in Rust"
license = "Apache-2.0"
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 26868524a..bbf13138d 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -678,9 +678,9 @@ impl UnionSchema {
&self.schemas
}
- /// Returns true if the first variant of this `UnionSchema` is `Null`.
+ /// Returns true if the any of the variants of this `UnionSchema` is `Null`.
pub fn is_nullable(&self) -> bool {
- !self.schemas.is_empty() && self.schemas[0] == Schema::Null
+ !self.schemas.is_empty() && self.schemas.iter().any(|s| s == &Schema::Null)
}
/// Optionally returns a reference to the schema matched by this value, as well as its position
@@ -4092,4 +4092,114 @@ mod tests {
_ => panic!("Expected Schema::Record"),
}
}
+
+ #[test]
+ fn avro_3625_null_is_first() {
+ let schema_str = String::from(
+ r#"
+ {
+ "type": "record",
+ "name": "union_schema_test",
+ "fields": [
+ {"name": "a", "type": ["null", "long"], "default": null}
+ ]
+ }
+ "#,
+ );
+
+ let schema = Schema::parse_str(&schema_str).unwrap();
+
+ match schema {
+ Schema::Record { name, fields, .. } => {
+ assert_eq!(name, Name::new("union_schema_test").unwrap());
+ assert_eq!(fields.len(), 1);
+ let field = &fields[0];
+ assert_eq!(&field.name, "a");
+ assert_eq!(&field.default, &Some(Value::Null));
+ match &field.schema {
+ Schema::Union(union) => {
+ assert_eq!(union.variants().len(), 2);
+ assert!(union.is_nullable());
+ assert_eq!(union.variants()[0], Schema::Null);
+ assert_eq!(union.variants()[1], Schema::Long);
+ }
+ _ => panic!("Expected Schema::Union"),
+ }
+ }
+ _ => panic!("Expected Schema::Record"),
+ }
+ }
+
+ #[test]
+ fn avro_3625_null_is_last() {
+ let schema_str = String::from(
+ r#"
+ {
+ "type": "record",
+ "name": "union_schema_test",
+ "fields": [
+ {"name": "a", "type": ["long","null"], "default": 123}
+ ]
+ }
+ "#,
+ );
+
+ let schema = Schema::parse_str(&schema_str).unwrap();
+
+ match schema {
+ Schema::Record { name, fields, .. } => {
+ assert_eq!(name, Name::new("union_schema_test").unwrap());
+ assert_eq!(fields.len(), 1);
+ let field = &fields[0];
+ assert_eq!(&field.name, "a");
+ assert_eq!(&field.default, &Some(json!(123)));
+ match &field.schema {
+ Schema::Union(union) => {
+ assert_eq!(union.variants().len(), 2);
+ assert_eq!(union.variants()[0], Schema::Long);
+ assert_eq!(union.variants()[1], Schema::Null);
+ }
+ _ => panic!("Expected Schema::Union"),
+ }
+ }
+ _ => panic!("Expected Schema::Record"),
+ }
+ }
+
+ #[test]
+ fn avro_3625_null_is_the_middle() {
+ let schema_str = String::from(
+ r#"
+ {
+ "type": "record",
+ "name": "union_schema_test",
+ "fields": [
+ {"name": "a", "type": ["long","null","int"], "default": 123}
+ ]
+ }
+ "#,
+ );
+
+ let schema = Schema::parse_str(&schema_str).unwrap();
+
+ match schema {
+ Schema::Record { name, fields, .. } => {
+ assert_eq!(name, Name::new("union_schema_test").unwrap());
+ assert_eq!(fields.len(), 1);
+ let field = &fields[0];
+ assert_eq!(&field.name, "a");
+ assert_eq!(&field.default, &Some(json!(123)));
+ match &field.schema {
+ Schema::Union(union) => {
+ assert_eq!(union.variants().len(), 3);
+ assert_eq!(union.variants()[0], Schema::Long);
+ assert_eq!(union.variants()[1], Schema::Null);
+ assert_eq!(union.variants()[2], Schema::Int);
+ }
+ _ => panic!("Expected Schema::Union"),
+ }
+ }
+ _ => panic!("Expected Schema::Record"),
+ }
+ }
}