pgx icon indicating copy to clipboard operation
pgx copied to clipboard

RowToStructByName does not abide by `db:"-"` ignore field tag.

Open tamis-laan opened this issue 2 years ago • 4 comments

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

tamis-laan avatar Aug 12 '23 15:08 tamis-laan

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 }]

jackc avatar Aug 12 '23 15:08 jackc

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.

tamis-laan avatar Aug 12 '23 15:08 tamis-laan

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.

Running into the same thing: I'd expect it work for the select * case

urjitbhatia avatar Jul 30 '24 00:07 urjitbhatia

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.

jackc avatar Aug 03 '24 14:08 jackc