func ParseScalar()

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)
}