func GetScalar()

in arrow/scalar/scalar.go [563:736]


func GetScalar(arr arrow.Array, idx int) (Scalar, error) {
	if arr.DataType().ID() != arrow.DICTIONARY && arr.IsNull(idx) {
		return MakeNullScalar(arr.DataType()), nil
	}

	if idx >= arr.Len() {
		return nil, fmt.Errorf("%w: called GetScalar with index larger than array len",
			arrow.ErrIndex)
	}

	switch arr := arr.(type) {
	case *array.Binary:
		buf := memory.NewBufferBytes(arr.Value(idx))
		defer buf.Release()
		return NewBinaryScalar(buf, arr.DataType()), nil
	case *array.LargeBinary:
		buf := memory.NewBufferBytes(arr.Value(idx))
		defer buf.Release()
		return NewLargeBinaryScalar(buf), nil
	case *array.Boolean:
		return NewBooleanScalar(arr.Value(idx)), nil
	case *array.Date32:
		return NewDate32Scalar(arr.Value(idx)), nil
	case *array.Date64:
		return NewDate64Scalar(arr.Value(idx)), nil
	case *array.DayTimeInterval:
		return NewDayTimeIntervalScalar(arr.Value(idx)), nil
	case *array.Decimal128:
		return NewDecimal128Scalar(arr.Value(idx), arr.DataType()), nil
	case *array.Decimal256:
		return NewDecimal256Scalar(arr.Value(idx), arr.DataType()), nil
	case *array.Duration:
		return NewDurationScalar(arr.Value(idx), arr.DataType()), nil
	case array.ExtensionArray:
		storage, err := GetScalar(arr.Storage(), idx)
		if err != nil {
			return nil, err
		}
		return NewExtensionScalar(storage, arr.DataType()), nil
	case *array.FixedSizeBinary:
		buf := memory.NewBufferBytes(arr.Value(idx))
		defer buf.Release()
		return NewFixedSizeBinaryScalar(buf, arr.DataType()), nil
	case *array.FixedSizeList:
		size := int(arr.DataType().(*arrow.FixedSizeListType).Len())
		slice := array.NewSlice(arr.ListValues(), int64(idx*size), int64((idx+1)*size))
		defer slice.Release()
		return NewFixedSizeListScalarWithType(slice, arr.DataType()), nil
	case *array.Float16:
		return NewFloat16Scalar(arr.Value(idx)), nil
	case *array.Float32:
		return NewFloat32Scalar(arr.Value(idx)), nil
	case *array.Float64:
		return NewFloat64Scalar(arr.Value(idx)), nil
	case *array.Int8:
		return NewInt8Scalar(arr.Value(idx)), nil
	case *array.Int16:
		return NewInt16Scalar(arr.Value(idx)), nil
	case *array.Int32:
		return NewInt32Scalar(arr.Value(idx)), nil
	case *array.Int64:
		return NewInt64Scalar(arr.Value(idx)), nil
	case *array.Uint8:
		return NewUint8Scalar(arr.Value(idx)), nil
	case *array.Uint16:
		return NewUint16Scalar(arr.Value(idx)), nil
	case *array.Uint32:
		return NewUint32Scalar(arr.Value(idx)), nil
	case *array.Uint64:
		return NewUint64Scalar(arr.Value(idx)), nil
	case *array.List:
		offsets := arr.Offsets()
		slice := array.NewSlice(arr.ListValues(), int64(offsets[idx]), int64(offsets[idx+1]))
		defer slice.Release()
		return NewListScalar(slice), nil
	case *array.LargeList:
		offsets := arr.Offsets()
		slice := array.NewSlice(arr.ListValues(), int64(offsets[idx]), int64(offsets[idx+1]))
		defer slice.Release()
		return NewLargeListScalar(slice), nil
	case *array.Map:
		offsets := arr.Offsets()
		slice := array.NewSlice(arr.ListValues(), int64(offsets[idx]), int64(offsets[idx+1]))
		defer slice.Release()
		return NewMapScalar(slice), nil
	case *array.MonthInterval:
		return NewMonthIntervalScalar(arr.Value(idx)), nil
	case *array.MonthDayNanoInterval:
		return NewMonthDayNanoIntervalScalar(arr.Value(idx)), nil
	case *array.Null:
		return ScalarNull, nil
	case *array.String:
		return NewStringScalar(arr.Value(idx)), nil
	case *array.LargeString:
		return NewLargeStringScalar(arr.Value(idx)), nil
	case *array.Struct:
		children := make(Vector, arr.NumField())
		for i := range children {
			child, err := GetScalar(arr.Field(i), idx)
			if err != nil {
				return nil, err
			}
			children[i] = child
		}
		return NewStructScalar(children, arr.DataType()), nil
	case *array.Time32:
		return NewTime32Scalar(arr.Value(idx), arr.DataType()), nil
	case *array.Time64:
		return NewTime64Scalar(arr.Value(idx), arr.DataType()), nil
	case *array.Timestamp:
		return NewTimestampScalar(arr.Value(idx), arr.DataType()), nil
	case *array.RunEndEncoded:
		physicalIndex := encoded.FindPhysicalIndex(arr.Data(), arr.Offset()+idx)
		value, err := GetScalar(arr.Values(), physicalIndex)
		if err != nil {
			return nil, err
		}

		return NewRunEndEncodedScalar(value, arr.DataType().(*arrow.RunEndEncodedType)), nil
	case *array.Dictionary:
		ty := arr.DataType().(*arrow.DictionaryType)
		valid := arr.IsValid(idx)
		scalar := &Dictionary{scalar: scalar{ty, valid}}
		if valid {
			index, err := MakeScalarParam(arr.GetValueIndex(idx), ty.IndexType)
			if err != nil {
				return nil, err
			}

			scalar.Value.Index = index
		} else {
			scalar.Value.Index = MakeNullScalar(ty.IndexType)
		}

		scalar.Value.Dict = arr.Dictionary()
		scalar.Value.Dict.Retain()
		return scalar, nil
	case *array.SparseUnion:
		var err error
		typeCode := arr.TypeCode(idx)
		children := make([]Scalar, arr.NumFields())
		defer func() {
			if err != nil {
				for _, c := range children {
					if c == nil {
						break
					}

					if v, ok := c.(Releasable); ok {
						v.Release()
					}
				}
			}
		}()

		for i := range arr.UnionType().Fields() {
			if children[i], err = GetScalar(arr.Field(i), idx); err != nil {
				return nil, err
			}
		}
		return NewSparseUnionScalar(children, typeCode, arr.UnionType().(*arrow.SparseUnionType)), nil
	case *array.DenseUnion:
		typeCode := arr.TypeCode(idx)
		child := arr.Field(arr.ChildID(idx))
		offset := arr.ValueOffset(idx)
		value, err := GetScalar(child, int(offset))
		if err != nil {
			return nil, err
		}
		return NewDenseUnionScalar(value, typeCode, arr.UnionType().(*arrow.DenseUnionType)), nil
	}

	return nil, fmt.Errorf("cannot create scalar from array of type %s", arr.DataType())
}