diff --git a/arrow/scalar/scalar.go b/arrow/scalar/scalar.go index 194b11b3..ade9ed7c 100644 --- a/arrow/scalar/scalar.go +++ b/arrow/scalar/scalar.go @@ -771,6 +771,26 @@ func MakeArrayFromScalar(sc Scalar, length int, mem memory.Allocator) (arrow.Arr return nil, fmt.Errorf("%w: array length must be non-negative, got %d", arrow.ErrInvalid, length) } + if length == 0 { + if dt, ok := sc.DataType().(*arrow.RunEndEncodedType); ok { + runEndsBuilder := array.NewBuilder(mem, dt.RunEnds()) + defer runEndsBuilder.Release() + runEnds := runEndsBuilder.NewArray() + defer runEnds.Release() + + valuesBuilder := array.NewBuilder(mem, dt.Encoded()) + defer valuesBuilder.Release() + values := valuesBuilder.NewArray() + defer values.Release() + + return array.NewRunEndEncodedArray(runEnds, values, 0, 0), nil + } + + builder := array.NewBuilder(mem, sc.DataType()) + defer builder.Release() + return builder.NewArray(), nil + } + if !sc.IsValid() { return MakeArrayOfNull(sc.DataType(), length, mem), nil } diff --git a/arrow/scalar/scalar_test.go b/arrow/scalar/scalar_test.go index 392019d7..666e45e5 100644 --- a/arrow/scalar/scalar_test.go +++ b/arrow/scalar/scalar_test.go @@ -1349,6 +1349,33 @@ func TestMakeArrayFromScalarUsesCorrectBinaryOffsetWidthForNulls(t *testing.T) { } } +func TestMakeArrayFromScalarSupportsZeroLength(t *testing.T) { + mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) + defer mem.AssertSize(t, 0) + + for _, s := range getScalars(mem) { + t.Run(s.DataType().Name(), func(t *testing.T) { + if releasable, ok := s.(scalar.Releasable); ok { + defer releasable.Release() + } + + arr, err := scalar.MakeArrayFromScalar(s, 0, mem) + require.NoError(t, err) + defer arr.Release() + assert.Equal(t, 0, arr.Len()) + assert.Equal(t, 0, arr.NullN()) + require.NoError(t, array.ValidateFull(arr)) + }) + } + + nullArr, err := scalar.MakeArrayFromScalar(scalar.ScalarNull, 0, mem) + require.NoError(t, err) + defer nullArr.Release() + assert.Equal(t, 0, nullArr.Len()) + assert.Equal(t, 0, nullArr.NullN()) + require.NoError(t, array.ValidateFull(nullArr)) +} + func TestMakeArrayFromScalarRejectsNegativeLength(t *testing.T) { mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) defer mem.AssertSize(t, 0)