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/01/05 11:37:52 UTC
[avro] branch master updated: AVRO-3216 Reuse records' schema by name (#1345)
This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/master by this push:
new b76a437 AVRO-3216 Reuse records' schema by name (#1345)
b76a437 is described below
commit b76a437b970889255703ff48f7ee5981dfbcc17a
Author: Martin Grigorov <ma...@users.noreply.github.com>
AuthorDate: Wed Jan 5 13:37:26 2022 +0200
AVRO-3216 Reuse records' schema by name (#1345)
* AVRO-3197 Fallback to the 'type' when the logical type does not support the type
Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
* AVRO-3197 Allow only when the "type" is "string"
* AVRO-3197 Handle problematic complex type for date/time logical types
Read the complex type recursively. It seems Avro Java may produce {"type": {"type": "string", "avro.java.string": "String"}, "logicalType": "timestamp-millis"}}, i.e. logicalType is on the same level as the outer "type"
Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
* AVRO-3216 Allow to reuse record's schema by name
* AVRO-3216 Extend the test case to do more assertions
* AVRO-3216 Print err with Debug
---
lang/rust/src/schema.rs | 10 ++++--
lang/rust/tests/io.rs | 2 +-
lang/rust/tests/schema.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 92 insertions(+), 6 deletions(-)
diff --git a/lang/rust/src/schema.rs b/lang/rust/src/schema.rs
index bab99d4..da8c0c3 100644
--- a/lang/rust/src/schema.rs
+++ b/lang/rust/src/schema.rs
@@ -785,12 +785,16 @@ impl Parser {
lookup.insert(field.name.clone(), field.position);
}
- Ok(Schema::Record {
- name,
+ let schema = Schema::Record {
+ name: name.clone(),
doc: complex.doc(),
fields,
lookup,
- })
+ };
+
+ self.parsed_schemas
+ .insert(name.fullname(None), schema.clone());
+ Ok(schema)
}
/// Parse a `serde_json::Value` representing a Avro enum type into a
diff --git a/lang/rust/tests/io.rs b/lang/rust/tests/io.rs
index 93edf0d..c1ab1d7 100644
--- a/lang/rust/tests/io.rs
+++ b/lang/rust/tests/io.rs
@@ -319,6 +319,6 @@ fn test_type_exception() -> Result<(), String> {
match encoded {
Ok(_) => Err(String::from("Expected ValidationError, got Ok")),
Err(Error::Validation) => Ok(()),
- Err(ref e) => Err(format!("Expected ValidationError, got {}", e)),
+ Err(ref e) => Err(format!("Expected ValidationError, got {:?}", e)),
}
}
diff --git a/lang/rust/tests/schema.rs b/lang/rust/tests/schema.rs
index efd9df2..d9fdefc 100644
--- a/lang/rust/tests/schema.rs
+++ b/lang/rust/tests/schema.rs
@@ -15,8 +15,10 @@
// specific language governing permissions and limitations
// under the License.
-//! Port of https://github.com/apache/avro/blob/release-1.9.1/lang/py/test/test_schema.py
-use avro_rs::{schema::Name, Error, Schema};
+use avro_rs::{
+ schema::{Name, RecordField},
+ Error, Schema,
+};
use lazy_static::lazy_static;
fn init() {
@@ -830,6 +832,86 @@ fn test_parse_list_with_cross_deps_and_namespaces_error() {
let _ = Schema::parse_list(&schema_strs_second).expect_err("Test failed");
}
+#[test]
+// <https://issues.apache.org/jira/browse/AVRO-3216>
+// test that field's RecordSchema could be referenced by a following field by full name
+fn test_parse_reused_record_schema_by_fullname() {
+ init();
+ let schema_str = r#"
+ {
+ "type" : "record",
+ "name" : "Weather",
+ "namespace" : "test",
+ "doc" : "A weather reading.",
+ "fields" : [
+ {
+ "name" : "station",
+ "type" : {
+ "type" : "string",
+ "avro.java.string" : "String"
+ }
+ },
+ {
+ "name" : "max_temp",
+ "type" : {
+ "type" : "record",
+ "name" : "Temp",
+ "namespace": "prefix",
+ "doc" : "A temperature reading.",
+ "fields" : [ {
+ "name" : "temp",
+ "type" : "long"
+ } ]
+ }
+ }, {
+ "name" : "min_temp",
+ "type" : "prefix.Temp"
+ }
+ ]
+ }
+ "#;
+
+ let schema = Schema::parse_str(schema_str);
+ assert!(schema.is_ok());
+ match schema.unwrap() {
+ Schema::Record {
+ ref name,
+ doc: _,
+ ref fields,
+ lookup: _,
+ } => {
+ assert_eq!(name.fullname(None), "test.Weather", "Name does not match!");
+
+ assert_eq!(fields.len(), 3, "The number of the fields is not correct!");
+
+ let RecordField {
+ ref name,
+ doc: _,
+ default: _,
+ ref schema,
+ order: _,
+ position: _,
+ } = fields.get(2).unwrap();
+
+ assert_eq!(name, "min_temp");
+
+ match schema {
+ Schema::Record {
+ ref name,
+ doc: _,
+ ref fields,
+ lookup: _,
+ } => {
+ assert_eq!(name.fullname(None), "prefix.Temp", "Name does not match!");
+ assert_eq!(fields.len(), 1, "The number of the fields is not correct!");
+ }
+ unexpected => unreachable!("Unexpected schema type: {:?}", unexpected),
+ }
+ }
+ unexpected => unreachable!("Unexpected schema type: {:?}", unexpected),
+ }
+}
+
/// Return all permutations of an input slice
fn permutations<T>(list: &[T]) -> Vec<Vec<&T>> {
let size = list.len();