in arrow/scalar/parse.go [196:340]
func ParseScalar(dt arrow.DataType, val string) (Scalar, error) {
switch dt.ID() {
case arrow.STRING:
return NewStringScalar(val), nil
case arrow.BINARY:
buf := memory.NewBufferBytes([]byte(val))
defer buf.Release()
return NewBinaryScalar(buf, dt), nil
case arrow.FIXED_SIZE_BINARY:
if len(val) != dt.(*arrow.FixedSizeBinaryType).ByteWidth {
return nil, xerrors.Errorf("invalid value %s for scalar of type %s", val, dt)
}
buf := memory.NewBufferBytes([]byte(val))
defer buf.Release()
return NewFixedSizeBinaryScalar(buf, dt), nil
case arrow.BOOL:
val, err := strconv.ParseBool(val)
if err != nil {
return nil, err
}
return NewBooleanScalar(val), nil
case arrow.INT8, arrow.INT16, arrow.INT32, arrow.INT64:
width := dt.(arrow.FixedWidthDataType).BitWidth()
val, err := strconv.ParseInt(val, 0, width)
if err != nil {
return nil, err
}
return MakeIntegerScalar(val, width)
case arrow.UINT8, arrow.UINT16, arrow.UINT32, arrow.UINT64:
width := dt.(arrow.FixedWidthDataType).BitWidth()
val, err := strconv.ParseUint(val, 0, width)
if err != nil {
return nil, err
}
return MakeUnsignedIntegerScalar(val, width)
case arrow.FLOAT16:
val, err := strconv.ParseFloat(val, 32)
if err != nil {
return nil, err
}
return NewFloat16ScalarFromFloat32(float32(val)), nil
case arrow.FLOAT32, arrow.FLOAT64:
width := dt.(arrow.FixedWidthDataType).BitWidth()
val, err := strconv.ParseFloat(val, width)
if err != nil {
return nil, err
}
switch width {
case 32:
return NewFloat32Scalar(float32(val)), nil
case 64:
return NewFloat64Scalar(float64(val)), nil
}
case arrow.TIMESTAMP:
format := "2006-01-02"
if val[len(val)-1] == 'Z' {
val = val[:len(val)-1]
}
switch {
case len(val) == 13:
format += string(val[10]) + "15"
case len(val) == 16:
format += string(val[10]) + "15:04"
case len(val) >= 19:
format += string(val[10]) + "15:04:05.999999999"
}
out, err := time.ParseInLocation(format, val, time.UTC)
if err != nil {
return nil, err
}
value := arrow.Timestamp(ConvertTimestampValue(arrow.Nanosecond, dt.(*arrow.TimestampType).Unit, out.UnixNano()))
return NewTimestampScalar(value, dt), nil
case arrow.DURATION:
value, err := time.ParseDuration(val)
if err != nil {
return nil, err
}
unit := dt.(*arrow.DurationType).Unit
var out arrow.Duration
switch unit {
case arrow.Nanosecond:
out = arrow.Duration(value.Nanoseconds())
case arrow.Microsecond:
out = arrow.Duration(value.Microseconds())
case arrow.Millisecond:
out = arrow.Duration(value.Milliseconds())
case arrow.Second:
out = arrow.Duration(value.Seconds())
}
return NewDurationScalar(out, dt), nil
case arrow.DATE32, arrow.DATE64:
out, err := time.ParseInLocation("2006-01-02", val, time.UTC)
if err != nil {
return nil, err
}
if dt.ID() == arrow.DATE32 {
return NewDate32Scalar(arrow.Date32(out.Unix() / int64((time.Hour * 24).Seconds()))), nil
} else {
return NewDate64Scalar(arrow.Date64(out.Unix() * 1000)), nil
}
case arrow.TIME32:
var (
out time.Time
err error
)
switch {
case len(val) == 5:
out, err = time.ParseInLocation("15:04", val, time.UTC)
default:
out, err = time.ParseInLocation("15:04:05.999", val, time.UTC)
}
if err != nil {
return nil, err
}
t := out.Sub(time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC))
if dt.(*arrow.Time32Type).Unit == arrow.Second {
return NewTime32Scalar(arrow.Time32(t.Seconds()), dt), nil
}
return NewTime32Scalar(arrow.Time32(t.Milliseconds()), dt), nil
case arrow.TIME64:
var (
out time.Time
err error
)
switch {
case len(val) == 5:
out, err = time.ParseInLocation("15:04", val, time.UTC)
default:
out, err = time.ParseInLocation("15:04:05.999999999", val, time.UTC)
}
if err != nil {
return nil, err
}
t := out.Sub(time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC))
if dt.(*arrow.Time64Type).Unit == arrow.Microsecond {
return NewTime64Scalar(arrow.Time64(t.Microseconds()), dt), nil
}
return NewTime64Scalar(arrow.Time64(t.Nanoseconds()), dt), nil
}
return nil, xerrors.Errorf("parsing of scalar for type %s not implemented", dt)
}