// Code generated by array/numericbuilder.gen_test.go.tmpl. DO NOT EDIT.

// 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 (
	"math"
	"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/stretchr/testify/assert"
)

func TestInt64StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewInt64Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Int64)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewInt64Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Int64)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewInt64Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt64Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewInt64Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewInt64Array()

	// check state of builder after NewInt64Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewInt64Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewInt64Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewInt64Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []int64{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Int64Values(), "unexpected Int64Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Int64Values(), 10, "unexpected length of Int64Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewInt64Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []int64{7, 8}, a.Int64Values())
	assert.Len(t, a.Int64Values(), 2)

	a.Release()

	var (
		want   = []int64{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewInt64Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Int64); !ok {
		t.Fatalf("could not type-assert to array.Int64")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Int64)
	if !ok {
		t.Fatalf("could not type-assert to array.Int64")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestInt64Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt64Builder(mem)
	defer ab.Release()

	exp := []int64{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewInt64Array()
	assert.Equal(t, exp, a.Int64Values())

	a.Release()
}

func TestInt64Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt64Builder(mem)
	defer ab.Release()

	exp := []int64{0, 1, 2, 3}

	ab.AppendValues([]int64{}, nil)
	a := ab.NewInt64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewInt64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]int64{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewInt64Array()
	assert.Equal(t, exp, a.Int64Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]int64{}, nil)
	a = ab.NewInt64Array()
	assert.Equal(t, exp, a.Int64Values())
	a.Release()
}

func TestInt64Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt64Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestInt64BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewInt64Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewInt64Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestUint64StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewUint64Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Uint64)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewUint64Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Uint64)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewUint64Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint64Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewUint64Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewUint64Array()

	// check state of builder after NewUint64Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewUint64Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewUint64Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewUint64Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []uint64{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Uint64Values(), "unexpected Uint64Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Uint64Values(), 10, "unexpected length of Uint64Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewUint64Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []uint64{7, 8}, a.Uint64Values())
	assert.Len(t, a.Uint64Values(), 2)

	a.Release()

	var (
		want   = []uint64{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewUint64Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Uint64); !ok {
		t.Fatalf("could not type-assert to array.Uint64")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Uint64)
	if !ok {
		t.Fatalf("could not type-assert to array.Uint64")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestUint64Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint64Builder(mem)
	defer ab.Release()

	exp := []uint64{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewUint64Array()
	assert.Equal(t, exp, a.Uint64Values())

	a.Release()
}

func TestUint64Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint64Builder(mem)
	defer ab.Release()

	exp := []uint64{0, 1, 2, 3}

	ab.AppendValues([]uint64{}, nil)
	a := ab.NewUint64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewUint64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]uint64{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewUint64Array()
	assert.Equal(t, exp, a.Uint64Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]uint64{}, nil)
	a = ab.NewUint64Array()
	assert.Equal(t, exp, a.Uint64Values())
	a.Release()
}

func TestUint64Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint64Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestUint64BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewUint64Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewUint64Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestFloat64StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewFloat64Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Float64)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewFloat64Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Float64)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewFloat64Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat64Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewFloat64Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewFloat64Array()

	// check state of builder after NewFloat64Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewFloat64Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewFloat64Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewFloat64Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []float64{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Float64Values(), "unexpected Float64Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Float64Values(), 10, "unexpected length of Float64Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewFloat64Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []float64{7, 8}, a.Float64Values())
	assert.Len(t, a.Float64Values(), 2)

	a.Release()

	var (
		want   = []float64{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewFloat64Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Float64); !ok {
		t.Fatalf("could not type-assert to array.Float64")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Float64)
	if !ok {
		t.Fatalf("could not type-assert to array.Float64")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestFloat64Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat64Builder(mem)
	defer ab.Release()

	exp := []float64{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewFloat64Array()
	assert.Equal(t, exp, a.Float64Values())

	a.Release()
}

func TestFloat64Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat64Builder(mem)
	defer ab.Release()

	exp := []float64{0, 1, 2, 3}

	ab.AppendValues([]float64{}, nil)
	a := ab.NewFloat64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewFloat64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]float64{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewFloat64Array()
	assert.Equal(t, exp, a.Float64Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]float64{}, nil)
	a = ab.NewFloat64Array()
	assert.Equal(t, exp, a.Float64Values())
	a.Release()
}

