in arrow/internal/arrjson/arrjson.go [293:550]
func typeFromJSON(typ json.RawMessage, children []FieldWrapper) (arrowType arrow.DataType, err error) {
tmp := nameJSON{}
if err = json.Unmarshal(typ, &tmp); err != nil {
return
}
switch tmp.Name {
case "null":
arrowType = arrow.Null
case "bool":
arrowType = arrow.FixedWidthTypes.Boolean
case "int":
t := bitWidthJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Signed {
case true:
switch t.BitWidth {
case 8:
arrowType = arrow.PrimitiveTypes.Int8
case 16:
arrowType = arrow.PrimitiveTypes.Int16
case 32:
arrowType = arrow.PrimitiveTypes.Int32
case 64:
arrowType = arrow.PrimitiveTypes.Int64
}
default:
switch t.BitWidth {
case 8:
arrowType = arrow.PrimitiveTypes.Uint8
case 16:
arrowType = arrow.PrimitiveTypes.Uint16
case 32:
arrowType = arrow.PrimitiveTypes.Uint32
case 64:
arrowType = arrow.PrimitiveTypes.Uint64
}
}
case "floatingpoint":
t := floatJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Precision {
case "HALF":
arrowType = arrow.FixedWidthTypes.Float16
case "SINGLE":
arrowType = arrow.PrimitiveTypes.Float32
case "DOUBLE":
arrowType = arrow.PrimitiveTypes.Float64
}
case "binary":
arrowType = arrow.BinaryTypes.Binary
case "largebinary":
arrowType = arrow.BinaryTypes.LargeBinary
case "utf8":
arrowType = arrow.BinaryTypes.String
case "largeutf8":
arrowType = arrow.BinaryTypes.LargeString
case "binaryview":
arrowType = arrow.BinaryTypes.BinaryView
case "utf8view":
arrowType = arrow.BinaryTypes.StringView
case "date":
t := unitZoneJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Unit {
case "DAY":
arrowType = arrow.FixedWidthTypes.Date32
case "MILLISECOND":
arrowType = arrow.FixedWidthTypes.Date64
}
case "time":
t := bitWidthJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.BitWidth {
case 32:
switch t.Unit {
case "SECOND":
arrowType = arrow.FixedWidthTypes.Time32s
case "MILLISECOND":
arrowType = arrow.FixedWidthTypes.Time32ms
}
case 64:
switch t.Unit {
case "MICROSECOND":
arrowType = arrow.FixedWidthTypes.Time64us
case "NANOSECOND":
arrowType = arrow.FixedWidthTypes.Time64ns
}
}
case "timestamp":
t := unitZoneJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
arrowType = &arrow.TimestampType{TimeZone: t.TimeZone}
switch t.Unit {
case "SECOND":
arrowType.(*arrow.TimestampType).Unit = arrow.Second
case "MILLISECOND":
arrowType.(*arrow.TimestampType).Unit = arrow.Millisecond
case "MICROSECOND":
arrowType.(*arrow.TimestampType).Unit = arrow.Microsecond
case "NANOSECOND":
arrowType.(*arrow.TimestampType).Unit = arrow.Nanosecond
}
case "list":
arrowType = arrow.ListOfField(arrow.Field{
Name: children[0].Name,
Type: children[0].arrowType,
Metadata: children[0].arrowMeta,
Nullable: children[0].Nullable,
})
case "largelist":
arrowType = arrow.LargeListOfField(arrow.Field{
Name: children[0].Name,
Type: children[0].arrowType,
Metadata: children[0].arrowMeta,
Nullable: children[0].Nullable,
})
case "listview":
arrowType = arrow.ListViewOfField(arrow.Field{
Name: children[0].Name,
Type: children[0].arrowType,
Metadata: children[0].arrowMeta,
Nullable: children[0].Nullable,
})
case "largelistview":
arrowType = arrow.LargeListViewOfField(arrow.Field{
Name: children[0].Name,
Type: children[0].arrowType,
Metadata: children[0].arrowMeta,
Nullable: children[0].Nullable,
})
case "map":
t := mapJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
pairType := children[0].arrowType
arrowType = arrow.MapOf(pairType.(*arrow.StructType).Field(0).Type, pairType.(*arrow.StructType).Field(1).Type)
arrowType.(*arrow.MapType).KeysSorted = t.KeysSorted
case "struct":
arrowType = arrow.StructOf(fieldsFromJSON(children)...)
case "fixedsizebinary":
t := byteWidthJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
arrowType = &arrow.FixedSizeBinaryType{ByteWidth: t.ByteWidth}
case "fixedsizelist":
t := listSizeJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
arrowType = arrow.FixedSizeListOfField(t.ListSize, arrow.Field{
Name: children[0].Name,
Type: children[0].arrowType,
Metadata: children[0].arrowMeta,
Nullable: children[0].Nullable,
})
case "interval":
t := unitZoneJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Unit {
case "YEAR_MONTH":
arrowType = arrow.FixedWidthTypes.MonthInterval
case "DAY_TIME":
arrowType = arrow.FixedWidthTypes.DayTimeInterval
case "MONTH_DAY_NANO":
arrowType = arrow.FixedWidthTypes.MonthDayNanoInterval
}
case "duration":
t := unitZoneJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Unit {
case "SECOND":
arrowType = arrow.FixedWidthTypes.Duration_s
case "MILLISECOND":
arrowType = arrow.FixedWidthTypes.Duration_ms
case "MICROSECOND":
arrowType = arrow.FixedWidthTypes.Duration_us
case "NANOSECOND":
arrowType = arrow.FixedWidthTypes.Duration_ns
}
case "decimal":
t := decimalJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.BitWidth {
case 256:
arrowType = &arrow.Decimal256Type{Precision: int32(t.Precision), Scale: int32(t.Scale)}
case 128, 0: // default to 128 bits when missing
arrowType = &arrow.Decimal128Type{Precision: int32(t.Precision), Scale: int32(t.Scale)}
case 64:
arrowType = &arrow.Decimal64Type{Precision: int32(t.Precision), Scale: int32(t.Scale)}
case 32:
arrowType = &arrow.Decimal32Type{Precision: int32(t.Precision), Scale: int32(t.Scale)}
}
case "union":
t := unionJSON{}
if err = json.Unmarshal(typ, &t); err != nil {
return
}
switch t.Mode {
case "SPARSE":
arrowType = arrow.SparseUnionOf(fieldsFromJSON(children), t.TypeIDs)
case "DENSE":
arrowType = arrow.DenseUnionOf(fieldsFromJSON(children), t.TypeIDs)
}
case "runendencoded":
if len(children) != 2 {
err = fmt.Errorf("%w: run-end encoded array must have exactly 2 fields, but got %d",
arrow.ErrInvalid, len(children))
return
}
if children[0].Name != "run_ends" {
err = fmt.Errorf("%w: first child of run-end encoded array must be called run_ends, but got: %s",
arrow.ErrInvalid, children[0].Name)
return
}
switch children[0].arrowType.ID() {
case arrow.INT16, arrow.INT32, arrow.INT64:
default:
err = fmt.Errorf("%w: only int16, int32 and int64 type are supported as run ends array, but got: %s",
arrow.ErrInvalid, children[0].Type)
return
}
if children[0].Nullable {
err = fmt.Errorf("%w: run ends array cannot be nullable", arrow.ErrInvalid)
return
}
if children[1].Name != "values" {
err = fmt.Errorf("%w: second child of run-end encoded array must be called values, got: %s",
arrow.ErrInvalid, children[1].Name)
return
}
arrowType = arrow.RunEndEncodedOf(children[0].arrowType, children[1].arrowType)
}
if arrowType == nil {
err = fmt.Errorf("unhandled type unmarshalling from json: %s", tmp.Name)
}
return
}