uptrace / bun

SQL-first Golang ORM
https://bun.uptrace.dev
BSD 2-Clause "Simplified" License
3.64k stars 220 forks source link

regression: models with nested embedded structs not handled properly #1004

Open oncilla opened 3 months ago

oncilla commented 3 months ago

Hi there,

First of all, thanks for this awesome project :tada:

I have noticed some regression. But it might also be me holding it wrong, thus, feel free to close this issue as "won't fix"

I have tried to update our v1.2.1 in our project. However, there seems to be some regression in how bun deals with nested structs that have embeddings.

We have a core.UUID type that embeds uuid.UUID to extend it with some additional functionality:

package core

type UUID struct {
    uuid.UUID
}

When running the following query, we receive a bun error:

    var appliances []core.UUID
    err := db.NewSelect().
        Table("domain_to_appliances").
        Column("uuid").
        Join("JOIN appliances ON appliances.id = domain_to_appliances.appliance_id").
        Where("domain_to_appliances.domain_id = ?", d.ID).
        Order("uuid ASC").
        Scan(ctx, &appliances)

(see models below)

This results in:

sql: Scan error on column index 0, name "uuid": bun: UUID does not have column "uuid"

It looks to me like bun now interprets core.UUID differently. Previously as a "primitive type", and now as a "table".

I managed to resolve the issue by using:

var appliances []uuid.UUID

and construct the appropriate type afterwards in a for loop.

If it helps, I can set up a minimal reproducer.


Our bun models look like this:

type RowID struct {
    ID int64 `bun:",pk,autoincrement"`
}

type Appliance struct {
    RowID
    ApplianceFields
    //... Some other fields
}

type ApplianceFields struct {
    bun.BaseModel  `bun:"table:appliances"`
    UUID           core.UUID `bun:"type:uuid,unique"`
    //... Some other fields
}

type Domain struct {
    RowID
    DomainFields
    //... Some other fields
}

type DomainFields struct {
    bun.BaseModel   `bun:"table:domains"`
    UUID            core.UUID     `bun:"type:uuid,unique"`
    // ... Some other fields
}

// DomainToAppliance is a join table for the m-to-n relationship between domains and appliances.
type DomainToAppliance struct {
    DomainID    int64      `bun:",pk"`
    ApplianceID int64      `bun:",pk"`
    Domain      *Domain    `bun:"rel:belongs-to,join:domain_id=id"`
    Appliance   *Appliance `bun:"rel:belongs-to,join:appliance_id=id"`
}
danielchalef commented 2 months ago

We see the same when just using uuid.UUID as the type. Unable to upgrade to 1.2.1. My guess is it's a regression introduced in fix: embedding of scanonly fields ed6ed74d5379ea6badb09cc37709211a51f5792b

arobert93 commented 3 weeks ago

I have the same issue. Downgrading to v1.1.17 seems to fix the issue.