func TestFloat64Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat64Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestFloat64BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewFloat64Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, "+Inf", 2, 3, "NaN", "NaN", 4, 5, "-Inf"]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewFloat64Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.False(t, math.IsInf(float64(arr.Value(0)), 0), arr.Value(0))
	assert.True(t, math.IsInf(float64(arr.Value(2)), 1), arr.Value(2))
	assert.True(t, math.IsNaN(float64(arr.Value(5))), arr.Value(5))
}

func TestInt32StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewInt32Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Int32)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewInt32Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Int32)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewInt32Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt32Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewInt32Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewInt32Array()

	// check state of builder after NewInt32Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewInt32Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewInt32Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewInt32Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []int32{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Int32Values(), "unexpected Int32Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Int32Values(), 10, "unexpected length of Int32Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewInt32Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []int32{7, 8}, a.Int32Values())
	assert.Len(t, a.Int32Values(), 2)

	a.Release()

	var (
		want   = []int32{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewInt32Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Int32); !ok {
		t.Fatalf("could not type-assert to array.Int32")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Int32)
	if !ok {
		t.Fatalf("could not type-assert to array.Int32")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestInt32Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt32Builder(mem)
	defer ab.Release()

	exp := []int32{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewInt32Array()
	assert.Equal(t, exp, a.Int32Values())

	a.Release()
}

func TestInt32Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt32Builder(mem)
	defer ab.Release()

	exp := []int32{0, 1, 2, 3}

	ab.AppendValues([]int32{}, nil)
	a := ab.NewInt32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewInt32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]int32{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewInt32Array()
	assert.Equal(t, exp, a.Int32Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]int32{}, nil)
	a = ab.NewInt32Array()
	assert.Equal(t, exp, a.Int32Values())
	a.Release()
}

func TestInt32Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt32Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestInt32BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewInt32Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewInt32Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestUint32StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewUint32Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Uint32)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewUint32Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Uint32)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewUint32Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint32Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewUint32Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewUint32Array()

	// check state of builder after NewUint32Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewUint32Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewUint32Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewUint32Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []uint32{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Uint32Values(), "unexpected Uint32Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Uint32Values(), 10, "unexpected length of Uint32Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewUint32Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []uint32{7, 8}, a.Uint32Values())
	assert.Len(t, a.Uint32Values(), 2)

	a.Release()

	var (
		want   = []uint32{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewUint32Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Uint32); !ok {
		t.Fatalf("could not type-assert to array.Uint32")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Uint32)
	if !ok {
		t.Fatalf("could not type-assert to array.Uint32")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestUint32Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint32Builder(mem)
	defer ab.Release()

	exp := []uint32{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewUint32Array()
	assert.Equal(t, exp, a.Uint32Values())

	a.Release()
}

func TestUint32Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint32Builder(mem)
	defer ab.Release()

	exp := []uint32{0, 1, 2, 3}

	ab.AppendValues([]uint32{}, nil)
	a := ab.NewUint32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewUint32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]uint32{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewUint32Array()
	assert.Equal(t, exp, a.Uint32Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]uint32{}, nil)
	a = ab.NewUint32Array()
	assert.Equal(t, exp, a.Uint32Values())
	a.Release()
}

