diff --git a/arrow/array/data.go b/arrow/array/data.go index 62284b39..6dafd8a9 100644 --- a/arrow/array/data.go +++ b/arrow/array/data.go @@ -147,7 +147,9 @@ func (d *Data) Release() { } for _, b := range d.childData { - b.Release() + if b != nil { + b.Release() + } } if d.dictionary != nil { diff --git a/arrow/array/data_test.go b/arrow/array/data_test.go index adc91a82..0a08c787 100644 --- a/arrow/array/data_test.go +++ b/arrow/array/data_test.go @@ -136,3 +136,22 @@ func TestSizeInBytes(t *testing.T) { } }) } + +func TestDataReleaseWithNilChildData(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.DefaultAllocator) + defer mem.AssertSize(t, 0) + + // Create a Data object that simulates the state after a failed concatenation + // where childData slice is allocated but contains nil elements + buffers := []*memory.Buffer{memory.NewBufferBytes([]byte("test-buffer"))} + data := NewData(arrow.ListOf(arrow.PrimitiveTypes.Int32), 1, buffers, nil, 0, 0) + + // Simulate the scenario where childData is allocated but elements remain nil + // This happens in concat.go when childData is allocated but concat() fails + data.childData = make([]arrow.ArrayData, 1) + // data.childData[0] remains nil (simulating failed concat) + + assert.NotPanics(t, func() { + data.Release() + }, "Release() should not panic when childData contains nil elements") +}