You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@avro.apache.org by "ASF subversion and git services (Jira)" <ji...@apache.org> on 2025/06/12 06:28:00 UTC

[jira] [Commented] (AVRO-3989) Schema conversion for logical types ignored when type is part of union

    [ https://issues.apache.org/jira/browse/AVRO-3989?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17965480#comment-17965480 ] 

ASF subversion and git services commented on AVRO-3989:
-------------------------------------------------------

Commit f131a5c501a20de563014ce0c17fae02ef69519a in avro's branch refs/heads/main from Harshit Mittal
[ https://gitbox.apache.org/repos/asf?p=avro.git;h=f131a5c501 ]

AVRO-3989: [java] add conversion classes to default instance of SpecificData (#3354)

* AVRO-3989: [java] add conversion classes to default instance of SpecificData

* add test case, exclude decimal conversion

* review comment: use schema from the generated class for `fooBar.avsc`

* add logical type conversion classes to ReflectData as well

* refactor to single method

---------

Co-authored-by: Harshit Mittal <hm...@netflix.com>

> Schema conversion for logical types ignored when type is part of union
> ----------------------------------------------------------------------
>
>                 Key: AVRO-3989
>                 URL: https://issues.apache.org/jira/browse/AVRO-3989
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: java
>    Affects Versions: 1.11.3
>            Reporter: Jacob Stampe Mikkelsen
>            Priority: Major
>              Labels: pull-request-available
>         Attachments: image-2024-06-02-21-32-25-461.png
>
>          Time Spent: 1h 50m
>  Remaining Estimate: 0h
>
> I have a schema with an optional timestamp which is to be rendered as millis and the generated Java class fails to get the conversions array and method added, which means that at runtime I get a ClassCastException when an "Instant" object is cast to a "Long" because there was no registered converter:
> The element with an optional timestamp in my schema:
> {{{}}
> {{  "name": "DecisionStartTime",}}
> {{  "type": [}}
> {{    "null",}}
> {{    {}}
> {{      "type": "long",}}
> {{      "logicalType": "timestamp-millis"}}
> {{    }}}
> {{  ],}}
> {{  "default": null}}
> {{}}}
> The problem seems to be here:
> [https://github.com/apache/avro/blame/5a60b5c43fe9c3bb40f4a1303913fdb3598bd4a5/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm#L198]
> Which only renders the conversion part if any of the fields has logicalType set and the actual method:
> [https://github.com/apache/avro/blob/5a60b5c43fe9c3bb40f4a1303913fdb3598bd4a5/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java#L976C3-L983C4]
> Does not take into account that a field which is a union does not have a logical type, however one of the union types might.
> *Proposed solution* - replace method
> {{  public boolean hasLogicalTypeField(Schema schema) {}}
> {{    for (Schema.Field field : schema.getFields()) {}}
> {{      if (field.schema().getLogicalType() != null) {}}
> {{        return true;}}
> {{      }}}
> {{    }}}
> {{    return false;}}
> {{  }}}
> With a method like this:
> {{  public boolean hasLogicalTypeField(Schema schema) {}}
> {{    for (Schema.Field field : schema.getFields()) {}}
> {{      if (field.schema().getLogicalType() != null) {}}
> {{        return true;}}
> {{      } else if (field.schema().type == Type.UNION) {}}
> {{        for (Schema type : field.schema().getTypes()) {}}
> {{          if (type.getLogicalType() != null) {}}
> {{            return true;}}
> {{          }}}
> {{        }}}
> {{      }}}
> {{    }}}
> {{    return false;}}
> {{  }}}
> The conversionInstance() method might also need tweaking in order to identify that the given type has a logical type as part of the union.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)