func TestUint32Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint32Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestUint32BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewUint32Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewUint32Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestFloat32StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewFloat32Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Float32)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewFloat32Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Float32)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewFloat32Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat32Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewFloat32Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewFloat32Array()

	// check state of builder after NewFloat32Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewFloat32Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewFloat32Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewFloat32Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []float32{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Float32Values(), "unexpected Float32Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Float32Values(), 10, "unexpected length of Float32Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewFloat32Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []float32{7, 8}, a.Float32Values())
	assert.Len(t, a.Float32Values(), 2)

	a.Release()

	var (
		want   = []float32{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewFloat32Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Float32); !ok {
		t.Fatalf("could not type-assert to array.Float32")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Float32)
	if !ok {
		t.Fatalf("could not type-assert to array.Float32")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestFloat32Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat32Builder(mem)
	defer ab.Release()

	exp := []float32{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewFloat32Array()
	assert.Equal(t, exp, a.Float32Values())

	a.Release()
}

func TestFloat32Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat32Builder(mem)
	defer ab.Release()

	exp := []float32{0, 1, 2, 3}

	ab.AppendValues([]float32{}, nil)
	a := ab.NewFloat32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewFloat32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]float32{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewFloat32Array()
	assert.Equal(t, exp, a.Float32Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]float32{}, nil)
	a = ab.NewFloat32Array()
	assert.Equal(t, exp, a.Float32Values())
	a.Release()
}

func TestFloat32Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewFloat32Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestFloat32BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewFloat32Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, "+Inf", 2, 3, "NaN", "NaN", 4, 5, "-Inf"]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewFloat32Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.False(t, math.IsInf(float64(arr.Value(0)), 0), arr.Value(0))
	assert.True(t, math.IsInf(float64(arr.Value(2)), 1), arr.Value(2))
	assert.True(t, math.IsNaN(float64(arr.Value(5))), arr.Value(5))
}

func TestInt16StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewInt16Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Int16)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewInt16Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Int16)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewInt16Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt16Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewInt16Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewInt16Array()

	// check state of builder after NewInt16Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewInt16Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewInt16Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewInt16Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []int16{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Int16Values(), "unexpected Int16Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Int16Values(), 10, "unexpected length of Int16Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewInt16Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []int16{7, 8}, a.Int16Values())
	assert.Len(t, a.Int16Values(), 2)

	a.Release()

	var (
		want   = []int16{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewInt16Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Int16); !ok {
		t.Fatalf("could not type-assert to array.Int16")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Int16)
	if !ok {
		t.Fatalf("could not type-assert to array.Int16")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestInt16Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt16Builder(mem)
	defer ab.Release()

	exp := []int16{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewInt16Array()
	assert.Equal(t, exp, a.Int16Values())

	a.Release()
}

func TestInt16Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt16Builder(mem)
	defer ab.Release()

	exp := []int16{0, 1, 2, 3}

	ab.AppendValues([]int16{}, nil)
	a := ab.NewInt16Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewInt16Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]int16{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewInt16Array()
	assert.Equal(t, exp, a.Int16Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]int16{}, nil)
	a = ab.NewInt16Array()
	assert.Equal(t, exp, a.Int16Values())
	a.Release()
}

func TestInt16Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt16Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestInt16BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewInt16Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewInt16Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestUint16StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewUint16Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Uint16)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewUint16Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Uint16)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewUint16Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint16Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewUint16Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewUint16Array()

	// check state of builder after NewUint16Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewUint16Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewUint16Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewUint16Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []uint16{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Uint16Values(), "unexpected Uint16Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Uint16Values(), 10, "unexpected length of Uint16Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewUint16Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []uint16{7, 8}, a.Uint16Values())
	assert.Len(t, a.Uint16Values(), 2)

	a.Release()

	var (
		want   = []uint16{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewUint16Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Uint16); !ok {
		t.Fatalf("could not type-assert to array.Uint16")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Uint16)
	if !ok {
		t.Fatalf("could not type-assert to array.Uint16")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestUint16Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint16Builder(mem)
	defer ab.Release()

	exp := []uint16{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewUint16Array()
	assert.Equal(t, exp, a.Uint16Values())

	a.Release()
}

func TestUint16Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint16Builder(mem)
	defer ab.Release()

	exp := []uint16{0, 1, 2, 3}

	ab.AppendValues([]uint16{}, nil)
	a := ab.NewUint16Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewUint16Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]uint16{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewUint16Array()
	assert.Equal(t, exp, a.Uint16Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]uint16{}, nil)
	a = ab.NewUint16Array()
	assert.Equal(t, exp, a.Uint16Values())
	a.Release()
}

