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 0ad2d1db fix(arrow): avoid retains on invalid chunk construction 
(#1078)
0ad2d1db is described below

commit 0ad2d1db696dbb1fef7b1c477c2db5d5e12bb2d7
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 20:15:30 2026 +0200

    fix(arrow): avoid retains on invalid chunk construction (#1078)
    
    ### Rationale for this change
    
    NewChunked validated and retained inputs in the same loop. If an early
    chunk matched the requested datatype but a later chunk did not, the
    function panicked after retaining the earlier chunk. Callers that
    recovered and released their own references could not free its buffers.
    
    ### What changes are included in this PR?
    
    Validate every non-nil chunk datatype before retaining any input.
    Invalid construction now leaves all caller-owned reference counts
    unchanged. Successful construction, nil-chunk handling, and the existing
    panic value are unchanged.
    
    ### Are these changes tested?
    
    Yes. The existing invalid-chunk test now places a valid chunk before the
    mismatched chunk. Its checked allocator therefore verifies rollback in
    addition to the existing exact ErrInvalid assertion.
    
    - go test ./arrow/array
    - go test -race ./arrow/array -run '^TestChunkedInvalid$' -count=1
    
    ### Are there any user-facing changes?
    
    No API changes. Recovering from invalid chunk construction no longer
    leaves earlier inputs retained.
---
 arrow/array/table_test.go | 4 +++-
 arrow/table.go            | 9 ++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arrow/array/table_test.go b/arrow/array/table_test.go
index 08fea1a8..4720f606 100644
--- a/arrow/array/table_test.go
+++ b/arrow/array/table_test.go
@@ -203,8 +203,10 @@ func TestChunkedInvalid(t *testing.T) {
                }
        }()
 
+       // Keep a valid chunk before the mismatch so failed construction must 
not
+       // leave an extra reference to it.
        c1 := arrow.NewChunked(arrow.PrimitiveTypes.Int32, []arrow.Array{
-               f1, f2,
+               f2, f1,
        })
        defer c1.Release()
 }
diff --git a/arrow/table.go b/arrow/table.go
index bdbf85bf..4f873350 100644
--- a/arrow/table.go
+++ b/arrow/table.go
@@ -146,6 +146,12 @@ type Chunked struct {
 //
 // NewChunked panics if the chunks do not have the same data type.
 func NewChunked(dtype DataType, chunks []Array) *Chunked {
+       for _, chunk := range chunks {
+               if chunk != nil && !TypeEqual(chunk.DataType(), dtype) {
+                       panic(fmt.Errorf("%w: arrow/array: mismatch data type 
%s vs %s", ErrInvalid, chunk.DataType().String(), dtype.String()))
+               }
+       }
+
        arr := &Chunked{
                chunks: make([]Array, 0, len(chunks)),
                dtype:  dtype,
@@ -157,9 +163,6 @@ func NewChunked(dtype DataType, chunks []Array) *Chunked {
                        continue
                }
 
-               if !TypeEqual(chunk.DataType(), dtype) {
-                       panic(fmt.Errorf("%w: arrow/array: mismatch data type 
%s vs %s", ErrInvalid, chunk.DataType().String(), dtype.String()))
-               }
                chunk.Retain()
                arr.chunks = append(arr.chunks, chunk)
                arr.length += chunk.Len()

Reply via email to