jackc / pgx

PostgreSQL driver and toolkit for Go
MIT License
10.83k stars 845 forks source link

failed to encode into binary format for uuid (OID 2950): cannot find encode plan #2164

Closed tomekit closed 1 week ago

tomekit commented 1 week ago

Hi,

I am scanning field into userId:

var userId pgtype.UUID
err = rows2.Scan(&userId)

I then subsequently user userId in the select query:

var params []interface{}
params = append(params, userId)
query := fmt.Sprintf("select id from table t where user_id = $1")
_, err = tx.Exec(ctx, query, params)

This results in err:

failed to encode args[0]: unable to encode []interface {}{pgtype.UUID{Bytes:[16]uint8{0x21, 0x8d, 0xfa, 0x42, 0x77, 0xaf, 0x4d, 0x35, 0xa7, 0x1d, 0x61, 0x46, 0x89, 0xd4, 0x90, 0xe2}, Valid:true}} into binary format for uuid (OID 2950): cannot find encode plan

and I am failing to understand why is that given that DB type is uuid and I am using native pgx type: pgtype.UUID.

It's likely I am not using it correctly given that I am quite new to pgx and Golang.

I am using: github.com/jackc/pgx/v5 v5.7.1

Based on: https://github.com/jackc/pgx/wiki/UUID-Support I've registered UUID type in my config like this:

dbPool, err := pgxpool.ParseConfig(cfg.Database.Uri)
dbPool.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
pgxuuid.Register(conn.TypeMap())
return nil
}

Any help appreciated!

tomekit commented 1 week ago

It seems that after I've switched to:

var userId uuid.UUID

...

params := pgx.NamedArgs{
    "user_id": userId,
}

it works fine even without the AfterConnect register.

Not that I exactly understand why is that, but it seems my problem is now resolved.

jackc commented 1 week ago

Glad you got it working. For what it's worth, the problem with your original example is your were trying to encode a slice of UUID not a single UUID into the PostgreSQL UUID. You would need to use the ... operator in your call to Exec to expand params.