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 b497053f fix(arrow/scalar): handle zero-length scalar arrays (#1116)
b497053f is described below
commit b497053f636ca7bc9d2463aec4eeeeefc2c53c48
Author: Minh Vu <[email protected]>
AuthorDate: Fri Aug 14 18:05:25 2026 +0200
fix(arrow/scalar): handle zero-length scalar arrays (#1116)
### Rationale for this change
MakeArrayFromScalar accepts a length of zero, but nested scalar types
try to concatenate an empty input. Run-end encoded scalars also need an
empty physical representation.
### What changes are included in this PR?
Use empty builders for zero-length output and construct run-end encoded
arrays with zero runs. Add coverage for nested and run-end encoded
scalars.
### Are these changes tested?
- `go test ./arrow/scalar`
### Are there any user-facing changes?
No API changes. This corrects the reported behavior while preserving the
existing ownership and compatibility contracts.
---
arrow/scalar/scalar.go | 20 ++++++++++++++++++++
arrow/scalar/scalar_test.go | 27 +++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
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)