You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2022/11/15 08:51:08 UTC

[arrow] 12/27: ARROW-18274: [Go] StructBuilder premature release fields (#14604)

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 <zo...@gmail.com>
AuthorDate: Tue Nov 8 09:40:11 2022 -0500

    ARROW-18274: [Go] StructBuilder premature release fields (#14604)
    
    Authored-by: Matt Topol <zo...@gmail.com>
    Signed-off-by: Matt Topol <zo...@gmail.com>
---
 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())
+}