bun icon indicating copy to clipboard operation
bun copied to clipboard

Libary crashes on resolving nested relations

Open ys3d opened this issue 2 years ago • 4 comments
trafficstars

I defined the following structs:

type Job struct {
	Id           int       `bun:",pk"` // uniq job ID
	Data       []*JobData `bun:"rel:has-many,join:id=job_id"`
}
type JobData struct {
	Id               int64  `bun:",pk,autoincrement"`
	JobId            int    `bun:",unique:unique_data"`
	ConfigGuid string `bun:",unique:unique_data"`
	Config           config.Config `bun:"rel:has-one,join:config_guid=guid"`
	Points     []Point       `bun:"rel:has-many,join:id=data_id"`
}
type Point struct {
	Id     int64 `bun:",pk,autoincrement"`
	DataId int64
	Time   time.Time
}

I tried to pull an element of JobData with:

err =s.db.NewSelect().
	                      Model(&job).
	                      WherePK().
	                      Relation("Data", func(q *bun.SelectQuery) *bun.SelectQuery {
		                      return q.Relation("Config").Relation("Points")
	                      }).
	                      Scan(context.Background())

In case I only try to resolve the relation "Config" everything works fine. The relation "Points" causes the following error. The error is caused with and without additionally requesting the "Config" relation:

panic: reflect: call of reflect.Value.Field on zero Value
goroutine 1 [running]:
reflect.Value.Field({0x0?, 0x0?, 0xc0004a2f28?}, 0x7f47703f9d40?)
        /usr/local/go/src/reflect/value.go:1268 +0xe5
github.com/uptrace/bun/schema.fieldByIndexAlloc({0x0?, 0x0?, 0x4311d6?}, {0xc00002ae70?, 0x4c8966?, 0xde0700?})
        /go/pkg/mod/github.com/uptrace/[email protected]/schema/reflect.go:52 +0x45
github.com/uptrace/bun/schema.(*Field).Value(...)
        /go/pkg/mod/github.com/uptrace/[email protected]/schema/field.go:53
github.com/uptrace/bun.modelKey({0xc0003652e0?, 0x41866d?, 0xe0a4b0?}, {0x0?, 0x0?, 0xc0004a3048?}, {0xc00050c1f0, 0x1, 0x422807?})
        /go/pkg/mod/github.com/uptrace/[email protected]/model_table_has_many.go:146 +0xed
github.com/uptrace/bun.baseValues.func1({0x0?, 0x0?, 0xc000382210?})
        /go/pkg/mod/github.com/uptrace/[email protected]/model_table_has_many.go:137 +0xaa
github.com/uptrace/bun.visitField({0x0?, 0x0?, 0x7f4770e66fb8?}, {0xc0000a9478, 0x0, 0x1}, 0xc0004a31d8)
        /go/pkg/mod/github.com/uptrace/[email protected]/util.go:38 +0xf2
github.com/uptrace/bun.walk({0x0?, 0x0?, 0xa76c0?}, {0xc0000a9478, 0x0, 0x1}, 0x10?)
        /go/pkg/mod/github.com/uptrace/[email protected]/util.go:25 +0xa9
github.com/uptrace/bun.baseValues({0xaae438, 0xc0000264b0}, {0xc00050c1f0, 0x1, 0x1})
        /go/pkg/mod/github.com/uptrace/[email protected]/model_table_has_many.go:136 +0x1d6
github.com/uptrace/bun.newHasManyModel(0xc000260550)
        /go/pkg/mod/github.com/uptrace/[email protected]/model_table_has_many.go:27 +0x7a
github.com/uptrace/bun.(*relationJoin).manyQuery(0x0?, 0xc0005bf4a0)
        /go/pkg/mod/github.com/uptrace/[email protected]/relation_join.go:57 +0x27
github.com/uptrace/bun.(*relationJoin).selectMany(0xc0005bf2c0?, {0xaab518, 0xc0000a8000}, 0x0?)
        /go/pkg/mod/github.com/uptrace/[email protected]/relation_join.go:49 +0x26
github.com/uptrace/bun.(*SelectQuery).selectJoins(0xc0005bf2c0, {0xaab518, 0xc0000a8000}, {0xc000260500, 0x2, 0xc0005bf2c0?})
        /go/pkg/mod/github.com/uptrace/[email protected]/query_select.go:473 +0x3d5
github.com/uptrace/bun.(*SelectQuery).Scan(0xc0005bf2c0, {0xaab518, 0xc0000a8000}, {0x0?, 0x996800?, 0xaaa201?})
        /go/pkg/mod/github.com/uptrace/[email protected]/query_select.go:888 +0x1db
github.com/uptrace/bun.(*relationJoin).selectMany(0x0?, {0xaab518, 0xc0000a8000}, 0xc000287000?)
        /go/pkg/mod/github.com/uptrace/[email protected]/relation_join.go:53 +0x45
github.com/uptrace/bun.(*SelectQuery).selectJoins(0xc0005bed20, {0xaab518, 0xc0000a8000}, {0xc00028e500, 0x3, 0xc0005bed20?})
        /go/pkg/mod/github.com/uptrace/[email protected]/query_select.go:473 +0x3d5
github.com/uptrace/bun.(*SelectQuery).Scan(0xc0005bed20, {0xaab518, 0xc0000a8000}, {0x0?, 0x1?, 0x0?})
        /go/pkg/mod/github.com/uptrace/[email protected]/query_select.go:888 +0x1db
jobmon/store.(*PostgresStore).GetJob(_, _)
        /app/store/postgres_store.go:291 +0x185
main.main()
        /app/jobmon.go:62 +0x50c

Does anybody have an idea what is causing this behaviour? Is that an bug or is it an mistake on my side?

ys3d avatar Aug 22 '23 15:08 ys3d

Update: Directly fetching an element of type JobData works perfectly fine using both relations

ys3d avatar Aug 24 '23 13:08 ys3d

up I get the same error using such syntax when Data is null

Model(&job).
WherePK().
Relation("Data.Config").
Relation("Data.Points").
Scan(context.Background())

yohimik avatar Jan 04 '24 13:01 yohimik

I'm getting the same error. My model is:

type User struct {
	bun.BaseModel `bun:"table:user,alias:u"`
	ID       int64
    Name     string
    Password string

	SuperUser       *SuperUser              `bun:"su,rel:has-one,join:id=user_id"`
	ClientUser      *ClientUser             `bun:"cu,rel:has-one,join:id=user_id"`
}


type SuperUser struct {
	bun.BaseModel `bun:"table:super_user,alias:su"`
	ID     int64
    Email  string
	UserID int64

	User   *User `bun:"rel:belongs-to,join:user_id=id"`
}


type ClientUser struct {
	bun.BaseModel `bun:"table:client_user,alias:cu"`
	ID     int64
    Email  string
	UserID int64

	User   *User `bun:"rel:belongs-to,join:user_id=id"`
}


type Order struct {
	bun.BaseModel `bun:"table:order,alias:o"`
	ID int64

	OwnerID int64

	Owner   *User `bun:"rel:belongs-to,join:owner_id=id"`
}

And I try the request:

Model(&order).
Relation("Owner").
Scan(context.Background())

It fails when I've values in both user tables (ClientUser and SuperUser)

hsequeda avatar Mar 07 '24 02:03 hsequeda

This issue is duplicating => https://github.com/uptrace/bun/issues/872

hsequeda avatar Mar 07 '24 12:03 hsequeda