You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@avro.apache.org by Patrick Nip <pn...@yahoo-inc.com> on 2014/09/15 06:45:17 UTC

How to update an union field genericly

I am trying to use the c++ generic interface to update the following record:


{

    "type": "record",

    "namespace": "com.abc.v1",

    "name": “def",

    "fields": [

        {

            "name": "id",

            "type": [

                "null",

                "bytes"

            ]

        }

    ]

}


The following is the way that I try to do the update is through the GenericDatum. The code compile but when throw an exception of:


uncaught exception of type N4avro9ExceptionE

- Not that many names


std::vector<uint8_t> postdata;

uint8_t idarray[] = { 35, 36, 37, 38 };

std::copy( idarray, idarray + 3, std::back_inserter( postdata ));



avro::GenericDatum dat( schema ); // dat was filled with null by default

dat.setFieldAt(0, postdata); // trying to replace the null with bytes


std::auto_ptr<avro::OutputStream> out = avro::fileOutputStream( "/tmp/fout" );

avro::EncoderPtr en = avro::jsonEncoder( schema );

en->init ( *out );

avro::encode ( *en, dat );




Re: How to update an union field genericly

Posted by Patrick Nip <pn...@yahoo-inc.com>.
Completed code sample:


#include "attributes.hh"

#include "avro/Encoder.hh"

#include "avro/Decoder.hh"

#include <boost/algorithm/string.hpp>

#include <boost/typeof/typeof.hpp>

#include <iomanip>

#include <vector>

#include <fstream>

#include "avro/Compiler.hh"

#include "avro/Generic.hh"

#include "avro/Schema.hh"


int

main(int argc, char ** argv)

{

  avro::ValidSchema schema;

  std::ifstream ifs("unit/id.json");

  avro::compileJsonSchema(ifs, schema);



  std::vector<uint8_t> postdata;

  uint8_t idarray[] = { 35, 36, 37, 38 };

  std::copy( idarray, idarray + 3, std::back_inserter( postdata ));



  avro::GenericDatum dat( schema ); // dat was filled with null by default

  avro::GenericRecord& datr = dat.value<avro::GenericRecord>();


  datr.setFieldAt(0, postdata); // trying to replace the null with bytes


  std::auto_ptr<avro::OutputStream> out = avro::fileOutputStream( "/tmp/fout" );

  avro::EncoderPtr en = avro::jsonEncoder( schema );

  en->init ( *out );

  avro::encode ( *en, dat );



  return 0;

}


Result:


[pnip =>avro_rhel6<= avro]$ ./schemaTest

terminate called after throwing an instance of 'avro::Exception'

  what():  Invalid operation. Expected: Bytes got Union

Aborted

[pnip =>avro_rhel6<= avro]$

From: Yahoo <pn...@yahoo-inc.com>>
Reply-To: "user@avro.apache.org<ma...@avro.apache.org>" <us...@avro.apache.org>>
Date: Sunday, September 14, 2014 at 9:45 PM
To: "user@avro.apache.org<ma...@avro.apache.org>" <us...@avro.apache.org>>
Subject: How to update an union field genericly


I am trying to use the c++ generic interface to update the following record:


{

    "type": "record",

    "namespace": "com.abc.v1",

    "name": “def",

    "fields": [

        {

            "name": "id",

            "type": [

                "null",

                "bytes"

            ]

        }

    ]

}


The following is the way that I try to do the update is through the GenericDatum. The code compile but when throw an exception of:


uncaught exception of type N4avro9ExceptionE

- Not that many names


std::vector<uint8_t> postdata;

uint8_t idarray[] = { 35, 36, 37, 38 };

std::copy( idarray, idarray + 3, std::back_inserter( postdata ));



avro::GenericDatum dat( schema ); // dat was filled with null by default

dat.setFieldAt(0, postdata); // trying to replace the null with bytes


std::auto_ptr<avro::OutputStream> out = avro::fileOutputStream( "/tmp/fout" );

avro::EncoderPtr en = avro::jsonEncoder( schema );

en->init ( *out );

avro::encode ( *en, dat );