Your Question

I have a couple of Models such as

Tag struct {
  gorm.Model
  Name      string      `gorm:"not null;unique"`
  Resources []*Resource `gorm:"many2many:resource_tags;"`
}


Resource struct {
  gorm.Model
  Name       string `gorm:"not null;default:null"`
  Kind       string `gorm:"not null;default:null"`
  Rating     float64
  CatalogID  uint
  Tags       []*Tag            `gorm:"many2many:resource_tags;constraint:OnDelete:CASCADE;"`
}

The goal is to find the list of resources whose tags are given, since a resource can have many tags we need to find distinct resource id

So with gorm v1.23.4 it works fine and the logic we have is


type Request struct {
    Db         *gorm.DB
    Log        *log.Logger
    ID         uint
    Name       string
    Tags       []string
}

func (r *Request) Query() ([]model.Resource, error) {

    // DISTINCT(resources.id) and resources.id is required as the
    // INNER JOIN of tags and resources returns duplicate records of
    // resources as a resource may have multiple tags, thus we have to
    // find DISTINCT on resource.id

    r.Db = r.Db.Select("DISTINCT(resources.id), resources.*").Scopes(
        filterByTags(r.Tags),
    )

    return r.findAllResources()
}


func (r *Request) findAllResources() ([]model.Resource, error) {

    var rs []model.Resource
    if err := r.Db.Find(&rs).Error; err != nil {
        r.Log.Error(err)
        return nil, FetchError
    }

    if len(rs) == 0 {
        return nil, NotFoundError
    }

    return rs, nil
}

func filterByTags(tags []string) func(db *gorm.DB) *gorm.DB {
    if tags == nil {
        return noop
    }

    tags = lower(tags)
    return func(db *gorm.DB) *gorm.DB {
        return db.Model(&model.Resource{}).
            Joins("JOIN resource_tags as rt on rt.resource_id = resources.id").
            Joins("JOIN tags on tags.id = rt.tag_id").
            Where("lower(tags.name) in (?)", tags)
    }
}

But while bumping to gorm v1.23.5

It's giving the following error

sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer

Is there something I'm missing in the latest release for which I need to make the change ? Thanks in advance 🙂

The document you expected this should be explained

Expected answer

Comment From: zetaab

we are seeing similar behaviour as well. Currently we downgraded back to 1.23.4 from 1.23.5. 1.23.5 is breaking few database calls with similar error.

one example call is

        if err := db.
            Select("DISTINCT(clusters.id)", "clusters.*").
            Order("clusters.id").
            Joins("LEFT JOIN namespace_admins na ON clusters.id = na.cluster_id").
            Where("(clusters.owner in (?) OR na.maintainer in (?))", groups, groups).
            Preload("AdditionalAlerts").
            Find(&clusters).Error; err != nil {
            return nil, err
2022/05/23 11:19:09 /Users/.../cluster.go:234 sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer; sql: Scan error on column index 1, name "id": destination not a pointer
[47.378ms] [rows:18] SELECT DISTINCT(clusters.id),clusters.* FROM "clusters" LEFT JOIN namespace_admins na ON clusters.id = na.cluster_id WHERE ((clusters.owner in ('FOO','BAR') OR na.maintainer in ('FOO','BAR'))) AND "clusters"."deleted_at" IS NULL ORDER BY clusters.id

Comment From: zetaab

for me it looks like breaking commit is https://github.com/go-gorm/gorm/commit/81c4024232c35c3d49907f3ae77c2857a1dd7f63 that is first commit that does not work like should.

ping @Joker666 @jinzhu

Comment From: zetaab

@Joker666 it looks like if we have Select("DISTINCT(clusters.id)", "clusters.*"). or similar, we have bug after commit 81c4024.

Comment From: Joker666

Can you guys add a playground link?

Comment From: zetaab

@PuneetPunamiya can you test does this solve issues for you

add go.mod replace gorm.io/gorm => github.com/zetaab/gorm v1.23.5-f

it contains commit https://github.com/zetaab/gorm/commit/86f10fbb6283239263eca5421050a0f6d10d79f2 + normal gorm 1.23.5. At least for me it fixes all issues.

Comment From: zetaab

@Joker666 I tried to make minimal code without success

Comment From: PuneetPunamiya

@zetaab Thanks for the fix, I tried with your patch and it works fine with it 🙂

Comment From: PuneetPunamiya

I think we should have a minor release for this as this can be a common bug