Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UPSERT with RETURNING and WHERE condition returns non modified rows as well while scanning rows #6500

Open
bedakb opened this issue Aug 3, 2023 · 1 comment
Assignees
Labels
type:question general questions

Comments

@bedakb
Copy link

bedakb commented Aug 3, 2023

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

@bedakb bedakb added the type:question general questions label Aug 3, 2023
@jeevanragula
Copy link

jeevanragula commented Jun 14, 2024

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:question general questions
Projects
None yet
Development

No branches or pull requests

3 participants