GORM Playground Link
https://github.com/daashuun/playground
Description
I tried to make
SELECT * FROM "test" WHERE a = 1 AND (b = 2 OR c = 3)
but this request
DB.Table("test").Scopes(
func(d *gorm.DB) *gorm.DB {
return d.Where("a = 1")
},
func(d *gorm.DB) *gorm.DB {
return d.Where(d.Or("b = 2").Or("c = 3"))
},
).Rows()
makes sql
SELECT * FROM "test" WHERE a = 1 OR b = 2 OR c = 3 AND (a = 1 OR b = 2 OR c = 3)
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: black-06
It needs to be repaired and you can use this instead:
db.Table("test").Scopes(
func(d *gorm.DB) *gorm.DB {
return d.Where("a = 1")
},
func(d *gorm.DB) *gorm.DB {
return d.Where(db.Or("b = 2").Or("c = 3")) // it's db
},
).Rows()
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: a631807682
@black-06 This is a bug? Can it be assigned to you?
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: black-06
@black-06 This is a bug? Can it be assigned to you?
I think so, it can be assigned to me.
But it may require many changes to Scopes? Do you have any idea
Comment From: a631807682
But it may require many changes to
Scopes? Do you have any idea
Sorry, I only read your comment and didn't check the question, I'll check and get back to you.
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: a631807682
@black-06 This does not seem to be a scope problem, but a subquery processing problem. which will reuse Exprs to build a clause, even if it has been used externally. https://github.com/go-gorm/gorm/blob/master/statement.go#L331
tx := DB.Where("a = 1").Session(&gorm.Session{})
tx.Where(tx.Or("b = 2").Or("c = 3")).First(&test)
// SELECT * FROM `tests` WHERE a = 1 AND (a = 1 OR b = 2 OR c = 3) AND `tests`.`deleted_at` IS NULL ORDER BY `tests`.`id` LIMIT 1
Comment From: black-06
@black-06 This does not seem to be a scope problem, but a subquery processing problem. which will reuse Exprs to build a clause, even if it has been used externally. https://github.com/go-gorm/gorm/blob/master/statement.go#L331
``go tx := DB.Where("a = 1").Session(&gorm.Session{}) tx.Where(tx.Or("b = 2").Or("c = 3")).First(&test) // SELECT * FROMtestsWHERE a = 1 AND (a = 1 OR b = 2 OR c = 3) ANDtests.deleted_atIS NULL ORDER BYtests.id` LIMIT 1```
use a flag to make sure that expr only be used once?
It's broken for
tx = db.Model(&User{}).Where(xxx)... // common conditions
tx.Where(o1).Find(&u1)
tx.Where(o2).Find(&u2)
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: a631807682
@black-06 This does not seem to be a scope problem, but a subquery processing problem. which will reuse Exprs to build a clause, even if it has been used externally.
master/statement.go#L331go tx := DB.Where("a = 1").Session(&gorm.Session{}) tx.Where(tx.Or("b = 2").Or("c = 3")).First(&test) // SELECT * FROM `tests` WHERE a = 1 AND (a = 1 OR b = 2 OR c = 3) AND `tests`.`deleted_at` IS NULL ORDER BY `tests`.`id` LIMIT 1use a flag to make sure that expr only be used once?
It's broken for
```go tx = db.Model(&User{}).Where(xxx)... // common conditions
tx.Where(o1).Find(&u1) tx.Where(o2).Find(&u2) ```
Can we add such judgments? I didn't test it, it's just a possibility, when the DB instance is the same, the expression should have been added in the subquery.
if v != stmt.DB {
...
}
Comment From: black-06
Umm... It can't work for this issue. @a631807682
DB.Table("test").Scopes(
func(d *gorm.DB) *gorm.DB {
return d.Where("a = 1")
},
func(d *gorm.DB) *gorm.DB {
return d.Where(d.Or("b = 2").Or("c = 3"))
},
).Rows()
Before:
SELECT * FROM `tests` WHERE a = 2 OR b = 2 OR c = 3 AND (a = 2 OR b = 2 OR c = 3)
After:
SELECT * FROM `tests` WHERE a = 2 AND (a = 2 OR b = 2 OR c = 3)
The externally condition gets clean, but internal doesn't.
I think maybe pass a clean database into it and then try to merge the returned results? https://github.com/go-gorm/gorm/blob/cc2d46e5be425300e064a39868cfdb333f24e4ac/callbacks.go#L78-L82
cleanDB = db.Session(&Session{})
for _, scope := range scopes {
result := scope(cleanDB)
db.merge(result)
}
Comment From: a631807682
I think maybe pass a clean database into it and then try to merge the returned results?
This seems to be hard to do as user may pass some values with multiple scope, I have no suggestion. cc @jinzhu