This is an automated email from the ASF dual-hosted git repository. kou pushed a commit to branch maint-10.0.x in repository https://gitbox.apache.org/repos/asf/arrow.git
commit c3353fad507595e4eb94a7b9f1dc6ed44cbc217c Author: Matt Topol <[email protected]> AuthorDate: Tue Nov 8 09:40:11 2022 -0500 ARROW-18274: [Go] StructBuilder premature release fields (#14604) Authored-by: Matt Topol <[email protected]> Signed-off-by: Matt Topol <[email protected]> --- go/arrow/array/struct.go | 11 ++++--- go/arrow/array/union_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/go/arrow/array/struct.go b/go/arrow/array/struct.go index 213febfa41..4901d26d1d 100644 --- a/go/arrow/array/struct.go +++ b/go/arrow/array/struct.go @@ -90,7 +90,10 @@ func (a *Struct) String() string { if i > 0 { o.WriteString(" ") } - if !bytes.Equal(structBitmap, v.NullBitmapBytes()) { + if arrow.IsUnion(v.DataType().ID()) { + fmt.Fprintf(o, "%v", v) + continue + } else if !bytes.Equal(structBitmap, v.NullBitmapBytes()) { masked := a.newStructFieldWithParentValidityMask(i) fmt.Fprintf(o, "%v", masked) masked.Release() @@ -234,10 +237,10 @@ func (b *StructBuilder) Release() { b.nullBitmap.Release() b.nullBitmap = nil } - } - for _, f := range b.fields { - f.Release() + for _, f := range b.fields { + f.Release() + } } } diff --git a/go/arrow/array/union_test.go b/go/arrow/array/union_test.go index ca6122c0ae..036031892d 100644 --- a/go/arrow/array/union_test.go +++ b/go/arrow/array/union_test.go @@ -17,6 +17,7 @@ package array_test import ( + "fmt" "strings" "testing" @@ -946,7 +947,81 @@ func (s *UnionBuilderSuite) TestSparseUnionStructWithUnion() { s.Truef(arrow.TypeEqual(expectedType, bldr.Type()), "expected: %s, got: %s", expectedType, bldr.Type()) } +func ExampleSparseUnionBuilder() { + dt1 := arrow.SparseUnionOf([]arrow.Field{ + {Name: "c", Type: &arrow.DictionaryType{IndexType: arrow.PrimitiveTypes.Uint16, ValueType: arrow.BinaryTypes.String}}, + }, []arrow.UnionTypeCode{0}) + dt2 := arrow.StructOf(arrow.Field{Name: "a", Type: dt1}) + + pool := memory.DefaultAllocator + bldr := array.NewStructBuilder(pool, dt2) + defer bldr.Release() + + bldrDt1 := bldr.FieldBuilder(0).(*array.SparseUnionBuilder) + binDictBldr := bldrDt1.Child(0).(*array.BinaryDictionaryBuilder) + + bldr.Append(true) + bldrDt1.Append(0) + binDictBldr.AppendString("foo") + + bldr.Append(true) + bldrDt1.Append(0) + binDictBldr.AppendString("bar") + + out := bldr.NewArray().(*array.Struct) + defer out.Release() + + fmt.Println(out) + + // Output: + // {[{c=foo} {c=bar}]} +} + func TestUnions(t *testing.T) { suite.Run(t, new(UnionFactorySuite)) suite.Run(t, new(UnionBuilderSuite)) } + +func TestNestedUnionStructDict(t *testing.T) { + // ARROW-18274 + dt1 := arrow.SparseUnionOf([]arrow.Field{ + {Name: "c", Type: &arrow.DictionaryType{ + IndexType: arrow.PrimitiveTypes.Uint16, + ValueType: arrow.BinaryTypes.String, + Ordered: false, + }}, + }, []arrow.UnionTypeCode{0}) + dt2 := arrow.StructOf( + arrow.Field{Name: "b", Type: dt1}, + ) + dt3 := arrow.SparseUnionOf([]arrow.Field{ + {Name: "a", Type: dt2}, + }, []arrow.UnionTypeCode{0}) + pool := memory.NewGoAllocator() + + builder := array.NewSparseUnionBuilder(pool, dt3) + defer builder.Release() + arr := builder.NewArray() + defer arr.Release() + assert.Equal(t, 0, arr.Len()) +} + +func TestNestedUnionDictUnion(t *testing.T) { + dt1 := arrow.SparseUnionOf([]arrow.Field{ + {Name: "c", Type: &arrow.DictionaryType{ + IndexType: arrow.PrimitiveTypes.Uint16, + ValueType: arrow.BinaryTypes.String, + Ordered: false, + }}, + }, []arrow.UnionTypeCode{0}) + dt2 := arrow.SparseUnionOf([]arrow.Field{ + {Name: "a", Type: dt1}, + }, []arrow.UnionTypeCode{0}) + pool := memory.NewGoAllocator() + + builder := array.NewSparseUnionBuilder(pool, dt2) + defer builder.Release() + arr := builder.NewArray() + defer arr.Release() + assert.Equal(t, 0, arr.Len()) +}
