| // 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. |
| |
| // +build cgo |
| // +build test |
| |
| // use test tag so that we only run these tests when the "test" tag is present |
| // so that the .c and other framework infrastructure is only compiled in during |
| // testing, and the .c files and symbols are not present in release builds. |
| |
| package cdata |
| |
| import ( |
| "io" |
| "runtime" |
| "testing" |
| "time" |
| "unsafe" |
| |
| "github.com/apache/arrow/go/v6/arrow" |
| "github.com/apache/arrow/go/v6/arrow/array" |
| "github.com/apache/arrow/go/v6/arrow/decimal128" |
| "github.com/apache/arrow/go/v6/arrow/memory" |
| "github.com/stretchr/testify/assert" |
| ) |
| |
| func TestSchemaExport(t *testing.T) { |
| sc := exportInt32TypeSchema() |
| f, err := importSchema(&sc) |
| assert.NoError(t, err) |
| |
| keys, _ := getMetadataKeys() |
| vals, _ := getMetadataValues() |
| |
| assert.Equal(t, arrow.PrimitiveTypes.Int32, f.Type) |
| assert.Equal(t, keys, f.Metadata.Keys()) |
| assert.Equal(t, vals, f.Metadata.Values()) |
| |
| // schema was released when importing |
| assert.True(t, schemaIsReleased(&sc)) |
| } |
| |
| func TestSimpleArrayExport(t *testing.T) { |
| assert.False(t, test1IsReleased()) |
| |
| testarr := exportInt32Array() |
| arr, err := ImportCArrayWithType(testarr, arrow.PrimitiveTypes.Int32) |
| assert.NoError(t, err) |
| |
| assert.False(t, test1IsReleased()) |
| assert.True(t, isReleased(testarr)) |
| |
| arr.Release() |
| runtime.GC() |
| assert.Eventually(t, test1IsReleased, 1*time.Second, 10*time.Millisecond) |
| } |
| |
| func TestSimpleArrayAndSchema(t *testing.T) { |
| sc := exportInt32TypeSchema() |
| testarr := exportInt32Array() |
| |
| // grab address of the buffer we stuck into the ArrowArray object |
| buflist := (*[2]unsafe.Pointer)(unsafe.Pointer(testarr.buffers)) |
| origvals := (*[10]int32)(unsafe.Pointer(buflist[1])) |
| |
| fld, arr, err := ImportCArray(testarr, &sc) |
| assert.NoError(t, err) |
| assert.Equal(t, arrow.PrimitiveTypes.Int32, fld.Type) |
| assert.EqualValues(t, 10, arr.Len()) |
| |
| // verify that the address is the same of the first integer for the |
| // slice that is being used by the array.Interface and the original buffer |
| vals := arr.(*array.Int32).Int32Values() |
| assert.Same(t, &vals[0], &origvals[0]) |
| |
| // and that the values are correct |
| for i, v := range vals { |
| assert.Equal(t, int32(i+1), v) |
| } |
| } |
| |
| func TestPrimitiveSchemas(t *testing.T) { |
| tests := []struct { |
| typ arrow.DataType |
| fmt string |
| }{ |
| {arrow.PrimitiveTypes.Int8, "c"}, |
| {arrow.PrimitiveTypes.Int16, "s"}, |
| {arrow.PrimitiveTypes.Int32, "i"}, |
| {arrow.PrimitiveTypes.Int64, "l"}, |
| {arrow.PrimitiveTypes.Uint8, "C"}, |
| {arrow.PrimitiveTypes.Uint16, "S"}, |
| {arrow.PrimitiveTypes.Uint32, "I"}, |
| {arrow.PrimitiveTypes.Uint64, "L"}, |
| {arrow.FixedWidthTypes.Boolean, "b"}, |
| {arrow.Null, "n"}, |
| {arrow.FixedWidthTypes.Float16, "e"}, |
| {arrow.PrimitiveTypes.Float32, "f"}, |
| {arrow.PrimitiveTypes.Float64, "g"}, |
| {&arrow.FixedSizeBinaryType{ByteWidth: 3}, "w:3"}, |
| {arrow.BinaryTypes.Binary, "z"}, |
| {arrow.BinaryTypes.String, "u"}, |
| {&arrow.Decimal128Type{Precision: 16, Scale: 4}, "d:16,4"}, |
| {&arrow.Decimal128Type{Precision: 15, Scale: 0}, "d:15,0"}, |
| {&arrow.Decimal128Type{Precision: 15, Scale: -4}, "d:15,-4"}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.typ.Name(), func(t *testing.T) { |
| sc := testPrimitive(tt.fmt) |
| |
| f, err := ImportCArrowField(&sc) |
| assert.NoError(t, err) |
| |
| assert.True(t, arrow.TypeEqual(tt.typ, f.Type)) |
| |
| assert.True(t, schemaIsReleased(&sc)) |
| }) |
| } |
| } |
| |
| func TestImportTemporalSchema(t *testing.T) { |
| tests := []struct { |
| typ arrow.DataType |
| fmt string |
| }{ |
| {arrow.FixedWidthTypes.Date32, "tdD"}, |
| {arrow.FixedWidthTypes.Date64, "tdm"}, |
| {arrow.FixedWidthTypes.Time32s, "tts"}, |
| {arrow.FixedWidthTypes.Time32ms, "ttm"}, |
| {arrow.FixedWidthTypes.Time64us, "ttu"}, |
| {arrow.FixedWidthTypes.Time64ns, "ttn"}, |
| {arrow.FixedWidthTypes.Duration_s, "tDs"}, |
| {arrow.FixedWidthTypes.Duration_ms, "tDm"}, |
| {arrow.FixedWidthTypes.Duration_us, "tDu"}, |
| {arrow.FixedWidthTypes.Duration_ns, "tDn"}, |
| {arrow.FixedWidthTypes.MonthInterval, "tiM"}, |
| {arrow.FixedWidthTypes.DayTimeInterval, "tiD"}, |
| {arrow.FixedWidthTypes.MonthDayNanoInterval, "tin"}, |
| {arrow.FixedWidthTypes.Timestamp_s, "tss:"}, |
| {&arrow.TimestampType{Unit: arrow.Second, TimeZone: "Europe/Paris"}, "tss:Europe/Paris"}, |
| {arrow.FixedWidthTypes.Timestamp_ms, "tsm:"}, |
| {&arrow.TimestampType{Unit: arrow.Millisecond, TimeZone: "Europe/Paris"}, "tsm:Europe/Paris"}, |
| {arrow.FixedWidthTypes.Timestamp_us, "tsu:"}, |
| {&arrow.TimestampType{Unit: arrow.Microsecond, TimeZone: "Europe/Paris"}, "tsu:Europe/Paris"}, |
| {arrow.FixedWidthTypes.Timestamp_ns, "tsn:"}, |
| {&arrow.TimestampType{Unit: arrow.Nanosecond, TimeZone: "Europe/Paris"}, "tsn:Europe/Paris"}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.typ.Name(), func(t *testing.T) { |
| sc := testPrimitive(tt.fmt) |
| |
| f, err := ImportCArrowField(&sc) |
| assert.NoError(t, err) |
| |
| assert.True(t, arrow.TypeEqual(tt.typ, f.Type)) |
| |
| assert.True(t, schemaIsReleased(&sc)) |
| }) |
| } |
| } |
| |
| func TestListSchemas(t *testing.T) { |
| tests := []struct { |
| typ arrow.DataType |
| fmts []string |
| names []string |
| isnull []bool |
| }{ |
| {arrow.ListOf(arrow.PrimitiveTypes.Int8), []string{"+l", "c"}, []string{"", "item"}, []bool{true}}, |
| {arrow.FixedSizeListOfNonNullable(2, arrow.PrimitiveTypes.Int64), []string{"+w:2", "l"}, []string{"", "item"}, []bool{false}}, |
| {arrow.ListOfNonNullable(arrow.ListOf(arrow.PrimitiveTypes.Int32)), []string{"+l", "+l", "i"}, []string{"", "item", "item"}, []bool{false, true}}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.typ.Name(), func(t *testing.T) { |
| sc := testNested(tt.fmts, tt.names, tt.isnull) |
| defer freeMallocedSchemas(sc) |
| |
| top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0] |
| f, err := ImportCArrowField(top) |
| assert.NoError(t, err) |
| |
| assert.True(t, arrow.TypeEqual(tt.typ, f.Type)) |
| |
| assert.True(t, schemaIsReleased(top)) |
| }) |
| } |
| } |
| |
| func TestStructSchemas(t *testing.T) { |
| tests := []struct { |
| typ arrow.DataType |
| fmts []string |
| names []string |
| flags []int64 |
| }{ |
| {arrow.StructOf( |
| arrow.Field{Name: "a", Type: arrow.PrimitiveTypes.Int8, Nullable: true}, |
| arrow.Field{Name: "b", Type: arrow.BinaryTypes.String, Nullable: true, Metadata: metadata2}, |
| ), []string{"+s", "c", "u"}, []string{"", "a", "b"}, []int64{flagIsNullable, flagIsNullable, flagIsNullable}}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.typ.Name(), func(t *testing.T) { |
| sc := testStruct(tt.fmts, tt.names, tt.flags) |
| defer freeMallocedSchemas(sc) |
| |
| top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0] |
| f, err := ImportCArrowField(top) |
| assert.NoError(t, err) |
| |
| assert.True(t, arrow.TypeEqual(tt.typ, f.Type)) |
| |
| assert.True(t, schemaIsReleased(top)) |
| }) |
| } |
| } |
| |
| func TestMapSchemas(t *testing.T) { |
| tests := []struct { |
| typ *arrow.MapType |
| keysSorted bool |
| fmts []string |
| names []string |
| flags []int64 |
| }{ |
| {arrow.MapOf(arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String), false, []string{"+m", "+s", "c", "u"}, []string{"", "entries", "key", "value"}, []int64{flagIsNullable, 0, 0, flagIsNullable}}, |
| {arrow.MapOf(arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String), true, []string{"+m", "+s", "c", "u"}, []string{"", "entries", "key", "value"}, []int64{flagIsNullable | flagMapKeysSorted, 0, 0, flagIsNullable}}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.typ.Name(), func(t *testing.T) { |
| sc := testMap(tt.fmts, tt.names, tt.flags) |
| defer freeMallocedSchemas(sc) |
| |
| top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0] |
| f, err := ImportCArrowField(top) |
| assert.NoError(t, err) |
| |
| tt.typ.KeysSorted = tt.keysSorted |
| assert.True(t, arrow.TypeEqual(tt.typ, f.Type)) |
| |
| assert.True(t, schemaIsReleased(top)) |
| }) |
| } |
| } |
| |
| func TestSchema(t *testing.T) { |
| // schema is exported as an equivalent struct type (+ top-level metadata) |
| sc := arrow.NewSchema([]arrow.Field{ |
| {Name: "nulls", Type: arrow.Null, Nullable: false}, |
| {Name: "values", Type: arrow.PrimitiveTypes.Int64, Nullable: true, Metadata: metadata1}, |
| }, &metadata2) |
| |
| cst := testSchema([]string{"+s", "n", "l"}, []string{"", "nulls", "values"}, []int64{0, 0, flagIsNullable}) |
| defer freeMallocedSchemas(cst) |
| |
| top := (*[1]*CArrowSchema)(unsafe.Pointer(cst))[0] |
| out, err := ImportCArrowSchema(top) |
| assert.NoError(t, err) |
| |
| assert.True(t, sc.Equal(out)) |
| assert.True(t, sc.Metadata().Equal(out.Metadata())) |
| |
| assert.True(t, schemaIsReleased(top)) |
| } |
| |
| func createTestInt8Arr() array.Interface { |
| bld := array.NewInt8Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]int8{1, 2, 0, -3}, []bool{true, true, false, true}) |
| return bld.NewInt8Array() |
| } |
| |
| func createTestInt16Arr() array.Interface { |
| bld := array.NewInt16Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]int16{1, 2, -3}, []bool{true, true, true}) |
| return bld.NewInt16Array() |
| } |
| |
| func createTestInt32Arr() array.Interface { |
| bld := array.NewInt32Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]int32{1, 2, 0, -3}, []bool{true, true, false, true}) |
| return bld.NewInt32Array() |
| } |
| |
| func createTestInt64Arr() array.Interface { |
| bld := array.NewInt64Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]int64{1, 2, -3}, []bool{true, true, true}) |
| return bld.NewInt64Array() |
| } |
| |
| func createTestUint8Arr() array.Interface { |
| bld := array.NewUint8Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]uint8{1, 2, 0, 3}, []bool{true, true, false, true}) |
| return bld.NewUint8Array() |
| } |
| |
| func createTestUint16Arr() array.Interface { |
| bld := array.NewUint16Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]uint16{1, 2, 3}, []bool{true, true, true}) |
| return bld.NewUint16Array() |
| } |
| |
| func createTestUint32Arr() array.Interface { |
| bld := array.NewUint32Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]uint32{1, 2, 0, 3}, []bool{true, true, false, true}) |
| return bld.NewUint32Array() |
| } |
| |
| func createTestUint64Arr() array.Interface { |
| bld := array.NewUint64Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]uint64{1, 2, 3}, []bool{true, true, true}) |
| return bld.NewUint64Array() |
| } |
| |
| func createTestBoolArr() array.Interface { |
| bld := array.NewBooleanBuilder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]bool{true, false, false}, []bool{true, true, false}) |
| return bld.NewBooleanArray() |
| } |
| |
| func createTestNullArr() array.Interface { |
| return array.NewNull(2) |
| } |
| |
| func createTestFloat32Arr() array.Interface { |
| bld := array.NewFloat32Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]float32{1.5, 0}, []bool{true, false}) |
| return bld.NewFloat32Array() |
| } |
| |
| func createTestFloat64Arr() array.Interface { |
| bld := array.NewFloat64Builder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]float64{1.5, 0}, []bool{true, false}) |
| return bld.NewFloat64Array() |
| } |
| |
| func createTestFSBArr() array.Interface { |
| bld := array.NewFixedSizeBinaryBuilder(memory.DefaultAllocator, &arrow.FixedSizeBinaryType{ByteWidth: 3}) |
| defer bld.Release() |
| |
| bld.AppendValues([][]byte{[]byte("foo"), []byte("bar"), nil}, []bool{true, true, false}) |
| return bld.NewFixedSizeBinaryArray() |
| } |
| |
| func createTestBinaryArr() array.Interface { |
| bld := array.NewBinaryBuilder(memory.DefaultAllocator, arrow.BinaryTypes.Binary) |
| defer bld.Release() |
| |
| bld.AppendValues([][]byte{[]byte("foo"), []byte("bar"), nil}, []bool{true, true, false}) |
| return bld.NewBinaryArray() |
| } |
| |
| func createTestStrArr() array.Interface { |
| bld := array.NewStringBuilder(memory.DefaultAllocator) |
| defer bld.Release() |
| |
| bld.AppendValues([]string{"foo", "bar", ""}, []bool{true, true, false}) |
| return bld.NewStringArray() |
| } |
| |
| func createTestDecimalArr() array.Interface { |
| bld := array.NewDecimal128Builder(memory.DefaultAllocator, &arrow.Decimal128Type{Precision: 16, Scale: 4}) |
| defer bld.Release() |
| |
| bld.AppendValues([]decimal128.Num{decimal128.FromU64(12345670), decimal128.FromU64(0)}, []bool{true, false}) |
| return bld.NewDecimal128Array() |
| } |
| |
| func TestPrimitiveArrs(t *testing.T) { |
| tests := []struct { |
| name string |
| fn func() array.Interface |
| }{ |
| {"int8", createTestInt8Arr}, |
| {"uint8", createTestUint8Arr}, |
| {"int16", createTestInt16Arr}, |
| {"uint16", createTestUint16Arr}, |
| {"int32", createTestInt32Arr}, |
| {"uint32", createTestUint32Arr}, |
| {"int64", createTestInt64Arr}, |
| {"uint64", createTestUint64Arr}, |
| {"bool", createTestBoolArr}, |
| {"null", createTestNullArr}, |
| {"float32", createTestFloat32Arr}, |
| {"float64", createTestFloat64Arr}, |
| {"fixed size binary", createTestFSBArr}, |
| {"binary", createTestBinaryArr}, |
| {"utf8", createTestStrArr}, |
| {"decimal128", createTestDecimalArr}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| arr := tt.fn() |
| defer arr.Release() |
| |
| carr := createCArr(arr) |
| defer freeTestArr(carr) |
| |
| imported, err := ImportCArrayWithType(carr, arr.DataType()) |
| assert.NoError(t, err) |
| assert.True(t, array.ArrayEqual(arr, imported)) |
| assert.True(t, isReleased(carr)) |
| |
| imported.Release() |
| }) |
| } |
| } |
| |
| func TestPrimitiveSliced(t *testing.T) { |
| arr := createTestInt16Arr() |
| defer arr.Release() |
| |
| sl := array.NewSlice(arr, 1, 2) |
| defer sl.Release() |
| |
| carr := createCArr(sl) |
| defer freeTestArr(carr) |
| |
| imported, err := ImportCArrayWithType(carr, arr.DataType()) |
| assert.NoError(t, err) |
| assert.True(t, array.ArrayEqual(sl, imported)) |
| assert.True(t, array.ArraySliceEqual(arr, 1, 2, imported, 0, int64(imported.Len()))) |
| assert.True(t, isReleased(carr)) |
| |
| imported.Release() |
| } |
| |
| func createTestListArr() array.Interface { |
| bld := array.NewListBuilder(memory.DefaultAllocator, arrow.PrimitiveTypes.Int8) |
| defer bld.Release() |
| |
| vb := bld.ValueBuilder().(*array.Int8Builder) |
| |
| bld.Append(true) |
| vb.AppendValues([]int8{1, 2}, []bool{true, true}) |
| |
| bld.Append(true) |
| vb.AppendValues([]int8{3, 0}, []bool{true, false}) |
| |
| bld.AppendNull() |
| |
| return bld.NewArray() |
| } |
| |
| func createTestFixedSizeList() array.Interface { |
| bld := array.NewFixedSizeListBuilder(memory.DefaultAllocator, 2, arrow.PrimitiveTypes.Int64) |
| defer bld.Release() |
| |
| vb := bld.ValueBuilder().(*array.Int64Builder) |
| |
| bld.Append(true) |
| vb.AppendValues([]int64{1, 2}, []bool{true, true}) |
| |
| bld.Append(true) |
| vb.AppendValues([]int64{3, 0}, []bool{true, false}) |
| |
| bld.AppendNull() |
| return bld.NewArray() |
| } |
| |
| func createTestStructArr() array.Interface { |
| bld := array.NewStructBuilder(memory.DefaultAllocator, arrow.StructOf( |
| arrow.Field{Name: "a", Type: arrow.PrimitiveTypes.Int8, Nullable: true}, |
| arrow.Field{Name: "b", Type: arrow.BinaryTypes.String, Nullable: true}, |
| )) |
| defer bld.Release() |
| |
| f1bld := bld.FieldBuilder(0).(*array.Int8Builder) |
| f2bld := bld.FieldBuilder(1).(*array.StringBuilder) |
| |
| bld.Append(true) |
| f1bld.Append(1) |
| f2bld.Append("foo") |
| |
| bld.Append(true) |
| f1bld.Append(2) |
| f2bld.AppendNull() |
| |
| return bld.NewArray() |
| } |
| |
| func createTestMapArr() array.Interface { |
| bld := array.NewMapBuilder(memory.DefaultAllocator, arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String, false) |
| defer bld.Release() |
| |
| kb := bld.KeyBuilder().(*array.Int8Builder) |
| vb := bld.ItemBuilder().(*array.StringBuilder) |
| |
| bld.Append(true) |
| kb.Append(1) |
| vb.Append("foo") |
| kb.Append(2) |
| vb.AppendNull() |
| |
| bld.Append(true) |
| kb.Append(3) |
| vb.Append("bar") |
| |
| return bld.NewArray() |
| } |
| |
| func TestNestedArrays(t *testing.T) { |
| tests := []struct { |
| name string |
| fn func() array.Interface |
| }{ |
| {"list", createTestListArr}, |
| {"fixed size list", createTestFixedSizeList}, |
| {"struct", createTestStructArr}, |
| {"map", createTestMapArr}, |
| } |
| |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| arr := tt.fn() |
| defer arr.Release() |
| |
| carr := createCArr(arr) |
| defer freeTestArr(carr) |
| |
| imported, err := ImportCArrayWithType(carr, arr.DataType()) |
| assert.NoError(t, err) |
| assert.True(t, array.ArrayEqual(arr, imported)) |
| assert.True(t, isReleased(carr)) |
| |
| imported.Release() |
| }) |
| } |
| } |
| |
| func TestRecordBatch(t *testing.T) { |
| arr := createTestStructArr() |
| defer arr.Release() |
| |
| carr := createCArr(arr) |
| defer freeTestArr(carr) |
| |
| sc := testStruct([]string{"+s", "c", "u"}, []string{"", "a", "b"}, []int64{0, flagIsNullable, flagIsNullable}) |
| defer freeMallocedSchemas(sc) |
| |
| top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0] |
| rb, err := ImportCRecordBatch(carr, top) |
| assert.NoError(t, err) |
| defer rb.Release() |
| |
| assert.EqualValues(t, 2, rb.NumCols()) |
| rbschema := rb.Schema() |
| assert.Equal(t, "a", rbschema.Field(0).Name) |
| assert.Equal(t, "b", rbschema.Field(1).Name) |
| |
| rec := array.NewRecord(rbschema, []array.Interface{arr.(*array.Struct).Field(0), arr.(*array.Struct).Field(1)}, -1) |
| defer rec.Release() |
| |
| assert.True(t, array.RecordEqual(rb, rec)) |
| } |
| |
| func TestRecordReaderStream(t *testing.T) { |
| stream := arrayStreamTest() |
| defer releaseStream(stream) |
| |
| rdr := ImportCArrayStream(stream, nil) |
| i := 0 |
| for { |
| rec, err := rdr.Read() |
| if err != nil { |
| if err == io.EOF { |
| break |
| } |
| assert.NoError(t, err) |
| } |
| defer rec.Release() |
| |
| assert.EqualValues(t, 2, rec.NumCols()) |
| assert.Equal(t, "a", rec.ColumnName(0)) |
| assert.Equal(t, "b", rec.ColumnName(1)) |
| i++ |
| for j := 0; j < int(rec.NumRows()); j++ { |
| assert.Equal(t, int32((j+1)*i), rec.Column(0).(*array.Int32).Value(j)) |
| } |
| assert.Equal(t, "foo", rec.Column(1).(*array.String).Value(0)) |
| assert.Equal(t, "bar", rec.Column(1).(*array.String).Value(1)) |
| assert.Equal(t, "baz", rec.Column(1).(*array.String).Value(2)) |
| } |
| } |