zeroshade commented on issue #46555:
URL: https://github.com/apache/arrow/issues/46555#issuecomment-2904786416

   I've been building out an API for a Variant Builder for the Go 
implementation, and so far I have based it on the [Spark Variant 
Builder](https://github.com/apache/spark/blob/master/common/variant/src/main/java/org/apache/spark/types/variant/VariantBuilder.java).
   
   The API looks like this for the primitive types:
   
   ```go
   func (b *Builder) AppendNull() error {...}
   func (b *Builder) AppendBool(v bool) error {...}
   // uses the smallest int type it can based on the value
   func (b *Builder) AppendInt(v int64) error {...}
   func (b *Builder) AppendTimestamp(v arrow.Timestamp, useMicro, useUTC bool) 
error {...}
   // and so on....
   ```
   
   There are also methods for adding a key to the metadata:
   
   ```go
   func (b *Builder) AddKey(k string) (id uint32) {...}
   func (b *Builder) AddKeys(k []string) (id []uint32) {...}
   ```
   
   Which just adds them so they will get put into the metadata when you finally 
build it, and returns the IDs.
   
   For managing objects and arrays, I decided against using sub-builders as 
that would require having to manage the lifetime of multiple objects and 
sub-builders which could get very complex. Instead the pattern is the following:
   
   1. Get the starting offset via `Buffer.Offset()`
   2. Use the starting offset and helper functions to build a list of 
fields/offsets while appending the values
   3. Call `FinishArray` / `FinishObject` with the start offset + list of 
offsets/fields.
   
   Code-wise it looks like this to build a list:
   
   ```go
   var b variant.Builder
   start := b.Offset()
   offsets := make([]int, 0)
   
   offsets = append(offsets, b.NextElement(start))
   b.AppendInt(5)
   
   offsets = append(offsets, b.NextElement(start))
   b.AppendBool(true)
   
   offsets = append(offsets, b.NextElement(start))
   b.AppendInt(9)
   
   b.FinishArray(start, offsets)
   
   v, err := b.Build()
   ```
   
   Resulting in a variant that is equivalent to `[5, true, 9]`.
   
   For an object it looks like:
   
   ```go
   var b variant.Builder
   start := b.Offset()
   fields := make([]variant.FieldEntry, 0)
   
   fields := append(fields, b.NextField(start, "int_field"))
   b.AppendInt(1)
   
   fields = append(fields, b.NextField(start, "string_field"))
   b.AppendString("Variant")
   
   fields = append(fields, b.NextField(start, "null_field"))
   b.AppendNull()
   
   b.FinishObject(start, fields)
   
   v, err := b.Build()
   ```
   
   This would create a variant that is equivalent to `{ "int_field": 1, 
"string_field": "Variant", "null_field": null }`
   
   What do you think?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to