blob: 7269f4fd0a5e4b8d7fb1835f1d100138d678cd17 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package array_test
import (
"strings"
"testing"
"github.com/apache/arrow-go/v18/arrow"
"github.com/apache/arrow-go/v18/arrow/array"
"github.com/apache/arrow-go/v18/arrow/memory"
"github.com/apache/arrow-go/v18/internal/json"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func makeRunEndEncodedArrayRaw(t *testing.T, dt *arrow.RunEndEncodedType, logicalLength, nulls, offset int, buffers []*memory.Buffer, children []arrow.ArrayData) *array.RunEndEncoded {
t.Helper()
data := array.NewData(dt, logicalLength, buffers, children, nulls, offset)
arr := array.NewRunEndEncodedData(data)
data.Release()
return arr
}
var (
stringValues, _, _ = array.FromJSON(memory.DefaultAllocator, arrow.BinaryTypes.String, strings.NewReader(`["Hello", "World", null]`))
int32Values, _, _ = array.FromJSON(memory.DefaultAllocator, arrow.PrimitiveTypes.Int32, strings.NewReader(`[10, 20, 30]`))
int32OnlyNull = array.MakeArrayOfNull(memory.DefaultAllocator, arrow.PrimitiveTypes.Int32, 3)
)
func TestMakeRLEArray(t *testing.T) {
rleArr := array.NewRunEndEncodedArray(int32Values, stringValues, 3, 0)
defer rleArr.Release()
arrData := rleArr.Data()
newArr := array.MakeFromData(arrData)
defer newArr.Release()
assert.Same(t, newArr.Data(), arrData)
assert.IsType(t, (*array.RunEndEncoded)(nil), newArr)
}
func TestRLEFromRunEndsAndValues(t *testing.T) {
rleArray := array.NewRunEndEncodedArray(int32Values, int32Values, 3, 0)
defer rleArray.Release()
assert.EqualValues(t, 3, rleArray.Len())
assert.Truef(t, array.Equal(int32Values, rleArray.Values()), "expected: %s\ngot: %s", int32Values, rleArray.Values())
assert.Truef(t, array.Equal(int32Values, rleArray.RunEndsArr()), "expected: %s\ngot: %s", int32Values, rleArray.RunEndsArr())
assert.Zero(t, rleArray.Offset())
assert.Zero(t, rleArray.Data().NullN())
// one dummy buffer, since code may assume there's at least one nil buffer
assert.Len(t, rleArray.Data().Buffers(), 1)
// explicit offset
rleArray = array.NewRunEndEncodedArray(int32Values, stringValues, 2, 1)
defer rleArray.Release()
assert.EqualValues(t, 2, rleArray.Len())
assert.Truef(t, array.Equal(stringValues, rleArray.Values()), "expected: %s\ngot: %s", stringValues, rleArray.Values())
assert.Truef(t, array.Equal(int32Values, rleArray.RunEndsArr()), "expected: %s\ngot: %s", int32Values, rleArray.RunEndsArr())
assert.EqualValues(t, 1, rleArray.Offset())
assert.Zero(t, rleArray.Data().NullN())
assert.PanicsWithError(t, "invalid: arrow/array: run ends array must be int16, int32, or int64", func() {
array.NewRunEndEncodedArray(stringValues, int32Values, 3, 0)
})
assert.PanicsWithError(t, "invalid: arrow/array: run ends array cannot contain nulls", func() {
array.NewRunEndEncodedArray(int32OnlyNull, int32Values, 3, 0)
})
}
func TestRunEndEncodedValidate(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
t.Run("valid array passes", func(t *testing.T) {
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[1, 3]`))
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["a", "b"]`))
defer runEnds.Release()
defer values.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 3, 0, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEnds.Data(), values.Data()})
defer arr.Release()
assert.NoError(t, arr.Validate())
assert.NoError(t, arr.ValidateFull())
})
t.Run("last run end shorter than logical length fails Validate", func(t *testing.T) {
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[1, 2]`))
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["a", "b"]`))
defer runEnds.Release()
defer values.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 3, 0, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEnds.Data(), values.Data()})
defer arr.Release()
err := arr.Validate()
require.Error(t, err)
assert.Contains(t, err.Error(), "last run end")
})
t.Run("duplicate run ends pass Validate but fail ValidateFull", func(t *testing.T) {
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[2, 2]`))
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["first", "second"]`))
defer runEnds.Release()
defer values.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 2, 0, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEnds.Data(), values.Data()})
defer arr.Release()
assert.NoError(t, arr.Validate())
err := arr.ValidateFull()
require.Error(t, err)
assert.Contains(t, err.Error(), "strictly greater")
})
t.Run("top level ValidateFull catches duplicate run ends", func(t *testing.T) {
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[2, 2]`))
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["first", "second"]`))
defer runEnds.Release()
defer values.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 2, 0, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEnds.Data(), values.Data()})
defer arr.Release()
assert.NoError(t, array.Validate(arr))
err := array.ValidateFull(arr)
require.Error(t, err)
assert.Contains(t, err.Error(), "strictly greater")
})
t.Run("unknown null counts without bitmaps still validate", func(t *testing.T) {
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[1, 3]`))
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["a", "b"]`))
defer runEnds.Release()
defer values.Release()
runEndsData := runEnds.Data().(*array.Data).Copy()
runEndsData.SetNullN(array.UnknownNullCount)
defer runEndsData.Release()
valuesData := values.Data().(*array.Data).Copy()
defer valuesData.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 3, array.UnknownNullCount, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEndsData, valuesData})
defer arr.Release()
assert.NoError(t, arr.Validate())
assert.NoError(t, arr.ValidateFull())
})
t.Run("run ends with lazy null count fail Validate", func(t *testing.T) {
validity := memory.NewBufferBytes([]byte{0x01})
valuesBuf := memory.NewBufferBytes(arrow.Int32Traits.CastToBytes([]int32{1, 3}))
runEndsData := array.NewData(arrow.PrimitiveTypes.Int32, 2, []*memory.Buffer{validity, valuesBuf}, nil, array.UnknownNullCount, 0)
defer runEndsData.Release()
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["a", "b"]`))
defer values.Release()
arr := makeRunEndEncodedArrayRaw(t, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int32, arrow.BinaryTypes.String), 3, 0, 0,
[]*memory.Buffer{nil}, []arrow.ArrayData{runEndsData, values.Data()})
defer arr.Release()
err := arr.Validate()
require.Error(t, err)
assert.Contains(t, err.Error(), "run ends array cannot contain nulls")
})
}
func TestRunLengthEncodedOffsetLength(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
runEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[100, 200, 300, 400, 500]`))
defer runEnds.Release()
values, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["Hello", "beautiful", "world", "of", "RLE"]`))
defer values.Release()
rleArray := array.NewRunEndEncodedArray(runEnds, values, 500, 0)
defer rleArray.Release()
assert.EqualValues(t, 5, rleArray.GetPhysicalLength())
assert.EqualValues(t, 0, rleArray.GetPhysicalOffset())
slice := array.NewSlice(rleArray, 199, 204).(*array.RunEndEncoded)
defer slice.Release()
assert.EqualValues(t, 2, slice.GetPhysicalLength())
assert.EqualValues(t, 1, slice.GetPhysicalOffset())
slice2 := array.NewSlice(rleArray, 199, 300).(*array.RunEndEncoded)
defer slice2.Release()
assert.EqualValues(t, 2, slice2.GetPhysicalLength())
assert.EqualValues(t, 1, slice2.GetPhysicalOffset())
slice3 := array.NewSlice(rleArray, 400, 500).(*array.RunEndEncoded)
defer slice3.Release()
assert.EqualValues(t, 1, slice3.GetPhysicalLength())
assert.EqualValues(t, 4, slice3.GetPhysicalOffset())
slice4 := array.NewSlice(rleArray, 0, 150).(*array.RunEndEncoded)
defer slice4.Release()
assert.EqualValues(t, 2, slice4.GetPhysicalLength())
assert.EqualValues(t, 0, slice4.GetPhysicalOffset())
zeroLengthAtEnd := array.NewSlice(rleArray, 500, 500).(*array.RunEndEncoded)
defer zeroLengthAtEnd.Release()
assert.EqualValues(t, 0, zeroLengthAtEnd.GetPhysicalLength())
assert.EqualValues(t, 5, zeroLengthAtEnd.GetPhysicalOffset())
}
func TestRLECompare(t *testing.T) {
rleArray := array.NewRunEndEncodedArray(int32Values, stringValues, 30, 0)
// second that is a copy of the first
standardEquals := array.MakeFromData(rleArray.Data().(*array.Data).Copy())
defer rleArray.Release()
defer standardEquals.Release()
assert.Truef(t, array.Equal(rleArray, standardEquals), "left: %s\nright: %s", rleArray, standardEquals)
assert.False(t, array.Equal(array.NewSlice(rleArray, 0, 29), array.NewSlice(rleArray, 1, 30)))
// array that is logically the same as our rleArray, but has 2 small
// runs for the first value instead of one large run
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
t.Run("logical duplicate", func(t *testing.T) {
dupRunEnds, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[5, 10, 20, 30]`))
defer dupRunEnds.Release()
strValues, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String,
strings.NewReader(`["Hello", "Hello", "World", null]`))
defer strValues.Release()
dupArr := array.NewRunEndEncodedArray(dupRunEnds, strValues, 30, 0)
defer dupArr.Release()
assert.Truef(t, array.Equal(rleArray, dupArr), "expected: %sgot: %s", rleArray, dupArr)
})
t.Run("emptyArr", func(t *testing.T) {
emptyRuns, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[]`))
emptyVals, _, _ := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`[]`))
defer emptyRuns.Release()
defer emptyVals.Release()
emptyArr := array.NewRunEndEncodedArray(emptyRuns, emptyVals, 0, 0)
defer emptyArr.Release()
dataCopy := emptyArr.Data().(*array.Data).Copy()
defer dataCopy.Release()
emptyArr2 := array.MakeFromData(dataCopy)
defer emptyArr2.Release()
assert.Truef(t, array.Equal(emptyArr, emptyArr2), "expected: %sgot: %s", emptyArr, emptyArr2)
})
t.Run("different offsets", func(t *testing.T) {
// three different slices that have the value [3, 3, 3, 4, 4, 4, 4]
offsetsa, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32,
strings.NewReader(`[2, 5, 12, 58, 60]`))
offsetsb, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32,
strings.NewReader(`[81, 86, 99, 100]`))
offsetsc, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int32,
strings.NewReader(`[3, 7]`))
valsa, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int64,
strings.NewReader(`[1, 2, 3, 4, 5]`))
valsb, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int64,
strings.NewReader(`[2, 3, 4, 5]`))
valsc, _, _ := array.FromJSON(mem, arrow.PrimitiveTypes.Int64,
strings.NewReader(`[3, 4]`))
defer func() {
offsetsa.Release()
offsetsb.Release()
offsetsc.Release()
valsa.Release()
valsb.Release()
valsc.Release()
}()
differentOffsetsA := array.NewRunEndEncodedArray(offsetsa, valsa, 60, 0)
defer differentOffsetsA.Release()
differentOffsetsB := array.NewRunEndEncodedArray(offsetsb, valsb, 100, 0)
defer differentOffsetsB.Release()
differentOffsetsC := array.NewRunEndEncodedArray(offsetsc, valsc, 7, 0)
defer differentOffsetsC.Release()
sliceA := array.NewSlice(differentOffsetsA, 9, 16)
defer sliceA.Release()
sliceB := array.NewSlice(differentOffsetsB, 83, 90)
defer sliceB.Release()
assert.True(t, array.Equal(sliceA, sliceB))
assert.True(t, array.Equal(sliceA, differentOffsetsC))
assert.True(t, array.Equal(sliceB, differentOffsetsC))
})
}
func TestRunEndEncodedBuilder(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewBuilder(mem, arrow.RunEndEncodedOf(arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String))
defer bldr.Release()
assert.IsType(t, (*array.RunEndEncodedBuilder)(nil), bldr)
reeBldr := bldr.(*array.RunEndEncodedBuilder)
valBldr := reeBldr.ValueBuilder().(*array.StringBuilder)
reeBldr.Append(100)
valBldr.Append("Hello")
reeBldr.Append(100)
valBldr.Append("beautiful")
reeBldr.Append(50)
valBldr.Append("world")
reeBldr.ContinueRun(50)
reeBldr.Append(100)
valBldr.Append("of")
reeBldr.Append(100)
valBldr.Append("RLE")
reeBldr.AppendNull()
rleArray := reeBldr.NewRunEndEncodedArray()
defer rleArray.Release()
assert.EqualValues(t, 501, rleArray.Len())
assert.EqualValues(t, 6, rleArray.GetPhysicalLength())
assert.Equal(t, arrow.INT16, rleArray.RunEndsArr().DataType().ID())
assert.Equal(t, []int16{100, 200, 300, 400, 500, 501}, rleArray.RunEndsArr().(*array.Int16).Int16Values())
strValues := rleArray.Values().(*array.String)
assert.Equal(t, "Hello", strValues.Value(0))
assert.Equal(t, "beautiful", strValues.Value(1))
assert.Equal(t, "world", strValues.Value(2))
assert.Equal(t, "of", strValues.Value(3))
assert.Equal(t, "RLE", strValues.Value(4))
assert.True(t, strValues.IsNull(5))
assert.Equal(t, "Hello", strValues.ValueStr(0))
}
func TestRunEndEncodedStringRoundTrip(t *testing.T) {
// 1. create array
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
b := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String)
defer b.Release()
valBldr := b.ValueBuilder().(*array.StringBuilder)
b.Append(100)
valBldr.Append("Hello")
b.Append(100)
valBldr.Append("beautiful")
b.Append(50)
valBldr.Append("world")
b.ContinueRun(50)
b.Append(100)
valBldr.Append("of")
b.Append(100)
valBldr.Append("RLE")
b.AppendNull()
arr := b.NewArray().(*array.RunEndEncoded)
defer arr.Release()
logical := arr.LogicalValuesArray()
defer logical.Release()
// 2. create array via AppendValueFromString
b1 := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String)
defer b1.Release()
for i := 0; i < arr.Len(); i++ {
assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
}
arr1 := b1.NewArray().(*array.RunEndEncoded)
defer arr1.Release()
logical1 := arr1.LogicalValuesArray()
defer logical1.Release()
assert.True(t, array.Equal(arr, arr1))
assert.True(t, array.Equal(logical, logical1))
}
func TestREEBuilderOverflow(t *testing.T) {
for _, typ := range []arrow.DataType{arrow.PrimitiveTypes.Int16, arrow.PrimitiveTypes.Int32, arrow.PrimitiveTypes.Int64} {
t.Run("run_ends="+typ.String(), func(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewRunEndEncodedBuilder(mem, typ, arrow.BinaryTypes.String)
defer bldr.Release()
valBldr := bldr.ValueBuilder().(*array.StringBuilder)
assert.Panics(t, func() {
valBldr.Append("Foo")
maxVal := uint64(1<<typ.(arrow.FixedWidthDataType).BitWidth()) - 1
bldr.Append(uint64(maxVal))
})
})
}
}
func TestLogicalRunEndsValuesArray(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String)
defer bldr.Release()
valBldr := bldr.ValueBuilder().(*array.StringBuilder)
// produces run-ends 1, 2, 4, 6, 10, 1000, 1750, 2000
bldr.AppendRuns([]uint64{1, 1, 2, 2, 4, 990, 750, 250})
valBldr.AppendValues([]string{"a", "b", "c", "d", "e", "f", "g", "h"}, nil)
arr := bldr.NewRunEndEncodedArray()
defer arr.Release()
sl := array.NewSlice(arr, 150, 1650)
defer sl.Release()
assert.EqualValues(t, 150, sl.Data().Offset())
assert.EqualValues(t, 1500, sl.Len())
logicalValues := sl.(*array.RunEndEncoded).LogicalValuesArray()
defer logicalValues.Release()
logicalRunEnds := sl.(*array.RunEndEncoded).LogicalRunEndsArray(mem)
defer logicalRunEnds.Release()
expectedValues, _, err := array.FromJSON(mem, arrow.BinaryTypes.String, strings.NewReader(`["f", "g"]`))
require.NoError(t, err)
defer expectedValues.Release()
expectedRunEnds := []int16{850, 1500}
assert.Truef(t, array.Equal(logicalValues, expectedValues), "expected: %s\ngot: %s", expectedValues, logicalValues)
assert.Equal(t, expectedRunEnds, logicalRunEnds.(*array.Int16).Int16Values())
}
func TestLogicalRunEndsValuesArrayEmpty(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String)
defer bldr.Release()
valBldr := bldr.ValueBuilder().(*array.StringBuilder)
// produces run-ends 1, 2, 4, 6, 10, 1000, 1750, 2000
bldr.AppendRuns([]uint64{1, 1, 2, 2, 4, 990, 750, 250})
valBldr.AppendValues([]string{"a", "b", "c", "d", "e", "f", "g", "h"}, nil)
arr := bldr.NewRunEndEncodedArray()
defer arr.Release()
emptySlice := array.NewSlice(arr, 2000, 2000)
defer emptySlice.Release()
assert.EqualValues(t, 2000, emptySlice.Data().Offset())
assert.EqualValues(t, 0, emptySlice.Len())
logicalValues := emptySlice.(*array.RunEndEncoded).LogicalValuesArray()
defer logicalValues.Release()
logicalRunEnds := emptySlice.(*array.RunEndEncoded).LogicalRunEndsArray(mem)
defer logicalRunEnds.Release()
assert.Zero(t, logicalValues.Len())
assert.Zero(t, logicalRunEnds.Len())
empty := bldr.NewRunEndEncodedArray()
defer empty.Release()
assert.EqualValues(t, 0, empty.Data().Offset())
assert.EqualValues(t, 0, empty.Len())
logicalValues = empty.LogicalValuesArray()
defer logicalValues.Release()
logicalRunEnds = empty.LogicalRunEndsArray(mem)
defer logicalRunEnds.Release()
assert.Zero(t, logicalValues.Len())
assert.Zero(t, logicalRunEnds.Len())
}
func TestRunEndEncodedUnmarshalJSON(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16, arrow.BinaryTypes.String)
defer bldr.Release()
const testJSON = `
[ null, "a", "a", "a", "b", "b", "b", null, null, "c", "d", "d", "d", null, null, null, "e", "e"]`
require.NoError(t, json.Unmarshal([]byte(testJSON), bldr))
arr := bldr.NewRunEndEncodedArray()
defer arr.Release()
expectedValues, _, err := array.FromJSON(mem, arrow.BinaryTypes.String,
strings.NewReader(`[null, "a", "b", null, "c", "d", null, "e"]`))
require.NoError(t, err)
defer expectedValues.Release()
assert.EqualValues(t, 18, arr.Len())
assert.Equal(t, []int16{1, 4, 7, 9, 10, 13, 16, 18}, arr.RunEndsArr().(*array.Int16).Int16Values())
logicalValues := arr.LogicalValuesArray()
defer logicalValues.Release()
assert.Truef(t, array.Equal(logicalValues, expectedValues), "expected: %s\ngot: %s", expectedValues, logicalValues)
}
func TestRunEndEncodedUnmarshalNestedJSON(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
bldr := array.NewRunEndEncodedBuilder(mem, arrow.PrimitiveTypes.Int16,
arrow.ListOf(arrow.PrimitiveTypes.Int32))
defer bldr.Release()
const testJSON = `
[null, [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, null, 3], [4, 5, null], null, null,
[4, 5, null], [4, 5, null], [4, 5, null]]
`
require.NoError(t, json.Unmarshal([]byte(testJSON), bldr))
arr := bldr.NewRunEndEncodedArray()
defer arr.Release()
assert.EqualValues(t, 11, arr.Len())
assert.Equal(t, []int16{1, 4, 5, 6, 8, 11}, arr.RunEndsArr().(*array.Int16).Int16Values())
expectedValues, _, err := array.FromJSON(mem, arrow.ListOf(arrow.PrimitiveTypes.Int32),
strings.NewReader(`[null, [1, 2, 3], [1, null, 3], [4, 5, null], null, [4, 5, null]]`))
require.NoError(t, err)
defer expectedValues.Release()
logicalValues := arr.LogicalValuesArray()
defer logicalValues.Release()
assert.Truef(t, array.Equal(logicalValues, expectedValues), "expected: %s\ngot: %s", expectedValues, logicalValues)
}