func TestUint16Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint16Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestUint16BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewUint16Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewUint16Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestInt8StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewInt8Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Int8)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewInt8Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Int8)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewInt8Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt8Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewInt8Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewInt8Array()

	// check state of builder after NewInt8Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewInt8Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewInt8Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewInt8Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []int8{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Int8Values(), "unexpected Int8Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Int8Values(), 10, "unexpected length of Int8Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewInt8Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []int8{7, 8}, a.Int8Values())
	assert.Len(t, a.Int8Values(), 2)

	a.Release()

	var (
		want   = []int8{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewInt8Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Int8); !ok {
		t.Fatalf("could not type-assert to array.Int8")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Int8)
	if !ok {
		t.Fatalf("could not type-assert to array.Int8")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestInt8Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt8Builder(mem)
	defer ab.Release()

	exp := []int8{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewInt8Array()
	assert.Equal(t, exp, a.Int8Values())

	a.Release()
}

func TestInt8Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt8Builder(mem)
	defer ab.Release()

	exp := []int8{0, 1, 2, 3}

	ab.AppendValues([]int8{}, nil)
	a := ab.NewInt8Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewInt8Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]int8{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewInt8Array()
	assert.Equal(t, exp, a.Int8Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]int8{}, nil)
	a = ab.NewInt8Array()
	assert.Equal(t, exp, a.Int8Values())
	a.Release()
}

func TestInt8Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewInt8Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestInt8BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewInt8Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewInt8Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestUint8StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewUint8Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Uint8)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewUint8Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Uint8)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewUint8Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint8Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewUint8Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewUint8Array()

	// check state of builder after NewUint8Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewUint8Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewUint8Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewUint8Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []uint8{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Uint8Values(), "unexpected Uint8Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Uint8Values(), 10, "unexpected length of Uint8Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewUint8Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []uint8{7, 8}, a.Uint8Values())
	assert.Len(t, a.Uint8Values(), 2)

	a.Release()

	var (
		want   = []uint8{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewUint8Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Uint8); !ok {
		t.Fatalf("could not type-assert to array.Uint8")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Uint8)
	if !ok {
		t.Fatalf("could not type-assert to array.Uint8")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestUint8Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint8Builder(mem)
	defer ab.Release()

	exp := []uint8{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewUint8Array()
	assert.Equal(t, exp, a.Uint8Values())

	a.Release()
}

func TestUint8Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint8Builder(mem)
	defer ab.Release()

	exp := []uint8{0, 1, 2, 3}

	ab.AppendValues([]uint8{}, nil)
	a := ab.NewUint8Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewUint8Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]uint8{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewUint8Array()
	assert.Equal(t, exp, a.Uint8Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]uint8{}, nil)
	a = ab.NewUint8Array()
	assert.Equal(t, exp, a.Uint8Values())
	a.Release()
}

func TestUint8Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewUint8Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestUint8BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewUint8Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewUint8Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestTime32StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dt := &arrow.Time32Type{Unit: arrow.Second}
	b := array.NewTime32Builder(mem, dt)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Time32)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewTime32Builder(mem, dt)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Time32)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewTime32Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time32Type{Unit: arrow.Second}
	ab := array.NewTime32Builder(mem, dtype)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewTime32Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewTime32Array()

	// check state of builder after NewTime32Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewTime32Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewTime32Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewTime32Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []arrow.Time32{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Time32Values(), "unexpected Time32Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Time32Values(), 10, "unexpected length of Time32Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewTime32Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []arrow.Time32{7, 8}, a.Time32Values())
	assert.Len(t, a.Time32Values(), 2)

	a.Release()

	var (
		want   = []arrow.Time32{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewTime32Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Time32); !ok {
		t.Fatalf("could not type-assert to array.Time32")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Time32)
	if !ok {
		t.Fatalf("could not type-assert to array.Time32")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestTime32Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time32Type{Unit: arrow.Second}
	ab := array.NewTime32Builder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Time32{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewTime32Array()
	assert.Equal(t, exp, a.Time32Values())

	a.Release()
}

func TestTime32Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time32Type{Unit: arrow.Second}
	ab := array.NewTime32Builder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Time32{0, 1, 2, 3}

	ab.AppendValues([]arrow.Time32{}, nil)
	a := ab.NewTime32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewTime32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]arrow.Time32{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewTime32Array()
	assert.Equal(t, exp, a.Time32Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]arrow.Time32{}, nil)
	a = ab.NewTime32Array()
	assert.Equal(t, exp, a.Time32Values())
	a.Release()
}

