GORM Playground Link
https://github.com/go-gorm/playground/pull/663
Description
When using the OnConflict handler, if you run two Creates on the same *gorm.DB, the second create will reuse some of the state from the first Create.
If the struct in the first create is larger than that in the second, this will cause a panic. If the struct in the second create is larger than the first, this will cause some other error which I have not investigated.
In addition to the GORM playground above, this can be seen in an even more minimal test case:
package example
import (
"testing"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type FieldRich struct {
First string `gorm:"primaryKey"`
Second string
Third string
}
type FieldPoor struct {
NumberOne int64 `gorm:"primaryKey"`
NumberTwo int64
}
func TestExample(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("file::memory:?cache=shared"))
db.AutoMigrate(&FieldRich{})
db.AutoMigrate(&FieldPoor{})
db.Create(&FieldRich{"one", "two", "three"})
db.Create(&FieldPoor{5, 4})
dbUpsert := db.Clauses(clause.OnConflict{UpdateAll: true})
dbUpsert.Create(&FieldRich{"one", "two", "three"})
dbUpsert.Create(&FieldPoor{5, 4})
}
Comment From: shedyfreak
it seems that the missing annotations of gorm on the other fields makes it fail, IMO this is a misuse of the library rather than a bug. it seems that the struct is finaly parsed as array of " fields" and at some level it fails to understand that those fields are not part of the gorm struct. I m not sure if there is any action requiered here.
Comment From: a631807682
https://gorm.io/docs/method_chaining.html#New-Session-Methods