in arrow/compute/exprs/exec.go [182:381]
func literalToDatum(mem memory.Allocator, lit expr.Literal, ext ExtensionIDSet) (compute.Datum, error) {
switch v := lit.(type) {
case *expr.PrimitiveLiteral[bool]:
return compute.NewDatum(scalar.NewBooleanScalar(v.Value)), nil
case *expr.PrimitiveLiteral[int8]:
return compute.NewDatum(scalar.NewInt8Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[int16]:
return compute.NewDatum(scalar.NewInt16Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[int32]:
return compute.NewDatum(scalar.NewInt32Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[int64]:
return compute.NewDatum(scalar.NewInt64Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[float32]:
return compute.NewDatum(scalar.NewFloat32Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[float64]:
return compute.NewDatum(scalar.NewFloat64Scalar(v.Value)), nil
case *expr.PrimitiveLiteral[string]:
return compute.NewDatum(scalar.NewStringScalar(v.Value)), nil
case *expr.PrimitiveLiteral[types.Timestamp]:
return compute.NewDatum(scalar.NewTimestampScalar(arrow.Timestamp(v.Value), &arrow.TimestampType{Unit: arrow.Microsecond})), nil
case *expr.PrimitiveLiteral[types.TimestampTz]:
return compute.NewDatum(scalar.NewTimestampScalar(arrow.Timestamp(v.Value),
&arrow.TimestampType{Unit: arrow.Microsecond, TimeZone: TimestampTzTimezone})), nil
case *expr.PrimitiveLiteral[types.Date]:
return compute.NewDatum(scalar.NewDate32Scalar(arrow.Date32(v.Value))), nil
case *expr.PrimitiveLiteral[types.Time]:
return compute.NewDatum(scalar.NewTime64Scalar(arrow.Time64(v.Value), &arrow.Time64Type{Unit: arrow.Microsecond})), nil
case *expr.PrimitiveLiteral[types.FixedChar]:
length := int(v.Type.(*types.FixedCharType).Length)
return compute.NewDatum(scalar.NewExtensionScalar(
scalar.NewFixedSizeBinaryScalar(memory.NewBufferBytes([]byte(v.Value)),
&arrow.FixedSizeBinaryType{ByteWidth: length}), fixedChar(int32(length)))), nil
case *expr.ByteSliceLiteral[[]byte]:
return compute.NewDatum(scalar.NewBinaryScalar(memory.NewBufferBytes(v.Value), arrow.BinaryTypes.Binary)), nil
case *expr.ByteSliceLiteral[types.UUID]:
return compute.NewDatum(scalar.NewExtensionScalar(scalar.NewFixedSizeBinaryScalar(
memory.NewBufferBytes(v.Value), uuid().(arrow.ExtensionType).StorageType()), uuid())), nil
case *expr.ByteSliceLiteral[types.FixedBinary]:
return compute.NewDatum(scalar.NewFixedSizeBinaryScalar(memory.NewBufferBytes(v.Value),
&arrow.FixedSizeBinaryType{ByteWidth: int(v.Type.(*types.FixedBinaryType).Length)})), nil
case *expr.NullLiteral:
dt, _, err := FromSubstraitType(v.Type, ext)
if err != nil {
return nil, err
}
return compute.NewDatum(scalar.MakeNullScalar(dt)), nil
case *expr.ListLiteral:
var elemType arrow.DataType
values := make([]scalar.Scalar, len(v.Value))
for i, val := range v.Value {
d, err := literalToDatum(mem, val, ext)
if err != nil {
return nil, err
}
defer d.Release()
values[i] = d.(*compute.ScalarDatum).Value
if elemType != nil {
if !arrow.TypeEqual(values[i].DataType(), elemType) {
return nil, fmt.Errorf("%w: %s has a value whose type doesn't match the other list values",
arrow.ErrInvalid, v)
}
} else {
elemType = values[i].DataType()
}
}
bldr := array.NewBuilder(memory.DefaultAllocator, elemType)
defer bldr.Release()
if err := scalar.AppendSlice(bldr, values); err != nil {
return nil, err
}
arr := bldr.NewArray()
defer arr.Release()
return compute.NewDatum(scalar.NewListScalar(arr)), nil
case *expr.MapLiteral:
dt, _, err := FromSubstraitType(v.Type, ext)
if err != nil {
return nil, err
}
mapType, ok := dt.(*arrow.MapType)
if !ok {
return nil, fmt.Errorf("%w: map literal with non-map type", arrow.ErrInvalid)
}
keys, values := make([]scalar.Scalar, len(v.Value)), make([]scalar.Scalar, len(v.Value))
for i, kv := range v.Value {
k, err := literalToDatum(mem, kv.Key, ext)
if err != nil {
return nil, err
}
defer k.Release()
scalarKey := k.(*compute.ScalarDatum).Value
v, err := literalToDatum(mem, kv.Value, ext)
if err != nil {
return nil, err
}
defer v.Release()
scalarValue := v.(*compute.ScalarDatum).Value
if !arrow.TypeEqual(mapType.KeyType(), scalarKey.DataType()) {
return nil, fmt.Errorf("%w: key type mismatch for %s, got key with type %s",
arrow.ErrInvalid, mapType, scalarKey.DataType())
}
if !arrow.TypeEqual(mapType.ItemType(), scalarValue.DataType()) {
return nil, fmt.Errorf("%w: value type mismatch for %s, got value with type %s",
arrow.ErrInvalid, mapType, scalarValue.DataType())
}
keys[i], values[i] = scalarKey, scalarValue
}
keyBldr, valBldr := array.NewBuilder(mem, mapType.KeyType()), array.NewBuilder(mem, mapType.ItemType())
defer keyBldr.Release()
defer valBldr.Release()
if err := scalar.AppendSlice(keyBldr, keys); err != nil {
return nil, err
}
if err := scalar.AppendSlice(valBldr, values); err != nil {
return nil, err
}
keyArr, valArr := keyBldr.NewArray(), valBldr.NewArray()
defer keyArr.Release()
defer valArr.Release()
kvArr, err := array.NewStructArray([]arrow.Array{keyArr, valArr}, []string{"key", "value"})
if err != nil {
return nil, err
}
defer kvArr.Release()
return compute.NewDatumWithoutOwning(scalar.NewMapScalar(kvArr)), nil
case *expr.StructLiteral:
fields := make([]scalar.Scalar, len(v.Value))
names := make([]string, len(v.Value))
for i, l := range v.Value {
lit, err := literalToDatum(mem, l, ext)
if err != nil {
return nil, err
}
fields[i] = lit.(*compute.ScalarDatum).Value
}
s, err := scalar.NewStructScalarWithNames(fields, names)
return compute.NewDatum(s), err
case *expr.ProtoLiteral:
switch v := v.Value.(type) {
case *types.Decimal:
if len(v.Value) != arrow.Decimal128SizeBytes {
return nil, fmt.Errorf("%w: decimal literal had %d bytes (expected %d)",
arrow.ErrInvalid, len(v.Value), arrow.Decimal128SizeBytes)
}
var val decimal128.Num
data := (*(*[arrow.Decimal128SizeBytes]byte)(unsafe.Pointer(&val)))[:]
copy(data, v.Value)
if endian.IsBigEndian {
// reverse the bytes
for i := len(data)/2 - 1; i >= 0; i-- {
opp := len(data) - 1 - i
data[i], data[opp] = data[opp], data[i]
}
}
return compute.NewDatum(scalar.NewDecimal128Scalar(val,
&arrow.Decimal128Type{Precision: v.Precision, Scale: v.Scale})), nil
case *types.UserDefinedLiteral: // not yet implemented
case *types.IntervalYearToMonth:
bldr := array.NewInt32Builder(memory.DefaultAllocator)
defer bldr.Release()
typ := intervalYear()
bldr.Append(v.Years)
bldr.Append(v.Months)
arr := bldr.NewArray()
defer arr.Release()
return &compute.ScalarDatum{Value: scalar.NewExtensionScalar(
scalar.NewFixedSizeListScalar(arr), typ)}, nil
case *types.IntervalDayToSecond:
bldr := array.NewInt32Builder(memory.DefaultAllocator)
defer bldr.Release()
typ := intervalDay()
bldr.Append(v.Days)
bldr.Append(v.Seconds)
arr := bldr.NewArray()
defer arr.Release()
return &compute.ScalarDatum{Value: scalar.NewExtensionScalar(
scalar.NewFixedSizeListScalar(arr), typ)}, nil
case *types.VarChar:
return compute.NewDatum(scalar.NewExtensionScalar(
scalar.NewStringScalar(v.Value), varChar(int32(v.Length)))), nil
}
}
return nil, arrow.ErrNotImplemented
}