in arrow/compute/exec/span.go [254:421]
func (a *ArraySpan) FillFromScalar(val scalar.Scalar) {
var (
trueBit byte = 0x01
falseBit byte = 0x00
)
a.Type = val.DataType()
a.Len = 1
typeID := a.Type.ID()
if val.IsValid() {
a.Nulls = 0
} else {
a.Nulls = 1
}
if !arrow.IsUnion(typeID) && typeID != arrow.NULL {
if val.IsValid() {
a.Buffers[0].Buf = []byte{trueBit}
} else {
a.Buffers[0].Buf = []byte{falseBit}
}
a.Buffers[0].Owner = nil
a.Buffers[0].SelfAlloc = false
}
switch {
case typeID == arrow.BOOL:
if val.(*scalar.Boolean).Value {
a.Buffers[1].Buf = []byte{trueBit}
} else {
a.Buffers[1].Buf = []byte{falseBit}
}
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
case arrow.IsPrimitive(typeID) || arrow.IsDecimal(typeID):
sc := val.(scalar.PrimitiveScalar)
a.Buffers[1].Buf = sc.Data()
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
case typeID == arrow.DICTIONARY:
sc := val.(scalar.PrimitiveScalar)
a.Buffers[1].Buf = sc.Data()
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
a.resizeChildren(1)
a.Children[0].SetMembers(val.(*scalar.Dictionary).Value.Dict.Data())
case arrow.IsBaseBinary(typeID):
sc := val.(scalar.BinaryScalar)
a.Buffers[1].Buf = arrow.Uint64Traits.CastToBytes(a.Scratch[:])
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
var dataBuffer []byte
if sc.IsValid() {
dataBuffer = sc.Data()
a.Buffers[2].Owner = sc.Buffer()
a.Buffers[2].SelfAlloc = false
}
if arrow.IsBinaryLike(typeID) {
setOffsetsForScalar(a,
unsafe.Slice((*int32)(unsafe.Pointer(&a.Scratch[0])), 2),
int64(len(dataBuffer)), 1)
} else {
// large_binary_like
setOffsetsForScalar(a,
unsafe.Slice((*int64)(unsafe.Pointer(&a.Scratch[0])), 2),
int64(len(dataBuffer)), 1)
}
a.Buffers[2].Buf = dataBuffer
case typeID == arrow.FIXED_SIZE_BINARY:
sc := val.(scalar.BinaryScalar)
if !sc.IsValid() {
a.Buffers[1].Buf = make([]byte, sc.DataType().(*arrow.FixedSizeBinaryType).ByteWidth)
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
break
}
a.Buffers[1].Buf = sc.Data()
a.Buffers[1].Owner = sc.Buffer()
a.Buffers[1].SelfAlloc = false
case arrow.IsListLike(typeID):
sc := val.(scalar.ListScalar)
valueLen := 0
a.resizeChildren(1)
if sc.GetList() != nil {
a.Children[0].SetMembers(sc.GetList().Data())
valueLen = sc.GetList().Len()
} else {
// even when the value is null, we must populate
// child data to yield a valid array. ugh
FillZeroLength(sc.DataType().(arrow.NestedType).Fields()[0].Type, &a.Children[0])
}
switch typeID {
case arrow.LIST, arrow.MAP:
setOffsetsForScalar(a,
unsafe.Slice((*int32)(unsafe.Pointer(&a.Scratch[0])), 2),
int64(valueLen), 1)
case arrow.LARGE_LIST:
setOffsetsForScalar(a,
unsafe.Slice((*int64)(unsafe.Pointer(&a.Scratch[0])), 2),
int64(valueLen), 1)
default:
// fixed size list has no second buffer
a.Buffers[1].Buf, a.Buffers[1].Owner = nil, nil
a.Buffers[1].SelfAlloc = false
}
case typeID == arrow.STRUCT:
sc := val.(*scalar.Struct)
a.Buffers[1].Buf = nil
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
a.resizeChildren(len(sc.Value))
for i, v := range sc.Value {
a.Children[i].FillFromScalar(v)
}
case arrow.IsUnion(typeID):
// first buffer is kept null since unions have no validity vector
a.Buffers[0].Buf, a.Buffers[0].Owner = nil, nil
a.Buffers[0].SelfAlloc = false
a.Buffers[1].Buf = arrow.Uint64Traits.CastToBytes(a.Scratch[:])[:1]
a.Buffers[1].Owner = nil
a.Buffers[1].SelfAlloc = false
codes := unsafe.Slice((*arrow.UnionTypeCode)(unsafe.Pointer(&a.Buffers[1].Buf[0])), 1)
a.resizeChildren(len(a.Type.(arrow.UnionType).Fields()))
switch sc := val.(type) {
case *scalar.DenseUnion:
codes[0] = sc.TypeCode
// has offset, start 4 bytes in so it's aligned to the 32-bit boundaries
off := unsafe.Slice((*int32)(unsafe.Add(unsafe.Pointer(&a.Scratch[0]), arrow.Int32SizeBytes)), 2)
setOffsetsForScalar(a, off, 1, 2)
// we can't "see" the other arrays in the union, but we put the "active"
// union array in the right place and fill zero-length arrays for
// the others.
childIDS := a.Type.(arrow.UnionType).ChildIDs()
for i, f := range a.Type.(arrow.UnionType).Fields() {
if i == childIDS[sc.TypeCode] {
a.Children[i].FillFromScalar(sc.Value)
} else {
FillZeroLength(f.Type, &a.Children[i])
}
}
case *scalar.SparseUnion:
codes[0] = sc.TypeCode
// sparse union scalars have a full complement of child values
// even though only one of them is relevant, so we just fill them
// in here
for i, v := range sc.Value {
a.Children[i].FillFromScalar(v)
}
}
case typeID == arrow.EXTENSION:
// pass through storage
sc := val.(*scalar.Extension)
a.FillFromScalar(sc.Value)
// restore the extension type
a.Type = val.DataType()
case typeID == arrow.NULL:
for i := range a.Buffers {
a.Buffers[i].Buf = nil
a.Buffers[i].Owner = nil
a.Buffers[i].SelfAlloc = false
}
}
}