This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new f1895951 fix(arrow/util): release protobuf enum dictionaries (#1083)
f1895951 is described below
commit f18959517845fbeacfd4d465644458629ee22235
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 20:44:18 2026 +0200
fix(arrow/util): release protobuf enum dictionaries (#1083)
Release the temporary string builder and array used to initialize protobuf
enum dictionaries.
`InsertStringDictValues` copies values from its input, so the temporary
builder and array created in getDictValues remained owned by the conversion
path and leaked after each enum append. Release the builder via defer and
the
returned dictionary-values array after the insert.
Adds checked-allocator coverage for the enum conversion path.
---
arrow/util/protobuf_reflect.go | 5 ++++-
arrow/util/protobuf_reflect_test.go | 18 ++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arrow/util/protobuf_reflect.go b/arrow/util/protobuf_reflect.go
index b5ba78ed..6cd897b1 100644
--- a/arrow/util/protobuf_reflect.go
+++ b/arrow/util/protobuf_reflect.go
@@ -360,6 +360,7 @@ func (pdr protobufDictReflection) getDataType()
arrow.DataType {
func (pdr protobufDictReflection) getDictValues(mem memory.Allocator)
arrow.Array {
enumValues := pdr.descriptor.Enum().Values()
bldr := array.NewStringBuilder(mem)
+ defer bldr.Release()
for i := 0; i < enumValues.Len(); i++ {
bldr.Append(string(enumValues.Get(i).Name()))
}
@@ -811,7 +812,9 @@ func (f ProtobufMessageFieldReflection) AppendValueOrNull(b
array.Builder, mem m
case arrow.DICTIONARY:
pdr := f.asDictionary()
db := b.(*array.BinaryDictionaryBuilder)
- err :=
db.InsertStringDictValues(pdr.getDictValues(mem).(*array.String))
+ dictValues := pdr.getDictValues(mem).(*array.String)
+ err := db.InsertStringDictValues(dictValues)
+ dictValues.Release()
if err != nil {
return err
}
diff --git a/arrow/util/protobuf_reflect_test.go
b/arrow/util/protobuf_reflect_test.go
index c4a085a4..723916e1 100644
--- a/arrow/util/protobuf_reflect_test.go
+++ b/arrow/util/protobuf_reflect_test.go
@@ -528,6 +528,24 @@ func TestAppendValueOrNull(t *testing.T) {
assert.EqualErrorf(t, got, want, "Error is: %v, want: %v", got, want)
}
+func TestAppendEnumReleasesDictionaryValues(t *testing.T) {
+ mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
+ pmr := NewProtobufMessageReflection(AllTheTypesNoAnyFixture().msg)
+ var enumField *ProtobufMessageFieldReflection
+ for i := range pmr.fields {
+ if pmr.fields[i].Type.ID() == arrow.DICTIONARY {
+ enumField = &pmr.fields[i]
+ break
+ }
+ }
+ require.NotNil(t, enumField)
+
+ bldr := array.NewDictionaryBuilder(mem,
enumField.Type.(*arrow.DictionaryType))
+ require.NoError(t, enumField.AppendValueOrNull(bldr, mem))
+ bldr.Release()
+ mem.AssertSize(t, 0)
+}
+
func TestGetMapKeyRejectsUnsupportedType(t *testing.T) {
_, err := getMapKey(reflect.ValueOf(struct{}{}))
require.Error(t, err)