This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git


The following commit(s) were added to refs/heads/main by this push:
     new cb9c80ea fix(arrow/array): fix panic in dictionary builders (#517)
cb9c80ea is described below

commit cb9c80ea223c4fe69db46797b61a7cfae497156f
Author: Matt Topol <[email protected]>
AuthorDate: Wed Sep 24 10:49:21 2025 -0400

    fix(arrow/array): fix panic in dictionary builders (#517)
    
    ### Rationale for this change
    The underlying hash table is in terms of primitive types
    (int64/int32/int16, etc.) not the top-level types (arrow.Duration,
    arrow.Timestamp, etc.) which results in a panic mismatch when appending
    values.
    
    fixes #516
    
    ### What changes are included in this PR?
    Checking and validating the type when appendValue is called to ensure
    correct type coercion.
    
    ### Are these changes tested?
    A unit test is added in this change.
    
    ### Are there any user-facing changes?
    A case that previously caused a panic will now be successful.
---
 arrow/array/dictionary.go      | 16 ++++++++++++++++
 arrow/array/dictionary_test.go | 14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/arrow/array/dictionary.go b/arrow/array/dictionary.go
index 395faf41..109d2a97 100644
--- a/arrow/array/dictionary.go
+++ b/arrow/array/dictionary.go
@@ -991,6 +991,22 @@ type dictBuilder[T arrow.ValueType] struct {
 }
 
 func (b *dictBuilder[T]) Append(v T) error {
+       switch val := any(v).(type) {
+       case arrow.Duration:
+               return b.appendValue(int64(val))
+       case arrow.Timestamp:
+               return b.appendValue(int64(val))
+       case arrow.Time32:
+               return b.appendValue(int32(val))
+       case arrow.Time64:
+               return b.appendValue(int64(val))
+       case arrow.Date32:
+               return b.appendValue(int32(val))
+       case arrow.Date64:
+               return b.appendValue(int64(val))
+       case arrow.MonthInterval:
+               return b.appendValue(int32(val))
+       }
        return b.appendValue(v)
 }
 
diff --git a/arrow/array/dictionary_test.go b/arrow/array/dictionary_test.go
index ba85aa1d..9b9d3b1f 100644
--- a/arrow/array/dictionary_test.go
+++ b/arrow/array/dictionary_test.go
@@ -1899,6 +1899,20 @@ func TestBinaryDictionaryPanic(t *testing.T) {
        assert.True(t, allocator.paniced)
 }
 
+func TestDictionaryBuilderDuration(t *testing.T) {
+       // verify fix for https://github.com/apache/arrow-go/issues/516
+       dictType := &arrow.DictionaryType{
+               IndexType: arrow.PrimitiveTypes.Int8,
+               ValueType: arrow.FixedWidthTypes.Duration_ms}
+       bldr := array.NewDictionaryBuilder(memory.DefaultAllocator, dictType)
+       defer bldr.Release()
+
+       b := bldr.(*array.DurationDictionaryBuilder)
+       assert.NoError(t, b.Append(arrow.Duration(42)))
+       arr := b.NewDictionaryArray()
+       defer arr.Release()
+}
+
 func BenchmarkBinaryDictionaryBuilder(b *testing.B) {
        mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
        defer mem.AssertSize(b, 0)

Reply via email to