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

Scott Carey commented on AVRO-1274:
-----------------------------------

Another type of schema that the builder cannot create (easily) is an optional 
field with no default.  Such a schema is brittle when used to read, but in some 
cases that is desired -- you may want to fail if the data being read does not 
contain a field or matching value at the source.

"optional" and "required" don't feel like the right names -- the latter is not 
required, if it has a default value, and the former may be required if it does 
not have a default value.  "nullable" is a more exact description for the 
former.

This means there are 5 methods per type if we keep the builder similar  -- 
nullable with null default, nullable with no default, nullable with a value 
default, non-nullable with a default, and non-null without a default.

A different way to handle this is to move the default handling to a specialized 
field builder per type (type-builder?) rather than have the method count be 
combinatorial (5 + N methods rather than 5 * N methods, for N types and 5 
default options).  This is the same code that would be required to make union 
defaults type-safe (When building a union, the first type would have to be 
added explicitly and return the appropriate default builder, then other types 
could be added to the union).

We could split it into enough types to make it more composable.  Below are some 
ideas that I haven't thought through completely, and I might take a stab at it 
in 4 weeks:
{code}
  nullableInt("foo").default(1); // for nullable int (a union of null and int, 
which is ordered properly based on whether it has a non-null default)
  nullableInt("foo").defaultNull(); // null default, if missing on read the 
field is null
  nullableInt("foo").required(); // no default value, the field is required

  int("foo").default(-1); // for non-nullable int with default -1;
  int("foo").required();
{code}

or completely chained syntax for each step (which requires several more builder 
types but can be perfectly type safe):
{code}
  name("foo").nullable().int().default(1);  // capture name separately, since 
we want to build types without names elsewhere and those have the same API 
otherwise
  name("foo").nullable().int().nullDefault();
  name("foo").nullable().int().required();
  name("foo").int().default(-1);
  name("foo").int().required();
  name("foo").arrayOf().int().nullable().default(new int[] {0}); // re-use type 
building for fields for array inner type
  name("foo").unionOf().fixed(4).default(new byte[] {127, 0, 0, 
1}).and().fixed(16); // re-use type building again, and also only allow the 
first one to be a type builder that supports defaults, the type builder after 
add() does not support defaults.  We cant prevent unions from adding the same 
type twice at this point without making a type for every combinational subset 
of unnamed types, due to limitations with Java's type system.

  // complex example 
  new RecordTypeBuilder("org.apache.avro.example.Tree")
   
.field("left").nullable().recordReference("org.apache.avro.example.Tree").defaultNull()
   .field("data").string().required()
   
.field("right").nullable().recordReference("org.apache.avro.example.Tree").defaultNull()
   .build();
{code}

"nullable()" is a special case union
{code}
  field("foo").nullable().int().defaultNull() // a special case binary union of 
null and a single other type

  field("foo").unionOf().null().and().int().defaultNull(); // same, but allows 
for adding more than one additional type to the union and does not support 
rearranging the order of the two for default purposes
{code}


                
> Add a schema builder API
> ------------------------
>
>                 Key: AVRO-1274
>                 URL: https://issues.apache.org/jira/browse/AVRO-1274
>             Project: Avro
>          Issue Type: New Feature
>          Components: java
>            Reporter: Tom White
>            Assignee: Tom White
>         Attachments: AVRO-1274.patch, AVRO-1274.patch, AVRO-1274.patch, 
> AVRO-1274.patch, AVRO-1274.patch, TestDefaults.patch
>
>
> It would be nice to have a fluent API that made it easier to construct record 
> schemas.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to