ent / ent/ent

Upsert using a custom GoType for ID results in error

Open
#3,868 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
17.2k
Forks
1k
PR merge metrics
No merged PRs in 30d

Description

When utilizing the `sql/upsert` flag, custom gotypes do not appear to be handled when scanning in the `RETURNING "id"` response. Rather than returning no error, as expected, Exec or ID both return `unexpected Identifier.ID type: string`

- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/ent/ent/issues) of this repository and believe that this is not a duplicate.

Closed issue #1985 has a post-close comment with another user facing a similar problem.

## Current Behavior 😯

I am using prefixed KSUIDs as a custom goType for my ID fields:
```go
func (m Mixin) Fields() []ent.Field {
return []ent.Field{
field.String("id").
GoType(ID("")).
DefaultFunc(func() ID { return MustNew(m.prefix) }),
}
}
```
(Implemented very similarly to the [`todopulid`](https://github.com/ent/contrib/tree/master/entgql/internal/todopulid) example. I can provide my code if needed.

When attempting to upsert an object with this type, like so:
```go
err := client.Identifier.Create().
SetType(i.Type).
SetValue(i.Val).
SetBookID(book.ID).
SetCalibreID(i.ID).
OnConflictColumns(identifier.FieldCalibreID).
Ignore().
Exec(ctx)
```

The following query is generated:
```
2023/12/26 00:18:35 driver.Query: query=INSERT INTO "identifiers" ("calibre_id", "type", "value", "identifier_book", "id") VALUES ($1, $2, $3, $4, $5) ON CONFLICT ("calibre_id") DO UPDATE SET "calibre_id" = "identifiers"."calibre_id", "type" = "identifiers"."type", "value" = "identifiers"."value", "identifier_book" = "identifiers"."identifier_book", "id" = "identifiers"."id" RETURNING "id" args=[15 goodreads 20551785 bok_2a4XEmwDKYCB0GyRJcoGTuLcVoe idn_2a4XEmgSmmS687VEPmELtk7l5ee]
```
which results in the following error:
```
12:18AM WRN Failed to create identifiers error="unexpected Identifier.ID type: string" book="Caliban's War" bookID=109
```

It appears that although my custom Scanner is used just fine when not doing an upsert, the id from `RETURNING "id"` clause is still being treated like a string (the db's type), insead of a `ksuid.ID` (the GoType).

## Expected Behavior 🤔

This shouldn't error -- the ID is properly scanned in when inserted via other means.

## Steps to Reproduce 🕹

code above should be sufficient

## Your Environment 🌎

| Tech | Version |
| ----------- | ------- |
| Go | 1.21.4 |
| Ent | 1.12.5 |
| Database | PostgreSQL |
| Driver | github.com/jackc/pgx/v5/stdlib |

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.