Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic when calling rows.Values() #195

Closed
labi-le opened this issue Mar 27, 2024 · 13 comments · Fixed by #196
Closed

panic when calling rows.Values() #195

labi-le opened this issue Mar 27, 2024 · 13 comments · Fixed by #196
Assignees
Labels
question Further information is requested

Comments

@labi-le
Copy link
Contributor

labi-le commented Mar 27, 2024

return r.rows[r.recNo-1], r.nextErr[r.recNo-1]

panic: runtime error: index out of range [-1]

i noticed that the error doesn't occur when I call rows.Next(), but in this case study I don't need to call this method

func TestObject_ScanRow(t *testing.T) {
	dat := _testPrepareData(1)
	prepared := _map2Rows(dat)

	o := NewObject(scanner.NewDynamic('_', []string{"to", "data"}))
	err := o.ScanRow(prepared)
	if err != nil {
		t.Fatal(err)
	}

	if len(o.Data) < 3 {
		t.Fatal("not equal")
	}
}

// func _map2Rows(data []map[string]string) pgx.Rows

// func _testPrepareData(length int) []map[string]string
@pashagolub
Copy link
Owner

Would you please provide reproducible test case showing the issue, that I can run on my environment?

@pashagolub pashagolub self-assigned this Mar 27, 2024
@pashagolub pashagolub added the question Further information is requested label Mar 27, 2024
@labi-le
Copy link
Contributor Author

labi-le commented Mar 27, 2024

Would you please provide reproducible test case showing the issue, that I can run on my environment?

package object_test

import (
	"github.com/jackc/pgx/v5"
	"github.com/pashagolub/pgxmock/v3"
	"testing"
)

func _map2Rows(data []map[string]string) pgx.Rows {
	var keys = make([]string, 0, len(data[0]))
	for key := range data[0] {
		keys = append(keys, key)
	}

	mock, _ := pgxmock.NewPool()

	rows := mock.NewRows(keys)
	values := make([]interface{}, len(keys))
	for _, row := range data {
		for kl := 0; kl < len(keys); kl++ {
			key := keys[kl]
			values[kl] = row[key]
		}

		rows.AddRow(values...)
		clear(values)
	}

	return rows.Kind()
}

type testObject struct {
	ID int
}

func (o *testObject) ScanRow(rows pgx.Rows) error {
	//rows.Next()
	_, rowErr := rows.Values()
	if rowErr != nil {
		return rowErr
	}

	return nil
}

func TestObjects_ScanRow(t *testing.T) {
	rows := _map2Rows([]map[string]string{
		{
			"id": "1",
		},
		{
			"id": "2",
		},
	})
	o := testObject{}
	err := o.ScanRow(rows)
	if err != nil {
		t.Fatal(err)
	}
}

@pashagolub
Copy link
Owner

I don't see here any testing. What are you trying to achieve?

And by the way, rows.Next() must be called:

// Values returns the decoded row values. As with Scan(), it is an error to
// call Values without first calling Next()
and checking that it returned
// true.
Values() ([]any, error)

@labi-le
Copy link
Contributor Author

labi-le commented Mar 27, 2024

I don't see here any testing. What are you trying to achieve?

And by the way, rows.Next() must be called:

// Values returns the decoded row values. As with Scan(), it is an error to
// call Values without first calling Next()
and checking that it returned
// true.
Values() ([]any, error)

when the database returns only one record and there is a Next() call, the error rows is closed is returned

@pashagolub
Copy link
Owner

when the database returns only one record and there is a Next() call, the error rows is closed is returned

Would you please provide me with the simplest code snippet showing this issue?

Thanks in advance!

@labi-le
Copy link
Contributor Author

labi-le commented Mar 27, 2024

Would you please provide me with the simplest code snippet showing this issue?

the error will occur if I use rows.Next() in the ScanRow method.

package main

import (
	"context"
	"fmt"
	"github.com/jackc/pgx/v5"
	"log"
	"os"
)

func main() {
	config, _ := pgx.ParseConfig("dsn")
	config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol

	conn, err := pgx.ConnectConfig(context.TODO(), config)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to connection to database: %v\n", err)
		os.Exit(1)
	}

	pf := Profile{}
	if testErr := conn.QueryRow(context.Background(), "select 1 as id, 'ivan' as name").Scan(&pf); testErr != nil {
		log.Fatal(testErr)
	}
}

type Profile struct {
}

func (p *Profile) ScanRow(rows pgx.Rows) error {
	//rows.Next()
	values, err := rows.Values()
	if err != nil {
		return err
	}

	_ = values

	return rows.Err()
}

@pashagolub
Copy link
Owner

Would you please check #196?

This should work:

go get -u github.com/pashagolub/pgxmock/v3@195-panic-when-calling-rowsvalues

@labi-le
Copy link
Contributor Author

labi-le commented Apr 4, 2024

Would you please check #196?

there's still panic in the tests
in the previous example, the panic has disappeared

@pashagolub
Copy link
Owner

In which exactly tests? Would you please add code showing the issue

@labi-le
Copy link
Contributor Author

labi-le commented Apr 4, 2024

In which exactly tests? Would you please add code showing the issue

#195 (comment)

@pashagolub
Copy link
Owner

That code must use rows.Next().

Why? Because you are playing with low level structs and interfaces. Thus you are responsible for correct usage.

Now can you, please, provide a code showing a real life problem, meaning when we are really testing database code?

@pashagolub
Copy link
Owner

func TestObjects_ScanRow(t *testing.T) {
	rows := _map2Rows([]map[string]string{
		{
			"id": "1",
		},
		{
			"id": "2",
		},
	})
	o := testObject{}
	rows.Next()
	err := o.ScanRow(rows)
	if err != nil {
		t.Fatal(err)
	}
}

@labi-le
Copy link
Contributor Author

labi-le commented Apr 6, 2024

honestly it's so unimportant, i'll just redo the test. thanks for wasting your time on this mess

@labi-le labi-le closed this as completed Apr 6, 2024
pashagolub added a commit that referenced this issue Apr 8, 2024
)

* [-] add `connRow` struct to handle `QueryRow()` calls, fixes #195
* [*] prettify code
* [-] fix error return value of `rows.Scan` is not checked (errcheck)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants