Skip to content

[AVRO-4137, C#]: SpecificWriter Enum Name Matching #3388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Scylin232
Copy link

Description

Quote from AVRO-4137:

At the moment, the C# library Avro matches Union types with Enum in the following way:

// SpecificDefaultWriter.cs - LN159 - protected override bool Matches(Schema sc, object obj)

case Schema.Type.Enumeration:
   return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString());

This leads to the scenario where several Enums declared within one Union schema cannot have the same value names, because upon serialization, the Enum that is declared earlier will be chosen, not the one that was originally passed.

It is further suggested to conduct a check on the type name and the schema itself:

case Schema.Type.Enumeration:
  return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString()) && sc.Name == obj.GetType().Name;

If you believe that this could lead to unforeseen problems (such as breaking backward compatibility), it is proposed to make the check optional, by default turned off. There may be other, more reliable methods to solve this issue, but the demonstrated one seemed the most optimal in my mind 😃

Thank you!

What is the purpose of the change

This pull request introduces SpecificWriter's Enum matching by name, fixing AVRO-4137

Verifying this change

This change is already covered by existing tests.

Documentation

  • Does this pull request introduce a new feature? no

@github-actions github-actions bot added the C# label May 26, 2025
@@ -139,7 +139,7 @@
return obj is ISpecificRecord &&
((obj as ISpecificRecord).Schema as RecordSchema).SchemaName.Equals((sc as RecordSchema).SchemaName);
case Schema.Type.Enumeration:
return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString());
return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString()) && sc.Name.Equals(obj.GetType().Name);

Check warning

Code scanning / CodeQL

Dereferenced variable may be null Warning

Variable
obj
may be null at this access as suggested by
this
null check.
Variable
obj
may be null at this access as suggested by
this
null check.
@@ -209,7 +209,7 @@
return obj is ISpecificRecord &&
((obj as ISpecificRecord).Schema as RecordSchema).SchemaName.Equals((sc as RecordSchema).SchemaName);
case Schema.Type.Enumeration:
return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString());
return obj.GetType().IsEnum && (sc as EnumSchema).Symbols.Contains(obj.ToString()) && sc.Name.Equals(obj.GetType().Name);

Check warning

Code scanning / CodeQL

Dereferenced variable may be null Warning

Variable
obj
may be null at this access as suggested by
this
null check.
Variable
obj
may be null at this access as suggested by
this
null check.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant