blob: 9475a9a8cbca9e632e1785316bef41a11eacb286 [file] [log] [blame]
// 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.
//go:build go1.18
package exprs
import (
"context"
"strings"
"testing"
"github.com/apache/arrow/go/v14/arrow"
"github.com/apache/arrow/go/v14/arrow/array"
"github.com/apache/arrow/go/v14/arrow/compute"
"github.com/apache/arrow/go/v14/arrow/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
boringArrowSchema = arrow.NewSchema([]arrow.Field{
{Name: "bool", Type: arrow.FixedWidthTypes.Boolean, Nullable: true},
{Name: "i8", Type: arrow.PrimitiveTypes.Int8, Nullable: true},
{Name: "i32", Type: arrow.PrimitiveTypes.Int32, Nullable: true},
{Name: "i32_req", Type: arrow.PrimitiveTypes.Int32},
{Name: "u32", Type: arrow.PrimitiveTypes.Uint32, Nullable: true},
{Name: "i64", Type: arrow.PrimitiveTypes.Int64, Nullable: true},
{Name: "f32", Type: arrow.PrimitiveTypes.Float32, Nullable: true},
{Name: "f32_req", Type: arrow.PrimitiveTypes.Float32},
{Name: "f64", Type: arrow.PrimitiveTypes.Float64, Nullable: true},
{Name: "date32", Type: arrow.FixedWidthTypes.Date32, Nullable: true},
{Name: "str", Type: arrow.BinaryTypes.String, Nullable: true},
{Name: "bin", Type: arrow.BinaryTypes.Binary, Nullable: true},
}, nil)
)
func TestMakeExecBatch(t *testing.T) {
mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
defer mem.AssertSize(t, 0)
const numRows = 3
var (
ctx = compute.WithAllocator(context.Background(), mem)
i32, _, _ = array.FromJSON(mem, arrow.PrimitiveTypes.Int32, strings.NewReader(`[1, 2, 3]`))
f32, _, _ = array.FromJSON(mem, arrow.PrimitiveTypes.Float32, strings.NewReader(`[1.5, 2.25, 3.125]`))
empty, _, _ = array.RecordFromJSON(mem, boringArrowSchema, strings.NewReader(`[]`))
)
defer i32.Release()
defer f32.Release()
getField := func(n string) arrow.Field {
f, _ := boringArrowSchema.FieldsByName(n)
return f[0]
}
tests := []struct {
name string
batch arrow.Record
}{
{"empty", empty},
{"subset", array.NewRecord(arrow.NewSchema([]arrow.Field{getField("i32"), getField("f32")}, nil),
[]arrow.Array{i32, f32}, numRows)},
{"flipped subset", array.NewRecord(arrow.NewSchema([]arrow.Field{getField("f32"), getField("i32")}, nil),
[]arrow.Array{f32, i32}, numRows)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer tt.batch.Release()
batch, err := makeExecBatch(ctx, boringArrowSchema, compute.NewDatumWithoutOwning(tt.batch))
require.NoError(t, err)
require.Equal(t, tt.batch.NumRows(), batch.Len)
defer func() {
for _, v := range batch.Values {
v.Release()
}
}()
for i, field := range boringArrowSchema.Fields() {
typ := batch.Values[i].(compute.ArrayLikeDatum).Type()
assert.Truef(t, arrow.TypeEqual(typ, field.Type),
"expected: %s\ngot: %s", field.Type, typ)
idxes := tt.batch.Schema().FieldIndices(field.Name)
if batch.Values[i].Kind() == compute.KindScalar {
assert.False(t, batch.Values[i].(*compute.ScalarDatum).Value.IsValid(),
"null placeholder should be injected")
assert.Len(t, idxes, 0, "should only happen when column isn't found")
} else {
col := tt.batch.Column(idxes[0])
val := batch.Values[i].(*compute.ArrayDatum).MakeArray()
defer val.Release()
assert.Truef(t, array.Equal(col, val), "expected: %s\ngot: %s", col, val)
}
}
})
}
}