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 28128ef0 test(arrow/array): make run-end-encoded concat tests valid on
32-bit platforms (#1408)
28128ef0 is described below
commit 28128ef0cc71db9c8865de06df38971efc8b396e
Author: Matt Topol <[email protected]>
AuthorDate: Mon Oct 26 15:21:24 2026 +0000
test(arrow/array): make run-end-encoded concat tests valid on 32-bit
platforms (#1408)
### Rationale for this change
`TestConcatRunEndEncodedInt64FinalRunEndClamp` panics on 386
(`GOARCH=386 go test ./arrow/array -run
TestConcatRunEndEncodedInt64FinalRunEndClamp`):
```
panic: arrow/array: index out of range
arrow/array/data.go:245 (NewSliceData)
arrow/array/concat_test.go:1231
```
The test builds its input with
`RunEndEncodedBuilder.Append(math.MaxInt64)`, which makes an array whose
length is `math.MaxInt64`. Array lengths are `int`, so on 32-bit targets
the length wraps negative and `array.NewSlice(big, 0, 1)` panics while
*building the input*: the test never reaches `Concatenate`. That is
exactly the platform it was written for, since #1219's original bug (an
`int(e)` conversion of the run end) only overflowed when `int` is 32
bits.
Two related tests, `TestConcatAlmostOverflowRunEndEncoding/int64` and
`TestConcatOverflowRunEndEncoding/int64`, have the same problem: they
build inputs whose logical lengths are near 2^62, which cannot exist
with 32-bit `int`.
These panics are not visible in CI, which only cross-builds for 386.
### What changes are included in this PR?
Test-only changes in `arrow/array/concat_test.go`:
- `TestConcatRunEndEncodedInt64FinalRunEndClamp` builds the one-element
input directly with `NewRunEndEncodedArray`: run ends `[math.MaxInt64]`,
logical length 1. That is the same shape as a one-element slice of a
`MaxInt64`-length run, and it is valid on 32-bit. The test now also
checks the concatenated run ends (`[5, 6]`) and values (`[1, 2]`), not
just the length.
- The two `*OverflowRunEndEncoding` tests skip their `int64` case when
`tt.max > math.MaxInt`, i.e. only where the inputs cannot be
constructed. The int16 and int32 cases still run everywhere.
### Are these changes tested?
- `GOARCH=386 go test ./arrow/array -run Concat`: ok (two `int64`
subtests skipped).
- `go test ./arrow/array`: ok on amd64, no skips.
- The rewritten clamp test still guards #1219: with #1219's `concat.go`
change reverted it fails on amd64 (`overflow in run-length-encoded run
ends concat`) and on 386 (wrong run ends).
- `go vet ./arrow/array` and `gofmt -l`: clean.
Not addressed here: `arrow/array` still has other, unrelated 386
failures in the decimal tests (e.g. `TestDecimal128Slice`,
`TestDecimal256Slice`), which fail the same way on main.
### Are there any user-facing changes?
No.
---
arrow/array/concat_test.go | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/arrow/array/concat_test.go b/arrow/array/concat_test.go
index ccd661ff..1beb650c 100644
--- a/arrow/array/concat_test.go
+++ b/arrow/array/concat_test.go
@@ -1222,19 +1222,29 @@ func TestConcatRunEndEncodedInt64FinalRunEndClamp(t
*testing.T) {
prefix := prefixBldr.NewArray()
defer prefix.Release()
- bigBldr := array.NewRunEndEncodedBuilder(mem,
arrow.PrimitiveTypes.Int64, arrow.PrimitiveTypes.Int64)
- defer bigBldr.Release()
- bigBldr.Append(math.MaxInt64)
- bigBldr.ValueBuilder().(*array.Int64Builder).Append(2)
- big := bigBldr.NewArray()
- defer big.Release()
- oneElem := array.NewSlice(big, 0, 1) // first element of the
MaxInt64-length run
+ // One logical element from a run ending at math.MaxInt64, as a slice
of the
+ // run's first element would be. Build it directly: an array whose
length is
+ // math.MaxInt64 cannot exist when int is 32 bits, but this one is
valid there.
+ runEndsBldr := array.NewInt64Builder(mem)
+ defer runEndsBldr.Release()
+ runEndsBldr.Append(math.MaxInt64)
+ runEnds := runEndsBldr.NewArray()
+ defer runEnds.Release()
+ valuesBldr := array.NewInt64Builder(mem)
+ defer valuesBldr.Release()
+ valuesBldr.Append(2)
+ values := valuesBldr.NewArray()
+ defer values.Release()
+ oneElem := array.NewRunEndEncodedArray(runEnds, values, 1, 0)
defer oneElem.Release()
result, err := array.Concatenate([]arrow.Array{prefix, oneElem}, mem)
require.NoError(t, err)
defer result.Release()
assert.EqualValues(t, 6, result.Len())
+ ree := result.(*array.RunEndEncoded)
+ assert.Equal(t, []int64{5, 6},
ree.RunEndsArr().(*array.Int64).Int64Values())
+ assert.Equal(t, []int64{1, 2},
ree.Values().(*array.Int64).Int64Values())
}
func TestConcatAlmostOverflowRunEndEncoding(t *testing.T) {
@@ -1249,6 +1259,11 @@ func TestConcatAlmostOverflowRunEndEncoding(t
*testing.T) {
for _, tt := range tests {
t.Run(tt.offsetType.String(), func(t *testing.T) {
+ if tt.max > math.MaxInt {
+ // The inputs' logical lengths are near tt.max,
and array lengths
+ // are ints, so this case cannot be built when
int is 32 bits.
+ t.Skipf("array lengths near %d do not fit in
int", tt.max)
+ }
mem :=
memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
@@ -1296,6 +1311,11 @@ func TestConcatOverflowRunEndEncoding(t *testing.T) {
for _, tt := range tests {
t.Run(tt.offsetType.String(), func(t *testing.T) {
+ if tt.max > math.MaxInt {
+ // The inputs' logical lengths are near tt.max,
and array lengths
+ // are ints, so this case cannot be built when
int is 32 bits.
+ t.Skipf("array lengths near %d do not fit in
int", tt.max)
+ }
mem :=
memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)