func TestTime32Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time32Type{Unit: arrow.Second}
	ab := array.NewTime32Builder(mem, dtype)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestTime32BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time32Type{Unit: arrow.Second}
	bldr := array.NewTime32Builder(mem, dtype)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewTime32Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestTime64StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dt := &arrow.Time64Type{Unit: arrow.Microsecond}
	b := array.NewTime64Builder(mem, dt)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Time64)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewTime64Builder(mem, dt)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Time64)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewTime64Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time64Type{Unit: arrow.Second}
	ab := array.NewTime64Builder(mem, dtype)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewTime64Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewTime64Array()

	// check state of builder after NewTime64Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewTime64Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewTime64Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewTime64Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []arrow.Time64{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Time64Values(), "unexpected Time64Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Time64Values(), 10, "unexpected length of Time64Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewTime64Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []arrow.Time64{7, 8}, a.Time64Values())
	assert.Len(t, a.Time64Values(), 2)

	a.Release()

	var (
		want   = []arrow.Time64{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewTime64Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Time64); !ok {
		t.Fatalf("could not type-assert to array.Time64")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Time64)
	if !ok {
		t.Fatalf("could not type-assert to array.Time64")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestTime64Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time64Type{Unit: arrow.Second}
	ab := array.NewTime64Builder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Time64{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewTime64Array()
	assert.Equal(t, exp, a.Time64Values())

	a.Release()
}

func TestTime64Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time64Type{Unit: arrow.Second}
	ab := array.NewTime64Builder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Time64{0, 1, 2, 3}

	ab.AppendValues([]arrow.Time64{}, nil)
	a := ab.NewTime64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewTime64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]arrow.Time64{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewTime64Array()
	assert.Equal(t, exp, a.Time64Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]arrow.Time64{}, nil)
	a = ab.NewTime64Array()
	assert.Equal(t, exp, a.Time64Values())
	a.Release()
}

func TestTime64Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time64Type{Unit: arrow.Second}
	ab := array.NewTime64Builder(mem, dtype)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestTime64BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.Time64Type{Unit: arrow.Second}
	bldr := array.NewTime64Builder(mem, dtype)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewTime64Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestDate32StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewDate32Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Date32)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewDate32Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Date32)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewDate32Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate32Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewDate32Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewDate32Array()

	// check state of builder after NewDate32Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewDate32Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewDate32Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewDate32Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []arrow.Date32{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Date32Values(), "unexpected Date32Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Date32Values(), 10, "unexpected length of Date32Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewDate32Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []arrow.Date32{7, 8}, a.Date32Values())
	assert.Len(t, a.Date32Values(), 2)

	a.Release()

	var (
		want   = []arrow.Date32{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewDate32Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Date32); !ok {
		t.Fatalf("could not type-assert to array.Date32")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Date32)
	if !ok {
		t.Fatalf("could not type-assert to array.Date32")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestDate32Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate32Builder(mem)
	defer ab.Release()

	exp := []arrow.Date32{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewDate32Array()
	assert.Equal(t, exp, a.Date32Values())

	a.Release()
}

func TestDate32Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate32Builder(mem)
	defer ab.Release()

	exp := []arrow.Date32{0, 1, 2, 3}

	ab.AppendValues([]arrow.Date32{}, nil)
	a := ab.NewDate32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewDate32Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]arrow.Date32{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewDate32Array()
	assert.Equal(t, exp, a.Date32Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]arrow.Date32{}, nil)
	a = ab.NewDate32Array()
	assert.Equal(t, exp, a.Date32Values())
	a.Release()
}

