Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 47 additions & 10 deletions arrow/array/arreflect/reflect_arrow_to_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,52 +161,89 @@ func setPrimitiveValue(v reflect.Value, arr arrow.Array, i int) error {
if !isIntKind(v.Kind()) {
return fmt.Errorf("cannot set int8 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetInt(int64(arr.(*array.Int8).Value(i)))
val := int64(arr.(*array.Int8).Value(i))
if v.OverflowInt(val) {
return fmt.Errorf("cannot set int8 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetInt(val)
case arrow.INT16:
if !isIntKind(v.Kind()) {
return fmt.Errorf("cannot set int16 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetInt(int64(arr.(*array.Int16).Value(i)))
val := int64(arr.(*array.Int16).Value(i))
if v.OverflowInt(val) {
return fmt.Errorf("cannot set int16 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetInt(val)
case arrow.INT32:
if !isIntKind(v.Kind()) {
return fmt.Errorf("cannot set int32 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetInt(int64(arr.(*array.Int32).Value(i)))
val := int64(arr.(*array.Int32).Value(i))
if v.OverflowInt(val) {
return fmt.Errorf("cannot set int32 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetInt(val)
case arrow.INT64:
if !isIntKind(v.Kind()) {
return fmt.Errorf("cannot set int64 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetInt(arr.(*array.Int64).Value(i))
val := arr.(*array.Int64).Value(i)
if v.OverflowInt(val) {
return fmt.Errorf("cannot set int64 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetInt(val)
case arrow.UINT8:
if !isUintKind(v.Kind()) {
return fmt.Errorf("cannot set uint8 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetUint(uint64(arr.(*array.Uint8).Value(i)))
val := uint64(arr.(*array.Uint8).Value(i))
if v.OverflowUint(val) {
return fmt.Errorf("cannot set uint8 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetUint(val)
case arrow.UINT16:
if !isUintKind(v.Kind()) {
return fmt.Errorf("cannot set uint16 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetUint(uint64(arr.(*array.Uint16).Value(i)))
val := uint64(arr.(*array.Uint16).Value(i))
if v.OverflowUint(val) {
return fmt.Errorf("cannot set uint16 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetUint(val)
case arrow.UINT32:
if !isUintKind(v.Kind()) {
return fmt.Errorf("cannot set uint32 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetUint(uint64(arr.(*array.Uint32).Value(i)))
val := uint64(arr.(*array.Uint32).Value(i))
if v.OverflowUint(val) {
return fmt.Errorf("cannot set uint32 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetUint(val)
case arrow.UINT64:
if !isUintKind(v.Kind()) {
return fmt.Errorf("cannot set uint64 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetUint(arr.(*array.Uint64).Value(i))
val := arr.(*array.Uint64).Value(i)
if v.OverflowUint(val) {
return fmt.Errorf("cannot set uint64 value %d into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetUint(val)
case arrow.FLOAT32:
if !isFloatKind(v.Kind()) {
return fmt.Errorf("cannot set float32 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetFloat(float64(arr.(*array.Float32).Value(i)))
val := float64(arr.(*array.Float32).Value(i))
v.SetFloat(val)
case arrow.FLOAT64:
if !isFloatKind(v.Kind()) {
return fmt.Errorf("cannot set float64 into %s: %w", v.Type(), ErrTypeMismatch)
}
v.SetFloat(arr.(*array.Float64).Value(i))
val := arr.(*array.Float64).Value(i)
if v.OverflowFloat(val) {
return fmt.Errorf("cannot set float64 value %f into %s: %w", val, v.Type(), ErrTypeMismatch)
}
v.SetFloat(val)
default:
return fmt.Errorf("unsupported primitive type %v: %w", arr.DataType(), ErrUnsupportedType)
}
Expand Down
40 changes: 40 additions & 0 deletions arrow/array/arreflect/reflect_arrow_to_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package arreflect

import (
"math"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -217,6 +218,19 @@ func TestSetPrimitiveValue(t *testing.T) {
assert.ErrorIs(t, setPrimitiveValue(reflect.ValueOf(&bad).Elem(), arr, 0), ErrTypeMismatch)
})

t.Run("int64 overflow into int8 returns error", func(t *testing.T) {
b := array.NewInt64Builder(mem)
defer b.Release()
b.Append(int64(300))
arr := b.NewArray().(*array.Int64)
defer arr.Release()

got := int8(7)
err := setPrimitiveValue(reflect.ValueOf(&got).Elem(), arr, 0)
assert.ErrorIs(t, err, ErrTypeMismatch)
assert.Equal(t, int8(7), got)
})

t.Run("uint16", func(t *testing.T) {
b := array.NewUint16Builder(mem)
defer b.Release()
Expand All @@ -232,6 +246,19 @@ func TestSetPrimitiveValue(t *testing.T) {
assert.ErrorIs(t, setPrimitiveValue(reflect.ValueOf(&bad).Elem(), arr, 0), ErrTypeMismatch)
})

t.Run("uint64 overflow into uint8 returns error", func(t *testing.T) {
b := array.NewUint64Builder(mem)
defer b.Release()
b.Append(300)
arr := b.NewArray().(*array.Uint64)
defer arr.Release()

got := uint8(7)
err := setPrimitiveValue(reflect.ValueOf(&got).Elem(), arr, 0)
assert.ErrorIs(t, err, ErrTypeMismatch)
assert.Equal(t, uint8(7), got)
})

t.Run("uint32", func(t *testing.T) {
b := array.NewUint32Builder(mem)
defer b.Release()
Expand Down Expand Up @@ -288,6 +315,19 @@ func TestSetPrimitiveValue(t *testing.T) {
assert.ErrorIs(t, setPrimitiveValue(reflect.ValueOf(&bad).Elem(), arr, 0), ErrTypeMismatch)
})

t.Run("float64 overflow into float32 returns error", func(t *testing.T) {
b := array.NewFloat64Builder(mem)
defer b.Release()
b.Append(math.MaxFloat64)
arr := b.NewArray().(*array.Float64)
defer arr.Release()

got := float32(1)
err := setPrimitiveValue(reflect.ValueOf(&got).Elem(), arr, 0)
assert.ErrorIs(t, err, ErrTypeMismatch)
assert.Equal(t, float32(1), got)
})

t.Run("float64 mismatch", func(t *testing.T) {
b := array.NewFloat64Builder(mem)
defer b.Release()
Expand Down
Loading