func typeFromJSON()

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
}