func TestDate32Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate32Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestDate32BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewDate32Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewDate32Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestDate64StringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	b := array.NewDate64Builder(mem)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Date64)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewDate64Builder(mem)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Date64)
	defer arr1.Release()

	assert.Exactly(t, arr.Len(), arr1.Len())
	for i := 0; i < arr.Len(); i++ {
		assert.Exactly(t, arr.IsValid(i), arr1.IsValid(i))
		assert.Exactly(t, arr.ValueStr(i), arr1.ValueStr(i))
		if arr.IsValid(i) {
			assert.Exactly(t, arr.Value(i).ToTime(), arr1.Value(i).ToTime())
		}
	}
}

func TestNewDate64Builder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate64Builder(mem)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewDate64Array
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewDate64Array()

	// check state of builder after NewDate64Array
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewDate64Array did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewDate64Array did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewDate64Array did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []arrow.Date64{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.Date64Values(), "unexpected Date64Values")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.Date64Values(), 10, "unexpected length of Date64Values")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewDate64Array()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []arrow.Date64{7, 8}, a.Date64Values())
	assert.Len(t, a.Date64Values(), 2)

	a.Release()

	var (
		want   = []arrow.Date64{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewDate64Array()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Date64); !ok {
		t.Fatalf("could not type-assert to array.Date64")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Date64)
	if !ok {
		t.Fatalf("could not type-assert to array.Date64")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestDate64Builder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate64Builder(mem)
	defer ab.Release()

	exp := []arrow.Date64{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewDate64Array()
	assert.Equal(t, exp, a.Date64Values())

	a.Release()
}

func TestDate64Builder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate64Builder(mem)
	defer ab.Release()

	exp := []arrow.Date64{0, 1, 2, 3}

	ab.AppendValues([]arrow.Date64{}, nil)
	a := ab.NewDate64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewDate64Array()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]arrow.Date64{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewDate64Array()
	assert.Equal(t, exp, a.Date64Values())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]arrow.Date64{}, nil)
	a = ab.NewDate64Array()
	assert.Equal(t, exp, a.Date64Values())
	a.Release()
}

func TestDate64Builder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewDate64Builder(mem)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestDate64BuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	bldr := array.NewDate64Builder(mem)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewDate64Array()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}

func TestDurationStringRoundTrip(t *testing.T) {
	// 1. create array
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dt := &arrow.DurationType{Unit: arrow.Second}
	b := array.NewDurationBuilder(mem, dt)
	defer b.Release()

	b.Append(1)
	b.Append(2)
	b.Append(3)
	b.AppendNull()
	b.Append(5)
	b.Append(6)
	b.AppendNull()
	b.Append(8)
	b.Append(9)
	b.Append(10)

	arr := b.NewArray().(*array.Duration)
	defer arr.Release()

	// 2. create array via AppendValueFromString
	b1 := array.NewDurationBuilder(mem, dt)
	defer b1.Release()

	for i := 0; i < arr.Len(); i++ {
		assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i)))
	}

	arr1 := b1.NewArray().(*array.Duration)
	defer arr1.Release()

	assert.True(t, array.Equal(arr, arr1))
}

