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 1698ad92 fix(arrow/array): always release JSON reader builder (#1065)
1698ad92 is described below

commit 1698ad92f3eec39f4ea9534b00d00791cd9a74c0
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 19:57:50 2026 +0200

    fix(arrow/array): always release JSON reader builder (#1065)
    
    Release the JSON reader's record builder on the final reader Release
    regardless of whether a current record batch exists.
    
    A decode error can leave `cur` nil while the builder still owns buffers
    parsed before the error (e.g. a duplicate-key rejection after the first
    value was appended), so the previous nested release leaked those buffers.
    
    Adds a regression test that parses far enough to allocate builder storage,
    triggers a duplicate-key error before a record batch is produced, and
    asserts with a checked allocator that Release frees the partial state.
---
 arrow/array/json_reader.go                    |  6 +++-
 arrow/array/json_reader_release_error_test.go | 48 +++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/arrow/array/json_reader.go b/arrow/array/json_reader.go
index 6aea688d..86f3383f 100644
--- a/arrow/array/json_reader.go
+++ b/arrow/array/json_reader.go
@@ -146,9 +146,13 @@ func (r *JSONReader) Release() {
        if r.refs.Add(-1) == 0 {
                if r.cur != nil {
                        r.cur.Release()
+                       r.cur = nil
+               }
+               if r.bldr != nil {
                        r.bldr.Release()
-                       r.r = nil
+                       r.bldr = nil
                }
+               r.r = nil
        }
 }
 
diff --git a/arrow/array/json_reader_release_error_test.go 
b/arrow/array/json_reader_release_error_test.go
new file mode 100644
index 00000000..14bc1876
--- /dev/null
+++ b/arrow/array/json_reader_release_error_test.go
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package array_test
+
+import (
+       "strings"
+       "testing"
+
+       "github.com/apache/arrow-go/v18/arrow"
+       "github.com/apache/arrow-go/v18/arrow/array"
+       "github.com/apache/arrow-go/v18/arrow/memory"
+       "github.com/stretchr/testify/require"
+)
+
+func TestJSONReaderReleaseBuilderAfterPartialReadError(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
+       schema := arrow.NewSchema([]arrow.Field{
+               {Name: "value", Type: arrow.PrimitiveTypes.Int64},
+       }, nil)
+
+       // The first value allocates builder buffers. Rejecting the duplicate 
key then
+       // fails before a record batch is created, leaving cur nil while the 
builder
+       // still owns those buffers.
+       rdr := array.NewJSONReader(
+               strings.NewReader(`{"value": 1, "value": 2}`),
+               schema,
+               array.WithAllocator(mem),
+       )
+       require.False(t, rdr.Next())
+       require.Error(t, rdr.Err())
+
+       rdr.Release()
+       mem.AssertSize(t, 0)
+}

Reply via email to