Skip to content

Commit

Permalink
GH-35965: [Go] Fix Decimal256DictionaryBuilder (#35966)
Browse files Browse the repository at this point in the history
### Rationale for this change
`Decimal256DictionaryBuilder` cannot append `decimal256` value and prefers `decimal128` instead.
```
cannot use v (variable of type decimal256.Num) as decimal128.Num value in argument to builder.Append
```

### What changes are included in this PR?

### Are these changes tested?
Yes

### Are there any user-facing changes?
Yes

* Closes: #35965

Authored-by: izveigor <izveigor@gmail.com>
Signed-off-by: Matt Topol <zotthewizard@gmail.com>
  • Loading branch information
izveigor committed Jun 7, 2023
1 parent 9630258 commit cd7f431
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
14 changes: 10 additions & 4 deletions go/arrow/array/dictionary.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/apache/arrow/go/v13/arrow"
"github.com/apache/arrow/go/v13/arrow/bitutil"
"github.com/apache/arrow/go/v13/arrow/decimal128"
"github.com/apache/arrow/go/v13/arrow/decimal256"
"github.com/apache/arrow/go/v13/arrow/float16"
"github.com/apache/arrow/go/v13/arrow/internal/debug"
"github.com/apache/arrow/go/v13/arrow/memory"
Expand All @@ -45,12 +46,12 @@ import (
//
// For example, the array:
//
// ["foo", "bar", "foo", "bar", "foo", "bar"]
// ["foo", "bar", "foo", "bar", "foo", "bar"]
//
// with dictionary ["bar", "foo"], would have the representation of:
//
// indices: [1, 0, 1, 0, 1, 0]
// dictionary: ["bar", "foo"]
// indices: [1, 0, 1, 0, 1, 0]
// dictionary: ["bar", "foo"]
//
// The indices in principle may be any integer type.
type Dictionary struct {
Expand Down Expand Up @@ -883,6 +884,11 @@ func getvalFn(arr arrow.Array) func(i int) interface{} {
val := typedarr.Value(i)
return (*(*[arrow.Decimal128SizeBytes]byte)(unsafe.Pointer(&val)))[:]
}
case *Decimal256:
return func(i int) interface{} {
val := typedarr.Value(i)
return (*(*[arrow.Decimal256SizeBytes]byte)(unsafe.Pointer(&val)))[:]
}
case *DayTimeInterval:
return func(i int) interface{} {
val := typedarr.Value(i)
Expand Down Expand Up @@ -1373,7 +1379,7 @@ type Decimal256DictionaryBuilder struct {
dictionaryBuilder
}

func (b *Decimal256DictionaryBuilder) Append(v decimal128.Num) error {
func (b *Decimal256DictionaryBuilder) Append(v decimal256.Num) error {
return b.appendValue((*(*[arrow.Decimal256SizeBytes]byte)(unsafe.Pointer(&v)))[:])
}
func (b *Decimal256DictionaryBuilder) InsertDictValues(arr *Decimal256) (err error) {
Expand Down
31 changes: 30 additions & 1 deletion go/arrow/array/dictionary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/apache/arrow/go/v13/arrow/array"
"github.com/apache/arrow/go/v13/arrow/bitutil"
"github.com/apache/arrow/go/v13/arrow/decimal128"
"github.com/apache/arrow/go/v13/arrow/decimal256"
"github.com/apache/arrow/go/v13/arrow/memory"
"github.com/apache/arrow/go/v13/internal/types"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -878,7 +879,7 @@ func TestFixedSizeBinaryDictionaryStringRoundTrip(t *testing.T) {
assert.True(t, array.Equal(arr, arr1))
}

func TestDecimalDictionaryBuilderBasic(t *testing.T) {
func TestDecimal128DictionaryBuilderBasic(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)

Expand Down Expand Up @@ -906,6 +907,34 @@ func TestDecimalDictionaryBuilderBasic(t *testing.T) {
assert.True(t, array.ArrayApproxEqual(expected, result))
}

func TestDecimal256DictionaryBuilderBasic(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)

test := []decimal256.Num{decimal256.FromI64(12), decimal256.FromI64(12), decimal256.FromI64(11), decimal256.FromI64(12)}
dictType := &arrow.DictionaryType{IndexType: &arrow.Int8Type{}, ValueType: &arrow.Decimal256Type{Precision: 2, Scale: 0}}
bldr := array.NewDictionaryBuilder(mem, dictType)
defer bldr.Release()

builder := bldr.(*array.Decimal256DictionaryBuilder)
for _, v := range test {
assert.NoError(t, builder.Append(v))
}

result := bldr.NewDictionaryArray()
defer result.Release()

indices, _, _ := array.FromJSON(mem, dictType.IndexType, strings.NewReader("[0, 0, 1, 0]"))
defer indices.Release()
dict, _, _ := array.FromJSON(mem, dictType.ValueType, strings.NewReader("[12, 11]"))
defer dict.Release()

expected := array.NewDictionaryArray(dictType, indices, dict)
defer expected.Release()

assert.True(t, array.ArrayApproxEqual(expected, result))
}

func TestNullDictionaryBuilderBasic(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
Expand Down

0 comments on commit cd7f431

Please sign in to comment.