This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/branch-1.11 by this push:
new ffa145c9a AVRO-3780: [Rust] Bug: decimal logical type usage through
Fixed (#2283)
ffa145c9a is described below
commit ffa145c9ab4d8b4600406f82dd52427a61eb5aed
Author: theo <[email protected]>
AuthorDate: Wed Jun 14 13:16:49 2023 +0300
AVRO-3780: [Rust] Bug: decimal logical type usage through Fixed (#2283)
* feat: add failing test case
* AVRO-3780: Fix parsing of `decimal` logical schema with `fixed`
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
---------
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Co-authored-by: Fedor Telnov <[email protected]>
Co-authored-by: Martin Tzvetanov Grigorov <[email protected]>
(cherry picked from commit 12d0655adaf232b82b4ca529ee985508950049d1)
---
lang/rust/avro/src/error.rs | 5 ++++-
lang/rust/avro/src/schema.rs | 44 ++++++++++++++++++++++++++++++++++++++++----
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/lang/rust/avro/src/error.rs b/lang/rust/avro/src/error.rs
index 4f7098d2f..17e2c4e8e 100644
--- a/lang/rust/avro/src/error.rs
+++ b/lang/rust/avro/src/error.rs
@@ -313,7 +313,10 @@ pub enum Error {
#[error("No `values` in map")]
GetMapValuesField,
- #[error("No `size` in fixed")]
+ #[error("Fixed schema `size` value must be a positive integer: {0}")]
+ GetFixedSizeFieldPositive(serde_json::Value),
+
+ #[error("Fixed schema has no `size`")]
GetFixedSizeField,
#[error("Failed to compress with flate")]
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 5b6e56505..aa5013ffb 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -1139,7 +1139,12 @@ impl Parser {
) -> AvroResult<Schema> {
match complex.get("type") {
Some(value) => {
- let ty = parser.parse(value, enclosing_namespace)?;
+ let ty = match value {
+ Value::String(s) if s == "fixed" => {
+ parser.parse_fixed(complex, enclosing_namespace)?
+ }
+ _ => parser.parse(value, enclosing_namespace)?,
+ };
if kinds
.iter()
@@ -1576,9 +1581,12 @@ impl Parser {
_ => None,
});
- let size = size_opt
- .and_then(|v| v.as_i64())
- .ok_or(Error::GetFixedSizeField)?;
+ let size = match size_opt {
+ Some(size) => size
+ .as_u64()
+ .ok_or_else(|| Error::GetFixedSizeFieldPositive(size.clone())),
+ None => Err(Error::GetFixedSizeField),
+ }?;
let name = Name::parse(complex)?;
let fully_qualified_name =
name.fully_qualified_name(enclosing_namespace);
@@ -4679,4 +4687,32 @@ mod tests {
Ok(())
}
+
+ #[test]
+ fn test_avro_3780_decimal_schema_type_with_fixed() -> TestResult {
+ let schema = json!(
+ {
+ "type": "record",
+ "name": "recordWithDecimal",
+ "fields": [
+ {
+ "name": "decimal",
+ "type": "fixed",
+ "name": "nestedFixed",
+ "size": 8,
+ "logicalType": "decimal",
+ "precision": 4
+ }
+ ]
+ });
+
+ let parse_result = Schema::parse(&schema);
+ assert!(
+ parse_result.is_ok(),
+ "parse result must be ok, got: {:?}",
+ parse_result
+ );
+
+ Ok(())
+ }
}