Home | About | Sematext search-lucene.com search-hadoop.com
 Search Hadoop and all its subprojects:

Switch to Threaded View
Avro >> mail # user >> Direct conversion from Generic Record to Specific Record


Copy link to this message
-
Re: Direct conversion from Generic Record to Specific Record
SpecificData#deepCopy will make this conversion.  It currently fails
for enums, but the fix is easy.  Here's a patch that makes that fix
and demonstrates a conversion.  If this change is of interest, please
file an issue in Jira.

Doug

Index: lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
===================================================================
--- lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
(revision 1564561)
+++ lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
(working copy)
@@ -933,8 +933,7 @@
       case DOUBLE:
         return (T)new Double((Double)value);
       case ENUM:
-        // Enums are immutable; shallow copy will suffice
-        return value;
+        return (T)createEnum(value.toString(), schema);
       case FIXED:
         return (T)createFixed(null, ((GenericFixed) value).bytes(), schema);
       case FLOAT:
Index: lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java
===================================================================
--- lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java
(revision 1564561)
+++ lang/java/ipc/src/test/java/org/apache/avro/specific/TestSpecificData.java
(working copy)
@@ -40,6 +40,8 @@
 import org.apache.avro.test.MD5;
 import org.apache.avro.test.Kind;

+import org.apache.avro.generic.GenericRecord;
+
 public class TestSpecificData {

   @Test
@@ -95,6 +97,16 @@
         new SpecificDatumReader<Object>());
 }

+  @Test public void testConvertGenericToSpecific() {
+    GenericRecord generic = new GenericData.Record(TestRecord.SCHEMA$);
+    generic.put("name", "foo");
+    generic.put("kind", new GenericData.EnumSymbol(Kind.SCHEMA$, "BAR"));
+    generic.put("hash", new GenericData.Fixed
+                (MD5.SCHEMA$, new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5}));
+    TestRecord specific =
+      (TestRecord)SpecificData.get().deepCopy(TestRecord.SCHEMA$, generic);
+  }
+
   @Test public void testGetClassSchema() throws Exception {
     Assert.assertEquals(TestRecord.getClassSchema(), TestRecord.SCHEMA$);
     Assert.assertEquals(MD5.getClassSchema(), MD5.SCHEMA$);

On Thu, Feb 6, 2014 at 8:12 AM, Christophe Taton
<[EMAIL PROTECTED]> wrote:
> I believe we could eventually make a generic function that can rewrite any
> record or record builder, whether specific or generic, into another record
> or record builder, whether specific or generic.
>
> Until this happens, Mika's suggestion is probably the best short-term
> solution.
>
> C.
>
>
> On Wed, Feb 5, 2014 at 2:59 PM, Roger Hoover <[EMAIL PROTECTED]> wrote:
>>
>> Hi Christophe,
>>
>> Thanks for your reply.  When you say that we could write a generic
>> conversion function, do you mean we can write one that works for all
>> schemas?  That would be great!
>>
>> I'd like an API something like this:
>>
>> MyCustomRecord record = MyCustomRecord.newBuilder(GenericRecord
>> record).build()
>>
>> Thanks,
>>
>> Roger
>>
>>
>> On Wed, Feb 5, 2014 at 10:59 AM, Christophe Taton
>> <[EMAIL PROTECTED]> wrote:
>>>
>>> Hi Roger,
>>> With the change proposed in
>>> https://issues.apache.org/jira/browse/AVRO-1443, you would be able to create
>>> a specific record using a generic builder API. That means we could write a
>>> generic conversion function that creates specific records.
>>> Would that work for you?
>>> C.
>>>
>>>
>>> On Wed, Feb 5, 2014 at 10:23 AM, Roger Hoover <[EMAIL PROTECTED]>
>>> wrote:
>>>>
>>>> Hi,
>>>>
>>>> I'm working with an existing API that hands me a GenericRecord.  Is
>>>> there an easy way I can covert it into a SpecificRecord.  Really I want to
>>>> get it into the code-generated object.
>>>>
>>>> Thanks,
>>>>
>>>> Roger
>>>>
>>>>
>>>
>>
>