Repository: parquet-go/parquet-go (go)

Issue:
Panic `index out of range` when use `Reset` with multiple row groups
### Minimal test example

```golang
func TestResetWithRowGroups(t *testing.T) {
	type testStruct struct {
		A int `parquet:"a,plain"`
	}

	tests := make([]testStruct, 100)
	for i := range 100 {
		tests[i] = testStruct{A: i + 1}
	}

	b := bytes.NewBuffer(nil)
	w := parquet.NewGenericWriter[testStruct](b, parquet.MaxRowsPerRowGroup(10))
	_, _ = w.Write(tests[0:50])
	_ = w.Close()

	b = bytes.NewBuffer(nil)
	w.Reset(b)
	_, _ = w.Write(tests[50:100])
	_ = w.Close()
}
```

### Expected

No panic

### Actual

```
--- FAIL: TestResetWithRowGroups (0.00s)
panic: runtime error: index out of range [1] with length 1 [recovered]
        panic: runtime error: index out of range [1] with length 1

goroutine 3501 [running]:
testing.tRunner.func1.2({0x1086fc0, 0xc0003e6c00})
        testing/testing.go:1631 +0x3f7
testing.tRunner.func1()
        testing/testing.go:1634 +0x6b6
panic({0x1086fc0?, 0xc0003e6c00?})
        runtime/panic.go:770 +0x132
github.com/parquet-go/parquet-go.(*writer).writeFileFooter(0xc0006fbc80)
        github.com/parquet-go/parquet-go/writer.go:868 +0x1566
github.com/parquet-go/parquet-go.(*writer).close(0xc0006fbc80)
        github.com/parquet-go/parquet-go/writer.go:815 +0x129
github.com/parquet-go/parquet-go.(*Writer).Close(...)
        github.com/parquet-go/parquet-go/writer.go:364
github.com/parquet-go/parquet-go.(*GenericWriter[...]).Close(0x125b380)
        github.com/parquet-go/parquet-go/writer.go:178 +0x11d
github.com/parquet-go/parquet-go_test.TestResetWithRowGroups(0xc000168680?)
        github.com/parquet-go/parquet-go/writer_test.go:1650 +0x2bd
testing.tRunner(0xc000168680, 0x11155c8)
        testing/testing.go:1689 +0x21f
created by testing.(*T).Run in goroutine 1
        testing/testing.go:1742 +0x826
FAIL    github.com/parquet-go/parquet-go        96.351s
```

Pull request description:
Fix #275 (panic after writer reset with multiple row groups)
Seems bug was introduced in #218.

Patch:
diff --git a/writer.go b/writer.go
index 9ce92de..ae9ea89 100644
--- a/writer.go
+++ b/writer.go
@@ -861,7 +861,6 @@ func (w *writer) writeFileFooter() error {
 	protocol := new(thrift.CompactProtocol)
 	encoder := thrift.NewEncoder(protocol.NewWriter(&w.writer))
 
-	w.columnIndex = w.columnIndex[:0]
 	for i, columnIndexes := range w.columnIndexes {
 		rowGroup := &w.rowGroups[i]
 		for j := range columnIndexes {
@@ -872,10 +871,8 @@ func (w *writer) writeFileFooter() error {
 			}
 			column.ColumnIndexLength = int32(w.writer.offset - column.ColumnIndexOffset)
 		}
-		w.columnIndex = append(w.columnIndex, columnIndexes...)
 	}
 
-	w.offsetIndex = w.offsetIndex[:0]
 	for i, offsetIndexes := range w.offsetIndexes {
 		rowGroup := &w.rowGroups[i]
 		for j := range offsetIndexes {
@@ -886,7 +883,6 @@ func (w *writer) writeFileFooter() error {
 			}
 			column.OffsetIndexLength = int32(w.writer.offset - column.OffsetIndexOffset)
 		}
-		w.offsetIndex = append(w.offsetIndex, offsetIndexes...)
 	}
 
 	numRows := int64(0)


Test patch:
diff --git a/writer_test.go b/writer_test.go
index 9ada676..bb7f775 100644
--- a/writer_test.go
+++ b/writer_test.go
@@ -1840,3 +1840,41 @@ func TestMapKeySorting(t *testing.T) {
 		})
 	}
 }
+
+func TestIssue275(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Fatal("require no panic")
+		}
+	}()
+
+	type testStruct struct {
+		A int `parquet:"value,plain"`
+	}
+
+	tests := make([]testStruct, 100)
+	for i := range 100 {
+		tests[i] = testStruct{A: i + 1}
+	}
+
+	b := bytes.NewBuffer(nil)
+	w := parquet.NewGenericWriter[testStruct](b, parquet.MaxRowsPerRowGroup(10))
+
+	if _, err := w.Write(tests[0:50]); err != nil {
+		t.Fatal(err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// test panic after reset writer
+	b = bytes.NewBuffer(nil)
+	w.Reset(b)
+
+	if _, err := w.Write(tests[50:100]); err != nil {
+		t.Fatal(err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+}