Your Question
Hello!
Is there a way to get only modified rows back as result of Upsert query together with RETURNING clause and WHERE condition? Consider this example:
type Product struct {
SKU string `gorm:"primaryKey"`
Country string `gorm:"primaryKey"`
Price float64
}
func (s Store) SaveProducts(ctx context.Context, products []Product) ([]Product, error) {
if len(products) == 0 {
return nil, nil
}
db := s.db.WithContext(ctx)
op := db.Clauses(clause.OnConflict{
Columns: []clause.Column{
{Name: "sku"},
{Name: "country"},
},
UpdateAll: true,
Where: clause.Where{
Exprs: []clause.Expression{
gorm.Expr("products.price IS DISTINCT FROM EXCLUDED.price"),
},
},
}, clause.Returning{}).Create(&products)
if op.Error != nil {
return nil, op.Error
}
fmt.Printf("affected rows = %d", op.RowsAffected)
var savedProducts []Product
rows, err := op.Rows()
if err != nil {
return nil, err
}
for rows.Next() {
var p Product
if err := db.ScanRows(rows, &p); err != nil {
return nil, err
}
savedProducts = append(savedProducts, p)
}
return savedProducts, nil
}
If I'd insert one row and then try to insert exactly same row again I'd generally expect returned result to be empty on second insertion, however that is not the case because every time everything is returned regardless of whether row was updated or not.
On the other hand op.RowsAffected logs correct value always (1 and 0 in above mentioned example).
The document you expected this should be explained
Expected answer
Comment From: jeevanragula
@bedakb Yes, Even I got into this bug. Are you able to solve with any workaround for this? Can we change the label of this issue to a bug instead of question?