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 2d4c3853 fix(arrow/array): bound table reader batches (#1146)
2d4c3853 is described below

commit 2d4c38536a878ce63116b8c352de600f38d8b621
Author: Minh Vu <[email protected]>
AuthorDate: Tue Aug 11 23:11:47 2026 +0200

    fix(arrow/array): bound table reader batches (#1146)
    
    ## What
    
    NewTable permits a column to be longer than the logical table row count.
    TableReader used the absolute row limit when choosing each batch size,
    so a 5-row table could emit a second batch that crossed the logical end.
    This uses the remaining row count.
    
    ## Test
    
    - go test ./arrow/array -run TestTableReaderDoesNotExceedTableRowCount
    -count=1
---
 arrow/array/table.go      |  2 +-
 arrow/array/table_test.go | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arrow/array/table.go b/arrow/array/table.go
index 43848481..9c8f7012 100644
--- a/arrow/array/table.go
+++ b/arrow/array/table.go
@@ -354,7 +354,7 @@ func (tr *TableReader) Next() bool {
        }
 
        // determine the minimum contiguous slice across all columns
-       chunksz := imin64(tr.max, tr.chksz)
+       chunksz := imin64(tr.max-tr.cur, tr.chksz)
        chunks := make([]arrow.Array, len(tr.chunks))
        for i := range chunks {
                j := tr.slots[i]
diff --git a/arrow/array/table_test.go b/arrow/array/table_test.go
index 00f8a3aa..b1da6f3e 100644
--- a/arrow/array/table_test.go
+++ b/arrow/array/table_test.go
@@ -957,6 +957,35 @@ func TestTableReader(t *testing.T) {
        }
 }
 
+func TestTableReaderDoesNotExceedTableRowCount(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
+       defer mem.AssertSize(t, 0)
+
+       field := arrow.Field{Name: "values", Type: arrow.PrimitiveTypes.Int32}
+       builder := array.NewInt32Builder(mem)
+       builder.AppendValues([]int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil)
+       values := builder.NewInt32Array()
+       builder.Release()
+       defer values.Release()
+
+       column := arrow.NewColumnFromArr(field, values)
+       defer column.Release()
+       table := array.NewTable(arrow.NewSchema([]arrow.Field{field}, nil), 
[]arrow.Column{column}, 5)
+       defer table.Release()
+
+       reader := array.NewTableReader(table, 3)
+       defer reader.Release()
+
+       var rows int64
+       for reader.Next() {
+               rows += reader.RecordBatch().NumRows()
+       }
+
+       if got, want := rows, int64(5); got != want {
+               t.Fatalf("invalid number of rows iterated over: got=%d, 
want=%d", got, want)
+       }
+}
+
 func TestTableReaderSkipsEmptyChunks(t *testing.T) {
        mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
        defer mem.AssertSize(t, 0)

Reply via email to