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 935f644c fix(arrow/util): release protobuf record builders (#1084)
935f644c is described below

commit 935f644c26155eab8edd530a94c374349cc85111
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 20:42:48 2026 +0200

    fix(arrow/util): release protobuf record builders (#1084)
    
    ## What changed
    
    Construct protobuf records through `RecordBuilder.NewRecordBatch` and
    release the builder after ownership transfers to the returned record.
    Record test helpers now release returned batches as well.
    
    ## Why
    
    The manual conversion retained the record builder, each temporary field
    array, and the intermediate struct array. Releasing the returned record
    did not release those extra references.
    
    ## Testing
    
    - `go test ./arrow/util`
    - Added checked-allocator coverage for the complete record lifecycle
---
 arrow/util/protobuf_reflect.go      | 16 +++++-----------
 arrow/util/protobuf_reflect_test.go | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/arrow/util/protobuf_reflect.go b/arrow/util/protobuf_reflect.go
index 17fa9344..b5ba78ed 100644
--- a/arrow/util/protobuf_reflect.go
+++ b/arrow/util/protobuf_reflect.go
@@ -659,24 +659,18 @@ func (msg ProtobufMessageReflection) Record(mem 
memory.Allocator) arrow.RecordBa
        }
 
        schema := msg.Schema()
+       if schema.NumFields() == 0 {
+               return array.NewRecordBatch(schema, nil, 1)
+       }
 
        recordBuilder := array.NewRecordBuilder(mem, schema)
+       defer recordBuilder.Release()
 
-       var fieldNames []string
        for i, f := range msg.fields {
                f.AppendValueOrNull(recordBuilder.Field(i), mem)
-               fieldNames = append(fieldNames, f.name())
-       }
-
-       var arrays []arrow.Array
-       for _, bldr := range recordBuilder.Fields() {
-               a := bldr.NewArray()
-               arrays = append(arrays, a)
        }
 
-       structArray, _ := array.NewStructArray(arrays, fieldNames)
-
-       return array.RecordFromStructArray(structArray, schema)
+       return recordBuilder.NewRecordBatch()
 }
 
 // NewProtobufMessageReflection initialises a ProtobufMessageReflection
diff --git a/arrow/util/protobuf_reflect_test.go 
b/arrow/util/protobuf_reflect_test.go
index 70a0e390..c4a085a4 100644
--- a/arrow/util/protobuf_reflect_test.go
+++ b/arrow/util/protobuf_reflect_test.go
@@ -228,6 +228,7 @@ func CheckSchema(t *testing.T, pmr 
*ProtobufMessageReflection, want string) {
 
 func CheckRecord(t *testing.T, pmr *ProtobufMessageReflection, jsonStr string) 
{
        rec := pmr.Record(nil)
+       defer rec.Release()
        got, err := json.Marshal(rec)
        assert.NoError(t, err)
        assert.JSONEq(t, jsonStr, string(got), "got: %s\nwant: %s", got, 
jsonStr)
@@ -364,6 +365,14 @@ func TestRecordFromProtobuf(t *testing.T) {
        CheckRecord(t, pmr, jsonStr)
 }
 
+func TestRecordReleasesConstructionBuffers(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
+       pmr := NewProtobufMessageReflection(AllTheTypesNoAnyFixture().msg, 
WithEnumHandler(EnumNumber))
+       rec := pmr.Record(mem)
+       rec.Release()
+       mem.AssertSize(t, 0)
+}
+
 func TestNullRecordFromProtobuf(t *testing.T) {
        pmr := NewProtobufMessageReflection(&util_message.AllTheTypes{})
        CheckRecord(t, pmr, `[{
@@ -486,6 +495,17 @@ func TestExcludedNested(t *testing.T) {
        CheckRecord(t, pmr, jsonStr)
 }
 
+func TestRecordReturnsOneRowForZeroFieldSchema(t *testing.T) {
+       excludeAll := func(*ProtobufFieldReflection) bool { return true }
+       pmr := NewProtobufMessageReflection(&util_message.AllTheTypesNoAny{}, 
WithExclusionPolicy(excludeAll))
+
+       rec := pmr.Record(memory.DefaultAllocator)
+       require.NotNil(t, rec)
+       defer rec.Release()
+       require.EqualValues(t, 1, rec.NumRows())
+       require.EqualValues(t, 0, rec.NumCols())
+}
+
 type testProtobufReflection struct {
        ProtobufFieldReflection
 }

Reply via email to