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

Issue:
columnPages.SeekToRow not work
version v0.20.1

```go
package main

import (
	"bytes"
	"fmt"

	"github.com/parquet-go/parquet-go"
)

func main() {
	data := buildFile()

	var err error

	pr, err := parquet.OpenFile(bytes.NewReader(data.Bytes()), int64(data.Len()))
	if err != nil {
		panic(err)
	}

	id := pr.Root().Column("id")
	{
		pages := id.Pages()
		page, err := pages.ReadPage()
		if err != nil {
			panic(err)
		}
		fmt.Println(page.NumRows()) // 3
		pages.Close()
	}

	{
		pages := id.Pages()

		err = pages.SeekToRow(0) // I think the behavior is incorrect, right?
		if err != nil {
			panic(err)
		}

		_, err := pages.ReadPage()
		fmt.Println(err) // EOF 
	}
}

type Contact struct {
	ID   int64  `parquet:"id"`
	Name string `parquet:"name"`
	Sex  bool   `parquet:"sex"`
}

func buildFile() *bytes.Buffer {
	buf := bytes.Buffer{}
	writer := parquet.NewWriter(&buf)
	data := [][]Contact{
		{
			{ID: 1, Name: "user1"},
			{ID: 2, Name: "user2"},
			{ID: 7, Name: "user7"},
		},
		{
			{ID: 8, Name: "user8"},
			{ID: 10, Name: "user10"},
			{ID: 12, Name: "user12"},
		},
		{
			{ID: 15, Name: "user15"},
			{ID: 16, Name: "user16"},
		},
	}
	for _, rows := range data {
		for _, row := range rows {
			err := writer.Write(&row)
			if err != nil {
				panic(err)
			}
		}
		err := writer.Flush()
		if err != nil {
			panic(err)
		}
	}
	err := writer.Close()
	if err != nil {
		panic(err)
	}
	return &buf
}

```

Pull request:
Fix columnPages SeekToRow
fix #119

Patch:
diff --git a/column.go b/column.go
index b0efc7a..776a9db 100644
--- a/column.go
+++ b/column.go
@@ -130,7 +130,7 @@ func (c *columnPages) ReadPage() (Page, error) {
 func (c *columnPages) SeekToRow(rowIndex int64) error {
 	c.index = 0
 
-	for c.index < len(c.pages) && c.pages[c.index].chunk.rowGroup.NumRows >= rowIndex {
+	for c.index < len(c.pages) && c.pages[c.index].chunk.rowGroup.NumRows < rowIndex {
 		rowIndex -= c.pages[c.index].chunk.rowGroup.NumRows
 		c.index++
 	}
@@ -139,8 +139,8 @@ func (c *columnPages) SeekToRow(rowIndex int64) error {
 		if err := c.pages[c.index].SeekToRow(rowIndex); err != nil {
 			return err
 		}
-		for i := range c.pages[c.index:] {
-			p := &c.pages[c.index+i]
+		for i := c.index + 1; i < len(c.pages); i++ {
+			p := &c.pages[i]
 			if err := p.SeekToRow(0); err != nil {
 				return err
 			}


Test patch:
diff --git a/column_test.go b/column_test.go
index e32ca4a..2909bc3 100644
--- a/column_test.go
+++ b/column_test.go
@@ -1,6 +1,7 @@
 package parquet_test
 
 import (
+	"bytes"
 	"fmt"
 	"math/rand"
 	"testing"
@@ -526,3 +527,82 @@ func valueOrder(columnType parquet.Type, values []parquet.Value) indexOrder {
 
 	return ascendingIndexOrder
 }
+
+func TestColumnPages_SeekToRow(t *testing.T) {
+	type Contact struct {
+		ID   int64  `parquet:"id"`
+		Name string `parquet:"name"`
+		Sex  bool   `parquet:"sex"`
+	}
+
+	buf := bytes.Buffer{}
+	writer := parquet.NewWriter(&buf)
+	data := [][]Contact{
+		{
+			{ID: 1, Name: "user1"},
+			{ID: 2, Name: "user2"},
+			{ID: 7, Name: "user7"},
+		},
+		{
+			{ID: 8, Name: "user8"},
+			{ID: 10, Name: "user10"},
+			{ID: 12, Name: "user12"},
+		},
+		{
+			{ID: 15, Name: "user15"},
+			{ID: 16, Name: "user16"},
+		},
+	}
+	for _, rows := range data {
+		for _, row := range rows {
+			err := writer.Write(&row)
+			if err != nil {
+				panic(err)
+			}
+		}
+		err := writer.Flush()
+		if err != nil {
+			panic(err)
+		}
+	}
+	err := writer.Close()
+	if err != nil {
+		panic(err)
+	}
+
+	pr, err := parquet.OpenFile(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+	if err != nil {
+		t.Error(err)
+	}
+
+	id := pr.Root().Column("id")
+
+	pages := id.Pages()
+	defer pages.Close()
+
+	var idx int64
+	for _, rows := range data {
+		for _, row := range rows {
+			err := pages.SeekToRow(idx)
+			if err != nil {
+				t.Error(err)
+			}
+
+			page, err := pages.ReadPage()
+			if err != nil {
+				t.Error(err)
+			}
+
+			var values [1]int64
+			page.Values().(interface {
+				ReadInt64s(values []int64) (n int, err error)
+			}).ReadInt64s(values[:])
+
+			if values[0] != row.ID {
+				t.Errorf("read value of page mismatch, row index %d: got=%d want=%d", idx, values[0], row.ID)
+			}
+
+			idx++
+		}
+	}
+}