func MakeScalarParam()

in arrow/scalar/parse.go [372:548]


func MakeScalarParam(val interface{}, dt arrow.DataType) (Scalar, error) {
	switch v := val.(type) {
	case []byte:
		buf := memory.NewBufferBytes(v)
		defer buf.Release()

		switch dt.ID() {
		case arrow.BINARY:
			return NewBinaryScalar(buf, dt), nil
		case arrow.LARGE_BINARY:
			return NewLargeBinaryScalar(buf), nil
		case arrow.STRING:
			return NewStringScalarFromBuffer(buf), nil
		case arrow.LARGE_STRING:
			return NewLargeStringScalarFromBuffer(buf), nil
		case arrow.FIXED_SIZE_BINARY:
			if buf.Len() == dt.(*arrow.FixedSizeBinaryType).ByteWidth {
				return NewFixedSizeBinaryScalar(buf, dt), nil
			}
			return nil, fmt.Errorf("invalid scalar value of len %d for type %s", v, dt)
		}
	case *memory.Buffer:
		switch dt.ID() {
		case arrow.BINARY:
			return NewBinaryScalar(v, dt), nil
		case arrow.LARGE_BINARY:
			return NewLargeBinaryScalar(v), nil
		case arrow.STRING:
			return NewStringScalarFromBuffer(v), nil
		case arrow.LARGE_STRING:
			return NewLargeStringScalarFromBuffer(v), nil
		case arrow.FIXED_SIZE_BINARY:
			if v.Len() == dt.(*arrow.FixedSizeBinaryType).ByteWidth {
				return NewFixedSizeBinaryScalar(v, dt), nil
			}
			return nil, fmt.Errorf("invalid scalar value of len %d for type %s", v.Len(), dt)
		}
	case string:
		switch {
		case arrow.IsBaseBinary(dt.ID()):
			buf := memory.NewBufferBytes([]byte(v))
			defer buf.Release()

			switch dt.ID() {
			case arrow.BINARY:
				return NewBinaryScalar(buf, dt), nil
			case arrow.LARGE_BINARY:
				return NewLargeBinaryScalar(buf), nil
			case arrow.STRING:
				return NewStringScalar(v), nil
			case arrow.LARGE_STRING:
				return NewLargeStringScalar(v), nil
			}
		case arrow.IsInteger(dt.ID()):
			bits := dt.(arrow.FixedWidthDataType).BitWidth()
			if arrow.IsUnsignedInteger(dt.ID()) {
				val, err := strconv.ParseUint(v, 0, bits)
				if err != nil {
					return nil, err
				}
				return MakeUnsignedIntegerScalar(val, bits)
			}
			val, err := strconv.ParseInt(v, 0, bits)
			if err != nil {
				return nil, err
			}
			return MakeIntegerScalar(val, bits)
		case arrow.IsFixedSizeBinary(dt.ID()):
			switch dt.ID() {
			case arrow.FIXED_SIZE_BINARY:
				ty := dt.(*arrow.FixedSizeBinaryType)
				if len(v) != ty.ByteWidth {
					return nil, fmt.Errorf("%w: invalid length for fixed size binary scalar", arrow.ErrInvalid)
				}
				return NewFixedSizeBinaryScalar(memory.NewBufferBytes([]byte(v)), ty), nil
			case arrow.DECIMAL128:
				ty := dt.(*arrow.Decimal128Type)
				n, err := decimal128.FromString(v, ty.Precision, ty.Scale)
				if err != nil {
					return nil, err
				}
				return NewDecimal128Scalar(n, ty), nil
			case arrow.DECIMAL256:
				ty := dt.(*arrow.Decimal256Type)
				n, err := decimal256.FromString(v, ty.Precision, ty.Scale)
				if err != nil {
					return nil, err
				}
				return NewDecimal256Scalar(n, ty), nil
			}
		case arrow.IsFloating(dt.ID()):
			bits := dt.(arrow.FixedWidthDataType).BitWidth()
			val, err := strconv.ParseFloat(v, bits)
			if err != nil {
				return nil, err
			}
			if bits == 32 {
				return NewFloat32Scalar(float32(val)), nil
			}
			return NewFloat64Scalar(val), nil
		case dt.ID() == arrow.TIMESTAMP:
			ty := dt.(*arrow.TimestampType)
			if ty.TimeZone == "" || strings.ToLower(ty.TimeZone) == "utc" {
				ts, err := arrow.TimestampFromString(v, ty.Unit)
				if err != nil {
					return nil, err
				}
				return NewTimestampScalar(ts, dt), nil
			}
			loc, err := time.LoadLocation(ty.TimeZone)
			if err != nil {
				return nil, err
			}
			ts, _, err := arrow.TimestampFromStringInLocation(v, ty.Unit, loc)
			if err != nil {
				return nil, err
			}
			return NewTimestampScalar(ts, ty), nil
		}
	case arrow.Time32:
		return NewTime32Scalar(v, dt), nil
	case arrow.Time64:
		return NewTime64Scalar(v, dt), nil
	case arrow.Timestamp:
		return NewTimestampScalar(v, dt), nil
	case arrow.Array:
		switch dt.ID() {
		case arrow.LIST:
			if !arrow.TypeEqual(v.DataType(), dt.(*arrow.ListType).Elem()) {
				return nil, fmt.Errorf("inconsistent type for list scalar array and data type")
			}
			return NewListScalar(v), nil
		case arrow.LARGE_LIST:
			if !arrow.TypeEqual(v.DataType(), dt.(*arrow.LargeListType).Elem()) {
				return nil, fmt.Errorf("inconsistent type for large list scalar array and data type")
			}
			return NewLargeListScalar(v), nil
		case arrow.FIXED_SIZE_LIST:
			if !arrow.TypeEqual(v.DataType(), dt.(*arrow.FixedSizeListType).Elem()) {
				return nil, fmt.Errorf("inconsistent type for list scalar array and data type")
			}
			return NewFixedSizeListScalarWithType(v, dt), nil
		case arrow.MAP:
			if !arrow.TypeEqual(dt.(*arrow.MapType).Elem(), v.DataType()) {
				return nil, fmt.Errorf("inconsistent type for map scalar type")
			}
			return NewMapScalar(v), nil
		}
	case decimal128.Num:
		if _, ok := dt.(*arrow.Decimal128Type); !ok {
			return nil, fmt.Errorf("mismatch cannot create decimal128 scalar with incorrect data type")
		}

		return NewDecimal128Scalar(v, dt), nil
	case decimal256.Num:
		if _, ok := dt.(*arrow.Decimal256Type); !ok {
			return nil, fmt.Errorf("mismatch cannot create decimal256 scalar with incorrect data type")
		}

		return NewDecimal256Scalar(v, dt), nil

	}

	if arrow.IsInteger(dt.ID()) {
		bits := dt.(arrow.FixedWidthDataType).BitWidth()
		val := reflect.ValueOf(val)
		if arrow.IsUnsignedInteger(dt.ID()) {
			return MakeUnsignedIntegerScalar(val.Convert(reflect.TypeOf(uint64(0))).Uint(), bits)
		}
		return MakeIntegerScalar(val.Convert(reflect.TypeOf(int64(0))).Int(), bits)
	}

	if dt.ID() == arrow.DICTIONARY {
		return MakeScalarParam(val, dt.(*arrow.DictionaryType).ValueType)
	}
	return MakeScalar(val), nil
}