RowToStructByName does not abide by `db:"-"` ignore field tag.
Describe the bug
When using RowToStructByName (https://pkg.go.dev/github.com/jackc/pgx/v5#RowToStructByName) and the struct tag db:"-" on a field according to the documentation the field should be ignored. Instead pgx produces the error:
struct doesn't have corresponding row field <field to ignore>
To Reproduce
type MyStruct struct {
Description string `db:"description"`
Secret string `db:"-"`
}
rows, _ := pool.Query(context.Background(), `SELECT * FROM mytable`)
responses, _ := pgx.CollectRows(rows, pgx.RowToStructByName[MyStruct])
Expected behavior I would expect the Secret field to be ignored.
Actual behavior
The secret field is not ignored and instead an error is produced saying:
struct doesn't have corresponding row field secret
Version
-
Go:
$ go version-> go version go1.20.5 linux/amd64 -
PostgreSQL:
$ psql --no-psqlrc --tuples-only -c 'select version()'-> PostgreSQL 15.3 (Debian 15.3-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit -
pgx:
$ grep 'github.com/jackc/pgx/v[0-9]' go.mod-> github.com/jackc/pgx/v5 v5.3.1
Try latest version of pgx. Works for me.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/jackc/pgx/v5"
)
type MyStruct struct {
Description string `db:"description"`
Secret string `db:"-"`
}
func main() {
ctx := context.Background()
conn, err := pgx.Connect(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer conn.Close(ctx)
rows, _ := conn.Query(context.Background(), `SELECT 'foo' as description`)
responses, err := pgx.CollectRows(rows, pgx.RowToStructByName[MyStruct])
if err != nil {
log.Fatal(err)
}
fmt.Println(responses)
}
jack@glados ~/dev/pgx_issues/pgx-1712 ±master⚡ » go run .
[{foo }]
hm... strange, I still have this problem after upgrading:
go: upgraded github.com/jackc/pgx/v5 v5.3.1 => v5.4.3
Does it still work with SELECT *? Here you are explicitly querying only foo.
hm... strange, I still have this problem after upgrading:
go: upgraded github.com/jackc/pgx/v5 v5.3.1 => v5.4.3Does it still work with
SELECT *? Here you are explicitly querying only foo.
Running into the same thing: I'd expect it work for the select * case
I just reread this thread and I think I know what is happening. There is an ambiguity regarding what ignore means. Normally, there must be an exact match between the fields in the struct and the columns in the result set. If there is an extra column in the result set that is not in the struct, then that is an error. Using db:"-" marks the struct field to be ignored. But it does nothing to the result set. So the ignored field is actually causing the error. In essence, the struct doesn't have that field because it is ignored, so there is no place for the result column to go.