in arrow/internal/arrjson/arrjson.go [1386:1816]
func arrayToJSON(field arrow.Field, arr arrow.Array) Array {
switch arr := arr.(type) {
case *array.Null:
return Array{
Name: field.Name,
Count: arr.Len(),
}
case *array.Boolean:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: boolsToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Int8:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: i8ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Int16:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: i16ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Int32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: i32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Int64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: i64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Uint8:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: u8ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Uint16:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: u16ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Uint32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: u32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Uint64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: u64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Float16:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: f16ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Float32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: f32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Float64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: f64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.String:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: strToJSON(arr),
Valids: validsToJSON(arr),
Offset: arr.ValueOffsets(),
}
case *array.LargeString:
offsets := arr.ValueOffsets()
strOffsets := make([]string, len(offsets))
for i, o := range offsets {
strOffsets[i] = strconv.FormatInt(o, 10)
}
return Array{
Name: field.Name,
Count: arr.Len(),
Data: strToJSON(arr),
Valids: validsToJSON(arr),
Offset: strOffsets,
}
case *array.Binary:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: bytesToJSON(arr),
Valids: validsToJSON(arr),
Offset: arr.ValueOffsets(),
}
case *array.LargeBinary:
offsets := arr.ValueOffsets()
strOffsets := make([]string, len(offsets))
for i, o := range offsets {
strOffsets[i] = strconv.FormatInt(o, 10)
}
return Array{
Name: field.Name,
Count: arr.Len(),
Data: bytesToJSON(arr),
Valids: validsToJSON(arr),
Offset: strOffsets,
}
case *array.StringView:
variadic := variadicBuffersToJSON(arr.Data().Buffers()[2:])
return Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Views: stringHeadersToJSON(arr, false),
Variadic: variadic,
}
case *array.BinaryView:
variadic := variadicBuffersToJSON(arr.Data().Buffers()[2:])
return Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Views: stringHeadersToJSON(arr, true),
Variadic: variadic,
}
case *array.List:
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Offset: arr.Offsets(),
Children: []Array{
arrayToJSON(arrow.Field{Name: "item", Type: arr.DataType().(*arrow.ListType).Elem()}, arr.ListValues()),
},
}
return o
case *array.LargeList:
offsets := arr.Offsets()
strOffsets := make([]string, len(offsets))
for i, o := range offsets {
strOffsets[i] = strconv.FormatInt(o, 10)
}
return Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Offset: strOffsets,
Children: []Array{
arrayToJSON(arrow.Field{Name: "item", Type: arr.DataType().(*arrow.LargeListType).Elem()}, arr.ListValues()),
},
}
case *array.ListView:
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Offset: arr.Offsets(),
Size: arr.Sizes(),
Children: []Array{
arrayToJSON(arrow.Field{Name: "item", Type: arr.DataType().(*arrow.ListViewType).Elem()}, arr.ListValues()),
},
}
if arr.Len() == 0 {
o.Offset, o.Size = []int32{}, []int32{}
}
return o
case *array.LargeListView:
offsets := arr.Offsets()
strOffsets := make([]string, len(offsets))
for i, o := range offsets {
strOffsets[i] = strconv.FormatInt(o, 10)
}
sizes := arr.Sizes()
strSizes := make([]string, len(sizes))
for i, s := range sizes {
strSizes[i] = strconv.FormatInt(s, 10)
}
return Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Offset: strOffsets,
Size: strSizes,
Children: []Array{
arrayToJSON(arrow.Field{Name: "item", Type: arr.DataType().(*arrow.LargeListViewType).Elem()}, arr.ListValues()),
},
}
case *array.Map:
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Offset: arr.Offsets(),
Children: []Array{
arrayToJSON(arrow.Field{Name: "entries", Type: arr.DataType().(*arrow.MapType).Elem()}, arr.ListValues()),
},
}
return o
case *array.FixedSizeList:
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Children: []Array{
arrayToJSON(arrow.Field{Name: "", Type: arr.DataType().(*arrow.FixedSizeListType).Elem()}, arr.ListValues()),
},
}
return o
case *array.Struct:
dt := arr.DataType().(*arrow.StructType)
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Children: make([]Array, dt.NumFields()),
}
for i := range o.Children {
o.Children[i] = arrayToJSON(dt.Field(i), arr.Field(i))
}
return o
case *array.FixedSizeBinary:
dt := arr.DataType().(*arrow.FixedSizeBinaryType)
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
Data: make([]interface{}, arr.Len()),
}
for i := range o.Data {
v := []byte(strings.ToUpper(hex.EncodeToString(arr.Value(i))))
if len(v) != 2*dt.ByteWidth {
panic(fmt.Errorf("arrjson: invalid hex-string length (got=%d, want=%d)", len(v), 2*dt.ByteWidth))
}
o.Data[i] = string(v) // re-convert as string to prevent json.Marshal from base64-encoding it.
}
return o
case *array.Date32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: date32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Date64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: date64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Time32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: time32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Time64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: time64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Timestamp:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: timestampToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.MonthInterval:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: monthintervalToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.DayTimeInterval:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: daytimeintervalToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.MonthDayNanoInterval:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: monthDayNanointervalToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Duration:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: durationToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Decimal32:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: decimal32ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Decimal64:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: decimal64ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Decimal128:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: decimal128ToJSON(arr),
Valids: validsToJSON(arr),
}
case *array.Decimal256:
return Array{
Name: field.Name,
Count: arr.Len(),
Data: decimal256ToJSON(arr),
Valids: validsToJSON(arr),
}
case array.ExtensionArray:
return arrayToJSON(field, arr.Storage())
case *array.Dictionary:
return arrayToJSON(field, arr.Indices())
case array.Union:
dt := arr.DataType().(arrow.UnionType)
o := Array{
Name: field.Name,
Count: arr.Len(),
Valids: validsToJSON(arr),
TypeID: arr.RawTypeCodes(),
Children: make([]Array, dt.NumFields()),
}
if dt.Mode() == arrow.DenseMode {
o.Offset = arr.(*array.DenseUnion).RawValueOffsets()
}
fields := dt.Fields()
for i := range o.Children {
o.Children[i] = arrayToJSON(fields[i], arr.Field(i))
}
return o
case *array.RunEndEncoded:
dt := arr.DataType().(*arrow.RunEndEncodedType)
fields := dt.Fields()
runEnds := arr.LogicalRunEndsArray(memory.DefaultAllocator)
defer runEnds.Release()
values := arr.LogicalValuesArray()
defer values.Release()
return Array{
Name: field.Name,
Count: arr.Len(),
Children: []Array{
arrayToJSON(fields[0], runEnds),
arrayToJSON(fields[1], values),
},
}
default:
panic(fmt.Errorf("unknown array type %T", arr))
}
}