Proposed change in AvroSchema to handle circular references.#445
Proposed change in AvroSchema to handle circular references.#445wernerdaehn wants to merge 1 commit intoapache:masterfrom wernerdaehn:AvroSchemaRecursionHandling
Conversation
…as suggestion only at the moment and not complete. The code has one TODO. And it needs the matching changes to actually write the records into the correct fields.
|
@wernerdaehn, thanks for working on this. The approach here appears to be to replace nested fields with an ID and then add a list of the circular type to the type itself. For example, if we had this tree class: That would get turned into this version: Is that right? |
|
You have a root record calls Node. It has a field called left of the same type, hence the field datatype changed to long. Same for the field right. And because the root node now has to store multiple elements, it needs to be turned into an array. (Your example is a bit weird because there is no actual payload, which makes it hard to read.) |
|
Better explanation: Whenever a child (=left Node; right Node in your example) has the same datatype as a parent, the child holds the instance pointer and the actual data is stored in the parent as new record identified by that pointer. |
|
any updates here? |
https://issues.apache.org/jira/browse/PARQUET-129
@rdblue
This is a suggestion only at the moment and not complete. Need help to complete the feature - see below. Should not be much work for a more experienced person, I hope.
I have added a Patient.asvc schema into the resource folder as a complex example.
Note:
I tried to be as conservative as possible to not break something, however had to change GroupType and MessageType classes to allow creating them first and adding fields second. That makes sense anyhow, not always you have the complete list of fields at the point in time this object is instantiated.
Just to define the term "circular references" correctly, we have the following scenarios:
The way to resolve that is to check before creating a new GroupType for SchemaN, if such a Schema had been created already in one of the parents. It should trigger only for case 2&3, not case 1 above.
If such a thing happens, then instead of creating the full GroupType for this field, it is rather an INT64 pointer. And the SchemaN definiton should get an additional INT64 field holding the reference pointer.
So you will end up with rows coming from the first occurrence of that schema, all having that INT64 empty, plus rows from the child columns of type SchemaN with the INT64 being set.
Example for Case 2:
Person: {firstname STRING, lastname String, [children: Person]}
would be turned into
Person: {firstname STRING, lastname String, [children: INT64], __ID}
My example Patient.asvc AvroSchema is converted into a nice Parquet schema, that is working.
What is missing:
The reason I have not implemented the writer is for the following questions: