in arrow/internal/arrjson/arrjson.go [247:490]
func (f *FieldWrapper) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &f.Field); err != nil {
return err
}
tmp := nameJSON{}
if err := json.Unmarshal(f.Type, &tmp); err != nil {
return err
}
switch tmp.Name {
case "null":
f.arrowType = arrow.Null
case "bool":
f.arrowType = arrow.FixedWidthTypes.Boolean
case "int":
t := bitWidthJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.Signed {
case true:
switch t.BitWidth {
case 8:
f.arrowType = arrow.PrimitiveTypes.Int8
case 16:
f.arrowType = arrow.PrimitiveTypes.Int16
case 32:
f.arrowType = arrow.PrimitiveTypes.Int32
case 64:
f.arrowType = arrow.PrimitiveTypes.Int64
}
default:
switch t.BitWidth {
case 8:
f.arrowType = arrow.PrimitiveTypes.Uint8
case 16:
f.arrowType = arrow.PrimitiveTypes.Uint16
case 32:
f.arrowType = arrow.PrimitiveTypes.Uint32
case 64:
f.arrowType = arrow.PrimitiveTypes.Uint64
}
}
case "floatingpoint":
t := floatJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.Precision {
case "HALF":
f.arrowType = arrow.FixedWidthTypes.Float16
case "SINGLE":
f.arrowType = arrow.PrimitiveTypes.Float32
case "DOUBLE":
f.arrowType = arrow.PrimitiveTypes.Float64
}
case "binary":
f.arrowType = arrow.BinaryTypes.Binary
case "utf8":
f.arrowType = arrow.BinaryTypes.String
case "date":
t := unitZoneJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.Unit {
case "DAY":
f.arrowType = arrow.FixedWidthTypes.Date32
case "MILLISECOND":
f.arrowType = arrow.FixedWidthTypes.Date64
}
case "time":
t := bitWidthJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.BitWidth {
case 32:
switch t.Unit {
case "SECOND":
f.arrowType = arrow.FixedWidthTypes.Time32s
case "MILLISECOND":
f.arrowType = arrow.FixedWidthTypes.Time32ms
}
case 64:
switch t.Unit {
case "MICROSECOND":
f.arrowType = arrow.FixedWidthTypes.Time64us
case "NANOSECOND":
f.arrowType = arrow.FixedWidthTypes.Time64ns
}
}
case "timestamp":
t := unitZoneJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
f.arrowType = &arrow.TimestampType{TimeZone: t.TimeZone}
switch t.Unit {
case "SECOND":
f.arrowType.(*arrow.TimestampType).Unit = arrow.Second
case "MILLISECOND":
f.arrowType.(*arrow.TimestampType).Unit = arrow.Millisecond
case "MICROSECOND":
f.arrowType.(*arrow.TimestampType).Unit = arrow.Microsecond
case "NANOSECOND":
f.arrowType.(*arrow.TimestampType).Unit = arrow.Nanosecond
}
case "list":
f.arrowType = arrow.ListOfField(arrow.Field{
Name: f.Children[0].Name,
Type: f.Children[0].arrowType,
Metadata: f.Children[0].arrowMeta,
Nullable: f.Children[0].Nullable,
})
case "map":
t := mapJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
pairType := f.Children[0].arrowType
f.arrowType = arrow.MapOf(pairType.(*arrow.StructType).Field(0).Type, pairType.(*arrow.StructType).Field(1).Type)
f.arrowType.(*arrow.MapType).KeysSorted = t.KeysSorted
case "struct":
f.arrowType = arrow.StructOf(fieldsFromJSON(f.Children)...)
case "fixedsizebinary":
t := byteWidthJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
f.arrowType = &arrow.FixedSizeBinaryType{ByteWidth: t.ByteWidth}
case "fixedsizelist":
t := listSizeJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
f.arrowType = arrow.FixedSizeListOfField(t.ListSize, arrow.Field{
Name: f.Children[0].Name,
Type: f.Children[0].arrowType,
Metadata: f.Children[0].arrowMeta,
Nullable: f.Children[0].Nullable,
})
case "interval":
t := unitZoneJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.Unit {
case "YEAR_MONTH":
f.arrowType = arrow.FixedWidthTypes.MonthInterval
case "DAY_TIME":
f.arrowType = arrow.FixedWidthTypes.DayTimeInterval
case "MONTH_DAY_NANO":
f.arrowType = arrow.FixedWidthTypes.MonthDayNanoInterval
}
case "duration":
t := unitZoneJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
switch t.Unit {
case "SECOND":
f.arrowType = arrow.FixedWidthTypes.Duration_s
case "MILLISECOND":
f.arrowType = arrow.FixedWidthTypes.Duration_ms
case "MICROSECOND":
f.arrowType = arrow.FixedWidthTypes.Duration_us
case "NANOSECOND":
f.arrowType = arrow.FixedWidthTypes.Duration_ns
}
case "decimal":
t := decimalJSON{}
if err := json.Unmarshal(f.Type, &t); err != nil {
return err
}
f.arrowType = &arrow.Decimal128Type{Precision: int32(t.Precision), Scale: int32(t.Scale)}
}
if f.arrowType == nil {
return xerrors.Errorf("unhandled type unmarshalling from json: %s", tmp.Name)
}
var err error
if len(f.Metadata) > 0 { // unmarshal the key/value metadata pairs
var (
mdkeys = make([]string, 0, len(f.Metadata))
mdvals = make([]string, 0, len(f.Metadata))
extKeyIdx int = -1
extDataIdx int = -1
)
for i, kv := range f.Metadata {
switch kv.Key {
case ipc.ExtensionTypeKeyName:
extKeyIdx = i
case ipc.ExtensionMetadataKeyName:
extDataIdx = i
}
mdkeys = append(mdkeys, kv.Key)
mdvals = append(mdvals, kv.Value)
}
if extKeyIdx == -1 { // no extension metadata just create the metadata
f.arrowMeta = arrow.NewMetadata(mdkeys, mdvals)
return nil
}
extType := arrow.GetExtensionType(mdvals[extKeyIdx])
if extType == nil { // unregistered extension type, just keep the metadata
f.arrowMeta = arrow.NewMetadata(mdkeys, mdvals)
return nil
}
var extData string
if extDataIdx > -1 {
extData = mdvals[extDataIdx]
// if both extension type and extension type metadata exist
// filter out both keys
newkeys := make([]string, 0, len(mdkeys)-2)
newvals := make([]string, 0, len(mdvals)-2)
for i := range mdkeys {
if i != extKeyIdx && i != extDataIdx {
newkeys = append(newkeys, mdkeys[i])
newvals = append(newvals, mdvals[i])
}
}
mdkeys = newkeys
mdvals = newvals
} else {
// if only extension type key is present, we can simplify filtering it out
mdkeys = append(mdkeys[:extKeyIdx], mdkeys[extKeyIdx+1:]...)
mdvals = append(mdvals[:extKeyIdx], mdvals[extKeyIdx+1:]...)
}
if f.arrowType, err = extType.Deserialize(f.arrowType, extData); err != nil {
return err
}
f.arrowMeta = arrow.NewMetadata(mdkeys, mdvals)
}
return err
}