]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/go/arrow/cdata/cdata_test.go
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / go / arrow / cdata / cdata_test.go
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 // +build cgo
18 // +build test
19
20 // use test tag so that we only run these tests when the "test" tag is present
21 // so that the .c and other framework infrastructure is only compiled in during
22 // testing, and the .c files and symbols are not present in release builds.
23
24 package cdata
25
26 import (
27 "io"
28 "runtime"
29 "testing"
30 "time"
31 "unsafe"
32
33 "github.com/apache/arrow/go/v6/arrow"
34 "github.com/apache/arrow/go/v6/arrow/array"
35 "github.com/apache/arrow/go/v6/arrow/decimal128"
36 "github.com/apache/arrow/go/v6/arrow/memory"
37 "github.com/stretchr/testify/assert"
38 )
39
40 func TestSchemaExport(t *testing.T) {
41 sc := exportInt32TypeSchema()
42 f, err := importSchema(&sc)
43 assert.NoError(t, err)
44
45 keys, _ := getMetadataKeys()
46 vals, _ := getMetadataValues()
47
48 assert.Equal(t, arrow.PrimitiveTypes.Int32, f.Type)
49 assert.Equal(t, keys, f.Metadata.Keys())
50 assert.Equal(t, vals, f.Metadata.Values())
51
52 // schema was released when importing
53 assert.True(t, schemaIsReleased(&sc))
54 }
55
56 func TestSimpleArrayExport(t *testing.T) {
57 assert.False(t, test1IsReleased())
58
59 testarr := exportInt32Array()
60 arr, err := ImportCArrayWithType(testarr, arrow.PrimitiveTypes.Int32)
61 assert.NoError(t, err)
62
63 assert.False(t, test1IsReleased())
64 assert.True(t, isReleased(testarr))
65
66 arr.Release()
67 runtime.GC()
68 assert.Eventually(t, test1IsReleased, 1*time.Second, 10*time.Millisecond)
69 }
70
71 func TestSimpleArrayAndSchema(t *testing.T) {
72 sc := exportInt32TypeSchema()
73 testarr := exportInt32Array()
74
75 // grab address of the buffer we stuck into the ArrowArray object
76 buflist := (*[2]unsafe.Pointer)(unsafe.Pointer(testarr.buffers))
77 origvals := (*[10]int32)(unsafe.Pointer(buflist[1]))
78
79 fld, arr, err := ImportCArray(testarr, &sc)
80 assert.NoError(t, err)
81 assert.Equal(t, arrow.PrimitiveTypes.Int32, fld.Type)
82 assert.EqualValues(t, 10, arr.Len())
83
84 // verify that the address is the same of the first integer for the
85 // slice that is being used by the array.Interface and the original buffer
86 vals := arr.(*array.Int32).Int32Values()
87 assert.Same(t, &vals[0], &origvals[0])
88
89 // and that the values are correct
90 for i, v := range vals {
91 assert.Equal(t, int32(i+1), v)
92 }
93 }
94
95 func TestPrimitiveSchemas(t *testing.T) {
96 tests := []struct {
97 typ arrow.DataType
98 fmt string
99 }{
100 {arrow.PrimitiveTypes.Int8, "c"},
101 {arrow.PrimitiveTypes.Int16, "s"},
102 {arrow.PrimitiveTypes.Int32, "i"},
103 {arrow.PrimitiveTypes.Int64, "l"},
104 {arrow.PrimitiveTypes.Uint8, "C"},
105 {arrow.PrimitiveTypes.Uint16, "S"},
106 {arrow.PrimitiveTypes.Uint32, "I"},
107 {arrow.PrimitiveTypes.Uint64, "L"},
108 {arrow.FixedWidthTypes.Boolean, "b"},
109 {arrow.Null, "n"},
110 {arrow.FixedWidthTypes.Float16, "e"},
111 {arrow.PrimitiveTypes.Float32, "f"},
112 {arrow.PrimitiveTypes.Float64, "g"},
113 {&arrow.FixedSizeBinaryType{ByteWidth: 3}, "w:3"},
114 {arrow.BinaryTypes.Binary, "z"},
115 {arrow.BinaryTypes.String, "u"},
116 {&arrow.Decimal128Type{Precision: 16, Scale: 4}, "d:16,4"},
117 {&arrow.Decimal128Type{Precision: 15, Scale: 0}, "d:15,0"},
118 {&arrow.Decimal128Type{Precision: 15, Scale: -4}, "d:15,-4"},
119 }
120
121 for _, tt := range tests {
122 t.Run(tt.typ.Name(), func(t *testing.T) {
123 sc := testPrimitive(tt.fmt)
124
125 f, err := ImportCArrowField(&sc)
126 assert.NoError(t, err)
127
128 assert.True(t, arrow.TypeEqual(tt.typ, f.Type))
129
130 assert.True(t, schemaIsReleased(&sc))
131 })
132 }
133 }
134
135 func TestImportTemporalSchema(t *testing.T) {
136 tests := []struct {
137 typ arrow.DataType
138 fmt string
139 }{
140 {arrow.FixedWidthTypes.Date32, "tdD"},
141 {arrow.FixedWidthTypes.Date64, "tdm"},
142 {arrow.FixedWidthTypes.Time32s, "tts"},
143 {arrow.FixedWidthTypes.Time32ms, "ttm"},
144 {arrow.FixedWidthTypes.Time64us, "ttu"},
145 {arrow.FixedWidthTypes.Time64ns, "ttn"},
146 {arrow.FixedWidthTypes.Duration_s, "tDs"},
147 {arrow.FixedWidthTypes.Duration_ms, "tDm"},
148 {arrow.FixedWidthTypes.Duration_us, "tDu"},
149 {arrow.FixedWidthTypes.Duration_ns, "tDn"},
150 {arrow.FixedWidthTypes.MonthInterval, "tiM"},
151 {arrow.FixedWidthTypes.DayTimeInterval, "tiD"},
152 {arrow.FixedWidthTypes.MonthDayNanoInterval, "tin"},
153 {arrow.FixedWidthTypes.Timestamp_s, "tss:"},
154 {&arrow.TimestampType{Unit: arrow.Second, TimeZone: "Europe/Paris"}, "tss:Europe/Paris"},
155 {arrow.FixedWidthTypes.Timestamp_ms, "tsm:"},
156 {&arrow.TimestampType{Unit: arrow.Millisecond, TimeZone: "Europe/Paris"}, "tsm:Europe/Paris"},
157 {arrow.FixedWidthTypes.Timestamp_us, "tsu:"},
158 {&arrow.TimestampType{Unit: arrow.Microsecond, TimeZone: "Europe/Paris"}, "tsu:Europe/Paris"},
159 {arrow.FixedWidthTypes.Timestamp_ns, "tsn:"},
160 {&arrow.TimestampType{Unit: arrow.Nanosecond, TimeZone: "Europe/Paris"}, "tsn:Europe/Paris"},
161 }
162
163 for _, tt := range tests {
164 t.Run(tt.typ.Name(), func(t *testing.T) {
165 sc := testPrimitive(tt.fmt)
166
167 f, err := ImportCArrowField(&sc)
168 assert.NoError(t, err)
169
170 assert.True(t, arrow.TypeEqual(tt.typ, f.Type))
171
172 assert.True(t, schemaIsReleased(&sc))
173 })
174 }
175 }
176
177 func TestListSchemas(t *testing.T) {
178 tests := []struct {
179 typ arrow.DataType
180 fmts []string
181 names []string
182 isnull []bool
183 }{
184 {arrow.ListOf(arrow.PrimitiveTypes.Int8), []string{"+l", "c"}, []string{"", "item"}, []bool{true}},
185 {arrow.FixedSizeListOfNonNullable(2, arrow.PrimitiveTypes.Int64), []string{"+w:2", "l"}, []string{"", "item"}, []bool{false}},
186 {arrow.ListOfNonNullable(arrow.ListOf(arrow.PrimitiveTypes.Int32)), []string{"+l", "+l", "i"}, []string{"", "item", "item"}, []bool{false, true}},
187 }
188
189 for _, tt := range tests {
190 t.Run(tt.typ.Name(), func(t *testing.T) {
191 sc := testNested(tt.fmts, tt.names, tt.isnull)
192 defer freeMallocedSchemas(sc)
193
194 top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0]
195 f, err := ImportCArrowField(top)
196 assert.NoError(t, err)
197
198 assert.True(t, arrow.TypeEqual(tt.typ, f.Type))
199
200 assert.True(t, schemaIsReleased(top))
201 })
202 }
203 }
204
205 func TestStructSchemas(t *testing.T) {
206 tests := []struct {
207 typ arrow.DataType
208 fmts []string
209 names []string
210 flags []int64
211 }{
212 {arrow.StructOf(
213 arrow.Field{Name: "a", Type: arrow.PrimitiveTypes.Int8, Nullable: true},
214 arrow.Field{Name: "b", Type: arrow.BinaryTypes.String, Nullable: true, Metadata: metadata2},
215 ), []string{"+s", "c", "u"}, []string{"", "a", "b"}, []int64{flagIsNullable, flagIsNullable, flagIsNullable}},
216 }
217
218 for _, tt := range tests {
219 t.Run(tt.typ.Name(), func(t *testing.T) {
220 sc := testStruct(tt.fmts, tt.names, tt.flags)
221 defer freeMallocedSchemas(sc)
222
223 top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0]
224 f, err := ImportCArrowField(top)
225 assert.NoError(t, err)
226
227 assert.True(t, arrow.TypeEqual(tt.typ, f.Type))
228
229 assert.True(t, schemaIsReleased(top))
230 })
231 }
232 }
233
234 func TestMapSchemas(t *testing.T) {
235 tests := []struct {
236 typ *arrow.MapType
237 keysSorted bool
238 fmts []string
239 names []string
240 flags []int64
241 }{
242 {arrow.MapOf(arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String), false, []string{"+m", "+s", "c", "u"}, []string{"", "entries", "key", "value"}, []int64{flagIsNullable, 0, 0, flagIsNullable}},
243 {arrow.MapOf(arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String), true, []string{"+m", "+s", "c", "u"}, []string{"", "entries", "key", "value"}, []int64{flagIsNullable | flagMapKeysSorted, 0, 0, flagIsNullable}},
244 }
245
246 for _, tt := range tests {
247 t.Run(tt.typ.Name(), func(t *testing.T) {
248 sc := testMap(tt.fmts, tt.names, tt.flags)
249 defer freeMallocedSchemas(sc)
250
251 top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0]
252 f, err := ImportCArrowField(top)
253 assert.NoError(t, err)
254
255 tt.typ.KeysSorted = tt.keysSorted
256 assert.True(t, arrow.TypeEqual(tt.typ, f.Type))
257
258 assert.True(t, schemaIsReleased(top))
259 })
260 }
261 }
262
263 func TestSchema(t *testing.T) {
264 // schema is exported as an equivalent struct type (+ top-level metadata)
265 sc := arrow.NewSchema([]arrow.Field{
266 {Name: "nulls", Type: arrow.Null, Nullable: false},
267 {Name: "values", Type: arrow.PrimitiveTypes.Int64, Nullable: true, Metadata: metadata1},
268 }, &metadata2)
269
270 cst := testSchema([]string{"+s", "n", "l"}, []string{"", "nulls", "values"}, []int64{0, 0, flagIsNullable})
271 defer freeMallocedSchemas(cst)
272
273 top := (*[1]*CArrowSchema)(unsafe.Pointer(cst))[0]
274 out, err := ImportCArrowSchema(top)
275 assert.NoError(t, err)
276
277 assert.True(t, sc.Equal(out))
278 assert.True(t, sc.Metadata().Equal(out.Metadata()))
279
280 assert.True(t, schemaIsReleased(top))
281 }
282
283 func createTestInt8Arr() array.Interface {
284 bld := array.NewInt8Builder(memory.DefaultAllocator)
285 defer bld.Release()
286
287 bld.AppendValues([]int8{1, 2, 0, -3}, []bool{true, true, false, true})
288 return bld.NewInt8Array()
289 }
290
291 func createTestInt16Arr() array.Interface {
292 bld := array.NewInt16Builder(memory.DefaultAllocator)
293 defer bld.Release()
294
295 bld.AppendValues([]int16{1, 2, -3}, []bool{true, true, true})
296 return bld.NewInt16Array()
297 }
298
299 func createTestInt32Arr() array.Interface {
300 bld := array.NewInt32Builder(memory.DefaultAllocator)
301 defer bld.Release()
302
303 bld.AppendValues([]int32{1, 2, 0, -3}, []bool{true, true, false, true})
304 return bld.NewInt32Array()
305 }
306
307 func createTestInt64Arr() array.Interface {
308 bld := array.NewInt64Builder(memory.DefaultAllocator)
309 defer bld.Release()
310
311 bld.AppendValues([]int64{1, 2, -3}, []bool{true, true, true})
312 return bld.NewInt64Array()
313 }
314
315 func createTestUint8Arr() array.Interface {
316 bld := array.NewUint8Builder(memory.DefaultAllocator)
317 defer bld.Release()
318
319 bld.AppendValues([]uint8{1, 2, 0, 3}, []bool{true, true, false, true})
320 return bld.NewUint8Array()
321 }
322
323 func createTestUint16Arr() array.Interface {
324 bld := array.NewUint16Builder(memory.DefaultAllocator)
325 defer bld.Release()
326
327 bld.AppendValues([]uint16{1, 2, 3}, []bool{true, true, true})
328 return bld.NewUint16Array()
329 }
330
331 func createTestUint32Arr() array.Interface {
332 bld := array.NewUint32Builder(memory.DefaultAllocator)
333 defer bld.Release()
334
335 bld.AppendValues([]uint32{1, 2, 0, 3}, []bool{true, true, false, true})
336 return bld.NewUint32Array()
337 }
338
339 func createTestUint64Arr() array.Interface {
340 bld := array.NewUint64Builder(memory.DefaultAllocator)
341 defer bld.Release()
342
343 bld.AppendValues([]uint64{1, 2, 3}, []bool{true, true, true})
344 return bld.NewUint64Array()
345 }
346
347 func createTestBoolArr() array.Interface {
348 bld := array.NewBooleanBuilder(memory.DefaultAllocator)
349 defer bld.Release()
350
351 bld.AppendValues([]bool{true, false, false}, []bool{true, true, false})
352 return bld.NewBooleanArray()
353 }
354
355 func createTestNullArr() array.Interface {
356 return array.NewNull(2)
357 }
358
359 func createTestFloat32Arr() array.Interface {
360 bld := array.NewFloat32Builder(memory.DefaultAllocator)
361 defer bld.Release()
362
363 bld.AppendValues([]float32{1.5, 0}, []bool{true, false})
364 return bld.NewFloat32Array()
365 }
366
367 func createTestFloat64Arr() array.Interface {
368 bld := array.NewFloat64Builder(memory.DefaultAllocator)
369 defer bld.Release()
370
371 bld.AppendValues([]float64{1.5, 0}, []bool{true, false})
372 return bld.NewFloat64Array()
373 }
374
375 func createTestFSBArr() array.Interface {
376 bld := array.NewFixedSizeBinaryBuilder(memory.DefaultAllocator, &arrow.FixedSizeBinaryType{ByteWidth: 3})
377 defer bld.Release()
378
379 bld.AppendValues([][]byte{[]byte("foo"), []byte("bar"), nil}, []bool{true, true, false})
380 return bld.NewFixedSizeBinaryArray()
381 }
382
383 func createTestBinaryArr() array.Interface {
384 bld := array.NewBinaryBuilder(memory.DefaultAllocator, arrow.BinaryTypes.Binary)
385 defer bld.Release()
386
387 bld.AppendValues([][]byte{[]byte("foo"), []byte("bar"), nil}, []bool{true, true, false})
388 return bld.NewBinaryArray()
389 }
390
391 func createTestStrArr() array.Interface {
392 bld := array.NewStringBuilder(memory.DefaultAllocator)
393 defer bld.Release()
394
395 bld.AppendValues([]string{"foo", "bar", ""}, []bool{true, true, false})
396 return bld.NewStringArray()
397 }
398
399 func createTestDecimalArr() array.Interface {
400 bld := array.NewDecimal128Builder(memory.DefaultAllocator, &arrow.Decimal128Type{Precision: 16, Scale: 4})
401 defer bld.Release()
402
403 bld.AppendValues([]decimal128.Num{decimal128.FromU64(12345670), decimal128.FromU64(0)}, []bool{true, false})
404 return bld.NewDecimal128Array()
405 }
406
407 func TestPrimitiveArrs(t *testing.T) {
408 tests := []struct {
409 name string
410 fn func() array.Interface
411 }{
412 {"int8", createTestInt8Arr},
413 {"uint8", createTestUint8Arr},
414 {"int16", createTestInt16Arr},
415 {"uint16", createTestUint16Arr},
416 {"int32", createTestInt32Arr},
417 {"uint32", createTestUint32Arr},
418 {"int64", createTestInt64Arr},
419 {"uint64", createTestUint64Arr},
420 {"bool", createTestBoolArr},
421 {"null", createTestNullArr},
422 {"float32", createTestFloat32Arr},
423 {"float64", createTestFloat64Arr},
424 {"fixed size binary", createTestFSBArr},
425 {"binary", createTestBinaryArr},
426 {"utf8", createTestStrArr},
427 {"decimal128", createTestDecimalArr},
428 }
429
430 for _, tt := range tests {
431 t.Run(tt.name, func(t *testing.T) {
432 arr := tt.fn()
433 defer arr.Release()
434
435 carr := createCArr(arr)
436 defer freeTestArr(carr)
437
438 imported, err := ImportCArrayWithType(carr, arr.DataType())
439 assert.NoError(t, err)
440 assert.True(t, array.ArrayEqual(arr, imported))
441 assert.True(t, isReleased(carr))
442
443 imported.Release()
444 })
445 }
446 }
447
448 func TestPrimitiveSliced(t *testing.T) {
449 arr := createTestInt16Arr()
450 defer arr.Release()
451
452 sl := array.NewSlice(arr, 1, 2)
453 defer sl.Release()
454
455 carr := createCArr(sl)
456 defer freeTestArr(carr)
457
458 imported, err := ImportCArrayWithType(carr, arr.DataType())
459 assert.NoError(t, err)
460 assert.True(t, array.ArrayEqual(sl, imported))
461 assert.True(t, array.ArraySliceEqual(arr, 1, 2, imported, 0, int64(imported.Len())))
462 assert.True(t, isReleased(carr))
463
464 imported.Release()
465 }
466
467 func createTestListArr() array.Interface {
468 bld := array.NewListBuilder(memory.DefaultAllocator, arrow.PrimitiveTypes.Int8)
469 defer bld.Release()
470
471 vb := bld.ValueBuilder().(*array.Int8Builder)
472
473 bld.Append(true)
474 vb.AppendValues([]int8{1, 2}, []bool{true, true})
475
476 bld.Append(true)
477 vb.AppendValues([]int8{3, 0}, []bool{true, false})
478
479 bld.AppendNull()
480
481 return bld.NewArray()
482 }
483
484 func createTestFixedSizeList() array.Interface {
485 bld := array.NewFixedSizeListBuilder(memory.DefaultAllocator, 2, arrow.PrimitiveTypes.Int64)
486 defer bld.Release()
487
488 vb := bld.ValueBuilder().(*array.Int64Builder)
489
490 bld.Append(true)
491 vb.AppendValues([]int64{1, 2}, []bool{true, true})
492
493 bld.Append(true)
494 vb.AppendValues([]int64{3, 0}, []bool{true, false})
495
496 bld.AppendNull()
497 return bld.NewArray()
498 }
499
500 func createTestStructArr() array.Interface {
501 bld := array.NewStructBuilder(memory.DefaultAllocator, arrow.StructOf(
502 arrow.Field{Name: "a", Type: arrow.PrimitiveTypes.Int8, Nullable: true},
503 arrow.Field{Name: "b", Type: arrow.BinaryTypes.String, Nullable: true},
504 ))
505 defer bld.Release()
506
507 f1bld := bld.FieldBuilder(0).(*array.Int8Builder)
508 f2bld := bld.FieldBuilder(1).(*array.StringBuilder)
509
510 bld.Append(true)
511 f1bld.Append(1)
512 f2bld.Append("foo")
513
514 bld.Append(true)
515 f1bld.Append(2)
516 f2bld.AppendNull()
517
518 return bld.NewArray()
519 }
520
521 func createTestMapArr() array.Interface {
522 bld := array.NewMapBuilder(memory.DefaultAllocator, arrow.PrimitiveTypes.Int8, arrow.BinaryTypes.String, false)
523 defer bld.Release()
524
525 kb := bld.KeyBuilder().(*array.Int8Builder)
526 vb := bld.ItemBuilder().(*array.StringBuilder)
527
528 bld.Append(true)
529 kb.Append(1)
530 vb.Append("foo")
531 kb.Append(2)
532 vb.AppendNull()
533
534 bld.Append(true)
535 kb.Append(3)
536 vb.Append("bar")
537
538 return bld.NewArray()
539 }
540
541 func TestNestedArrays(t *testing.T) {
542 tests := []struct {
543 name string
544 fn func() array.Interface
545 }{
546 {"list", createTestListArr},
547 {"fixed size list", createTestFixedSizeList},
548 {"struct", createTestStructArr},
549 {"map", createTestMapArr},
550 }
551
552 for _, tt := range tests {
553 t.Run(tt.name, func(t *testing.T) {
554 arr := tt.fn()
555 defer arr.Release()
556
557 carr := createCArr(arr)
558 defer freeTestArr(carr)
559
560 imported, err := ImportCArrayWithType(carr, arr.DataType())
561 assert.NoError(t, err)
562 assert.True(t, array.ArrayEqual(arr, imported))
563 assert.True(t, isReleased(carr))
564
565 imported.Release()
566 })
567 }
568 }
569
570 func TestRecordBatch(t *testing.T) {
571 arr := createTestStructArr()
572 defer arr.Release()
573
574 carr := createCArr(arr)
575 defer freeTestArr(carr)
576
577 sc := testStruct([]string{"+s", "c", "u"}, []string{"", "a", "b"}, []int64{0, flagIsNullable, flagIsNullable})
578 defer freeMallocedSchemas(sc)
579
580 top := (*[1]*CArrowSchema)(unsafe.Pointer(sc))[0]
581 rb, err := ImportCRecordBatch(carr, top)
582 assert.NoError(t, err)
583 defer rb.Release()
584
585 assert.EqualValues(t, 2, rb.NumCols())
586 rbschema := rb.Schema()
587 assert.Equal(t, "a", rbschema.Field(0).Name)
588 assert.Equal(t, "b", rbschema.Field(1).Name)
589
590 rec := array.NewRecord(rbschema, []array.Interface{arr.(*array.Struct).Field(0), arr.(*array.Struct).Field(1)}, -1)
591 defer rec.Release()
592
593 assert.True(t, array.RecordEqual(rb, rec))
594 }
595
596 func TestRecordReaderStream(t *testing.T) {
597 stream := arrayStreamTest()
598 defer releaseStream(stream)
599
600 rdr := ImportCArrayStream(stream, nil)
601 i := 0
602 for {
603 rec, err := rdr.Read()
604 if err != nil {
605 if err == io.EOF {
606 break
607 }
608 assert.NoError(t, err)
609 }
610 defer rec.Release()
611
612 assert.EqualValues(t, 2, rec.NumCols())
613 assert.Equal(t, "a", rec.ColumnName(0))
614 assert.Equal(t, "b", rec.ColumnName(1))
615 i++
616 for j := 0; j < int(rec.NumRows()); j++ {
617 assert.Equal(t, int32((j+1)*i), rec.Column(0).(*array.Int32).Value(j))
618 }
619 assert.Equal(t, "foo", rec.Column(1).(*array.String).Value(0))
620 assert.Equal(t, "bar", rec.Column(1).(*array.String).Value(1))
621 assert.Equal(t, "baz", rec.Column(1).(*array.String).Value(2))
622 }
623 }