func TestNewDurationBuilder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.DurationType{Unit: arrow.Second}
	ab := array.NewDurationBuilder(mem, dtype)
	defer ab.Release()

	ab.Retain()
	ab.Release()

	ab.Append(1)
	ab.Append(2)
	ab.Append(3)
	ab.AppendNull()
	ab.Append(5)
	ab.Append(6)
	ab.AppendNull()
	ab.Append(8)
	ab.Append(9)
	ab.Append(10)

	// check state of builder before NewDurationArray
	assert.Equal(t, 10, ab.Len(), "unexpected Len()")
	assert.Equal(t, 2, ab.NullN(), "unexpected NullN()")

	a := ab.NewDurationArray()

	// check state of builder after NewDurationArray
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewDurationArray did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewDurationArray did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewDurationArray did not reset state")

	// check state of array
	assert.Equal(t, 2, a.NullN(), "unexpected null count")
	assert.Equal(t, []arrow.Duration{1, 2, 3, 0, 5, 6, 0, 8, 9, 10}, a.DurationValues(), "unexpected DurationValues")
	assert.Equal(t, []byte{0xb7}, a.NullBitmapBytes()[:1]) // 4 bytes due to minBuilderCapacity
	assert.Len(t, a.DurationValues(), 10, "unexpected length of DurationValues")

	a.Release()

	ab.Append(7)
	ab.Append(8)

	a = ab.NewDurationArray()

	assert.Equal(t, 0, a.NullN())
	assert.Equal(t, []arrow.Duration{7, 8}, a.DurationValues())
	assert.Len(t, a.DurationValues(), 2)

	a.Release()

	var (
		want   = []arrow.Duration{1, 2, 3, 4}
		valids = []bool{true, true, false, true}
	)

	ab.AppendValues(want, valids)
	a = ab.NewDurationArray()

	sub := array.MakeFromData(a.Data())
	defer sub.Release()

	if got, want := sub.DataType().ID(), a.DataType().ID(); got != want {
		t.Fatalf("invalid type: got=%q, want=%q", got, want)
	}

	if _, ok := sub.(*array.Duration); !ok {
		t.Fatalf("could not type-assert to array.Duration")
	}

	if got, want := a.String(), `[1 2 (null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	slice := array.NewSliceData(a.Data(), 2, 4)
	defer slice.Release()

	sub1 := array.MakeFromData(slice)
	defer sub1.Release()

	v, ok := sub1.(*array.Duration)
	if !ok {
		t.Fatalf("could not type-assert to array.Duration")
	}

	if got, want := v.String(), `[(null) 4]`; got != want {
		t.Fatalf("got=%q, want=%q", got, want)
	}

	a.Release()
}

func TestDurationBuilder_AppendValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.DurationType{Unit: arrow.Second}
	ab := array.NewDurationBuilder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Duration{0, 1, 2, 3}
	ab.AppendValues(exp, nil)
	a := ab.NewDurationArray()
	assert.Equal(t, exp, a.DurationValues())

	a.Release()
}

func TestDurationBuilder_Empty(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.DurationType{Unit: arrow.Second}
	ab := array.NewDurationBuilder(mem, dtype)
	defer ab.Release()

	exp := []arrow.Duration{0, 1, 2, 3}

	ab.AppendValues([]arrow.Duration{}, nil)
	a := ab.NewDurationArray()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues(nil, nil)
	a = ab.NewDurationArray()
	assert.Zero(t, a.Len())
	a.Release()

	ab.AppendValues([]arrow.Duration{}, nil)
	ab.AppendValues(exp, nil)
	a = ab.NewDurationArray()
	assert.Equal(t, exp, a.DurationValues())
	a.Release()

	ab.AppendValues(exp, nil)
	ab.AppendValues([]arrow.Duration{}, nil)
	a = ab.NewDurationArray()
	assert.Equal(t, exp, a.DurationValues())
	a.Release()
}

func TestDurationBuilder_Resize(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.DurationType{Unit: arrow.Second}
	ab := array.NewDurationBuilder(mem, dtype)
	defer ab.Release()

	assert.Equal(t, 0, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	ab.Reserve(63)
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 0, ab.Len())

	for i := 0; i < 63; i++ {
		ab.Append(0)
	}
	assert.Equal(t, 64, ab.Cap())
	assert.Equal(t, 63, ab.Len())

	ab.Resize(5)
	assert.Equal(t, 5, ab.Len())

	ab.Resize(32)
	assert.Equal(t, 5, ab.Len())
}

func TestDurationBuilderUnmarshalJSON(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	dtype := &arrow.DurationType{Unit: arrow.Second}
	bldr := array.NewDurationBuilder(mem, dtype)
	defer bldr.Release()

	jsonstr := `[0, 1, null, 2.3, -11]`

	err := bldr.UnmarshalJSON([]byte(jsonstr))
	assert.NoError(t, err)

	arr := bldr.NewDurationArray()
	defer arr.Release()

	assert.NotNil(t, arr)

	assert.Equal(t, int64(0), int64(arr.Value(0)))
	assert.Equal(t, int64(1), int64(arr.Value(1)))
	assert.True(t, arr.IsNull(2))
	assert.Equal(t, int64(2), int64(arr.Value(3)))
	assert.Equal(t, int64(5), int64(arr.Len()))
}
