Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-1750

GenericDatum API behavior breaking change

VotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.7.7
    • 1.8.2
    • c++
    • None

    Description

      It appears that a change was introduced to the avro::GenericDatum
      implementation between 1.7.6 and 1.7.7 that causes unions to be handled
      differently.

      The 1.7.6 implementation does this:

      inline Type AVRO_DECL GenericDatum::type() const {
          return (type_ == AVRO_UNION) ?
              boost::any_cast<GenericUnion>(&value_)->type() : type_;
      }
      
      template<typename T>
      const T& GenericDatum::value() const {
          return (type_ == AVRO_UNION) ?
              boost::any_cast<GenericUnion>(&value_)->value<T>() :
              *boost::any_cast<T>(&value_);
      }
      
      template<typename T>
      T& GenericDatum::value() {
          return (type_ == AVRO_UNION) ?
              boost::any_cast<GenericUnion>(&value_)->value<T>() :
              *boost::any_cast<T>(&value_);
      }
      

      …whereas the 1.7.7 implementation does this:

      /**
       * The avro data type this datum holds.
       */
      Type type() const {
          return type_;
      }
      
      /**
       * Returns the value held by this datum.
       * T The type for the value. This must correspond to the
       * avro type returned by type().
       */
      template<typename T> const T& value() const {
          return *boost::any_cast<T>(&value_);
      }
      
      /**
       * Returns the reference to the value held by this datum, which
       * can be used to change the contents. Please note that only
       * value can be changed, the data type of the value held cannot
       * be changed.
       *
       * T The type for the value. This must correspond to the
       * avro type returned by type().
       */
      template<typename T> T& value() {
          return *boost::any_cast<T>(&value_);
      }
      

      The result of this is that, if the underlying value is an AVRO_UNION,
      calls to GenericDatum::type and GenericDatum::value<> that previously resolved to the union member type no longer do so (and user code relying on that behavior has been broken).

      This change apparently was made as part of the changes for AVRO-1474; however, looking at the comments in that issue, it's not clear to me why it was required for that fix.

      Attachments

        1. AVRO-1750.patch
          3 kB
          Thiruvalluvan M. G.

        Issue Links

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            thiru_mg Thiruvalluvan M. G.
            braden Braden Shepherdson
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment