This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch avro-3814/schema-resolution-union
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to 
refs/heads/avro-3814/schema-resolution-union by this push:
     new c21718a21 AVRO-3814: Revert changes to validate_internal()
c21718a21 is described below

commit c21718a216bd3ff92b8d0522a3368e940bcacf42
Author: Martin Tzvetanov Grigorov <[email protected]>
AuthorDate: Tue Aug 15 10:17:45 2023 +0300

    AVRO-3814: Revert changes to validate_internal()
    
    Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
---
 lang/rust/avro/src/schema.rs |   1 -
 lang/rust/avro/src/types.rs  | 102 ++++++++++++-------------------------------
 lang/rust/avro/src/writer.rs |  10 +----
 3 files changed, 29 insertions(+), 84 deletions(-)

diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 0c3ce3351..d688473bd 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -838,7 +838,6 @@ impl UnionSchema {
                 collected_names.extend(resolved_names);
                 let namespace = &schema.namespace().or_else(|| 
enclosing_namespace.clone());
 
-                // Attempt to validate the value in order to ensure we've 
selected the right schema.
                 value
                     .clone()
                     .resolve_internal(schema, &collected_names, namespace, 
&None)
diff --git a/lang/rust/avro/src/types.rs b/lang/rust/avro/src/types.rs
index 2a812c3af..7e2c44e23 100644
--- a/lang/rust/avro/src/types.rs
+++ b/lang/rust/avro/src/types.rs
@@ -350,7 +350,7 @@ impl Value {
         schemata.iter().any(|schema| {
             let enclosing_namespace = schema.namespace();
 
-            match self.validate_internal(schema, rs.get_names(), 
&enclosing_namespace, false) {
+            match self.validate_internal(schema, rs.get_names(), 
&enclosing_namespace) {
                 Some(reason) => {
                     let log_message = format!(
                         "Invalid value: {:?} for schema: {:?}. Reason: {}",
@@ -386,7 +386,6 @@ impl Value {
         schema: &Schema,
         names: &HashMap<Name, S>,
         enclosing_namespace: &Namespace,
-        schema_resolution: bool,
     ) -> Option<String> {
         match (self, schema) {
             (_, Schema::Ref { name }) => {
@@ -399,14 +398,7 @@ impl Value {
                             names.keys()
                         ))
                     },
-                    |s| {
-                        self.validate_internal(
-                            s.borrow(),
-                            names,
-                            &name.namespace,
-                            schema_resolution,
-                        )
-                    },
+                    |s| self.validate_internal(s.borrow(), names, 
&name.namespace),
                 )
             }
             (&Value::Null, &Schema::Null) => None,
@@ -477,42 +469,24 @@ impl Value {
                 Schema::Enum(EnumSchema {
                     symbols, default, ..
                 }),
-            ) => {
-                if schema_resolution {
-                    // When resolving a schema the following rule applies:
-                    // if both are enums: if the writer’s symbol is not 
present in the reader’s enum and the reader has a default value,
-                    // then that value is used, otherwise an error is 
signalled.
-                    if symbols.contains(s) || default.is_some() {
-                        // If `s` is a symbol in the schema, or a default is 
available then the value is valid.
-                        None
+            ) => symbols
+                .get(i as usize)
+                .map(|ref symbol| {
+                    if symbol != &s {
+                        Some(format!("Symbol '{s}' is not at position '{i}'"))
                     } else {
-                        Some(format!(
-                            "Unknown symbol '{s}': no symbol to fallback to is 
available."
-                        ))
+                        None
                     }
-                } else {
-                    symbols
-                        .get(i as usize)
-                        .map(|ref symbol| {
-                            if symbol != &s {
-                                Some(format!("Symbol '{s}' is not at position 
'{i}'"))
-                            } else {
-                                None
-                            }
-                        })
-                        .unwrap_or_else(|| match default {
-                            Some(_) => None,
-                            None => Some(format!("No symbol at position 
'{i}'")),
-                        })
-                }
-            }
+                })
+                .unwrap_or_else(|| match default {
+                    Some(_) => None,
+                    None => Some(format!("No symbol at position '{i}'")),
+                }),
             // (&Value::Union(None), &Schema::Union(_)) => None,
             (&Value::Union(i, ref value), Schema::Union(inner)) => inner
                 .variants()
                 .get(i as usize)
-                .map(|schema| {
-                    value.validate_internal(schema, names, 
enclosing_namespace, schema_resolution)
-                })
+                .map(|schema| value.validate_internal(schema, names, 
enclosing_namespace))
                 .unwrap_or_else(|| Some(format!("No schema in the union at 
position '{i}'"))),
             (v, Schema::Union(inner)) => {
                 match inner.find_schema_with_known_schemata(v, Some(names), 
enclosing_namespace) {
@@ -523,19 +497,14 @@ impl Value {
             (Value::Array(items), Schema::Array(inner)) => 
items.iter().fold(None, |acc, item| {
                 Value::accumulate(
                     acc,
-                    item.validate_internal(inner, names, enclosing_namespace, 
schema_resolution),
+                    item.validate_internal(inner, names, enclosing_namespace),
                 )
             }),
             (Value::Map(items), Schema::Map(inner)) => {
                 items.iter().fold(None, |acc, (_, value)| {
                     Value::accumulate(
                         acc,
-                        value.validate_internal(
-                            inner,
-                            names,
-                            enclosing_namespace,
-                            schema_resolution,
-                        ),
+                        value.validate_internal(inner, names, 
enclosing_namespace),
                     )
                 })
             }
@@ -558,7 +527,7 @@ impl Value {
                         record_fields.len(),
                         non_nullable_fields_count
                     ));
-                } else if record_fields.len() > fields.len() && 
!schema_resolution {
+                } else if record_fields.len() > fields.len() {
                     return Some(format!(
                         "The value's records length ({}) is greater than the 
schema's ({} fields)",
                         record_fields.len(),
@@ -583,37 +552,20 @@ impl Value {
                                         &field.schema,
                                         names,
                                         record_namespace,
-                                        schema_resolution,
                                     ),
                                 )
                             }
-                            None => {
-                                if schema_resolution {
-                                    // While performing validation during 
schema resolution we allow
-                                    // extraneous fields to exist in the 
Value::Record, as these
-                                    // will get cleaned up later by the schema 
resolution logic.
-                                    acc
-                                } else {
-                                    Value::accumulate(
-                                        acc,
-                                        Some(format!(
-                                            "There is no schema field for 
field '{field_name}'"
-                                        )),
-                                    )
-                                }
-                            }
+                            None => Value::accumulate(
+                                acc,
+                                Some(format!("There is no schema field for 
field '{field_name}'")),
+                            ),
                         }
                     })
             }
             (Value::Map(items), Schema::Record(RecordSchema { fields, .. })) 
=> {
                 fields.iter().fold(None, |acc, field| {
                     if let Some(item) = items.get(&field.name) {
-                        let res = item.validate_internal(
-                            &field.schema,
-                            names,
-                            enclosing_namespace,
-                            schema_resolution,
-                        );
+                        let res = item.validate_internal(&field.schema, names, 
enclosing_namespace);
                         Value::accumulate(acc, res)
                     } else if !field.is_nullable() {
                         Value::accumulate(
@@ -1305,7 +1257,7 @@ mod tests {
 
         for (value, schema, valid, expected_err_message) in 
value_schema_valid.into_iter() {
             let err_message =
-                value.validate_internal::<Schema>(&schema, 
&HashMap::default(), &None, false);
+                value.validate_internal::<Schema>(&schema, 
&HashMap::default(), &None);
             assert_eq!(valid, err_message.is_none());
             if !valid {
                 let full_err_message = format!(
@@ -1509,12 +1461,12 @@ mod tests {
             ("f".to_string(), Value::String("foo".to_string())), // extraneous 
field
         ]);
         assert!(value
-            .validate_internal(&schema, rs.get_names(), &schema.namespace(), 
false)
+            .validate_internal(&schema, rs.get_names(), &schema.namespace())
             .is_some());
         // However, when applying schema resolution rules, the extraneous 
should be ignored by the validation logic.
-        assert!(value
-            .validate_internal(&schema, rs.get_names(), &schema.namespace(), 
true)
-            .is_none());
+        // assert!(value
+        //     .validate_internal(&schema, rs.get_names(), 
&schema.namespace(), true)
+        //     .is_none());
 
         let value = Value::Record(vec![
             ("b".to_string(), Value::String("foo".to_string())),
diff --git a/lang/rust/avro/src/writer.rs b/lang/rust/avro/src/writer.rs
index 79641ed0c..83e863455 100644
--- a/lang/rust/avro/src/writer.rs
+++ b/lang/rust/avro/src/writer.rs
@@ -425,7 +425,7 @@ fn write_avro_datum_schemata<T: Into<Value>>(
     let rs = ResolvedSchema::try_from(schemata)?;
     let names = rs.get_names();
     let enclosing_namespace = schema.namespace();
-    if let Some(_err) = avro.validate_internal(schema, names, 
&enclosing_namespace, false) {
+    if let Some(_err) = avro.validate_internal(schema, names, 
&enclosing_namespace) {
         return Err(Error::Validation);
     }
     encode_internal(&avro, schema, names, &enclosing_namespace, buffer)
@@ -544,12 +544,7 @@ fn write_value_ref_resolved(
     value: &Value,
     buffer: &mut Vec<u8>,
 ) -> AvroResult<()> {
-    match value.validate_internal(
-        schema,
-        resolved_schema.get_names(),
-        &schema.namespace(),
-        false,
-    ) {
+    match value.validate_internal(schema, resolved_schema.get_names(), 
&schema.namespace()) {
         Some(err) => Err(Error::ValidationWithReason(err)),
         None => encode_internal(
             value,
@@ -571,7 +566,6 @@ fn write_value_ref_owned_resolved(
         root_schema,
         resolved_schema.get_names(),
         &root_schema.namespace(),
-        false,
     ) {
         return Err(Error::ValidationWithReason(err));
     }

Reply via email to