-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
fix: merge group conds clause #7198
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -380,14 +380,68 @@ | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| func (db *DB) executeScopes() (tx *DB) { | ||||||||||||||||||||||||||||||||||
| if len(db.Statement.scopes) == 0 { | ||||||||||||||||||||||||||||||||||
| return db | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| scopes := db.Statement.scopes | ||||||||||||||||||||||||||||||||||
| db.Statement.scopes = nil | ||||||||||||||||||||||||||||||||||
| originClause := db.Statement.Clauses | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // use clean db in scope | ||||||||||||||||||||||||||||||||||
| cleanDB := db.Session(&Session{}) | ||||||||||||||||||||||||||||||||||
| cleanDB.Statement.Clauses = map[string]clause.Clause{} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| txs := make([]*DB, 0, len(scopes)) | ||||||||||||||||||||||||||||||||||
| for _, scope := range scopes { | ||||||||||||||||||||||||||||||||||
| db = scope(db) | ||||||||||||||||||||||||||||||||||
| txs = append(txs, scope(cleanDB)) | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| db.Statement.Clauses = originClause | ||||||||||||||||||||||||||||||||||
| db.mergeClauses(txs) | ||||||||||||||||||||||||||||||||||
| return db | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| func (db *DB) mergeClauses(txs []*DB) { | ||||||||||||||||||||||||||||||||||
|
Check failure on line 405 in chainable_api.go
|
||||||||||||||||||||||||||||||||||
| if len(txs) == 0 { | ||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| for _, tx := range txs { | ||||||||||||||||||||||||||||||||||
| stmt := tx.Statement | ||||||||||||||||||||||||||||||||||
| if stmt != nil { | ||||||||||||||||||||||||||||||||||
| stmtClause := stmt.Clauses | ||||||||||||||||||||||||||||||||||
| // merge clauses | ||||||||||||||||||||||||||||||||||
| if cs, ok := stmtClause["WHERE"]; ok { | ||||||||||||||||||||||||||||||||||
| if where, ok := cs.Expression.(clause.Where); ok { | ||||||||||||||||||||||||||||||||||
| db.Statement.AddClause(where) | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // cover other expr | ||||||||||||||||||||||||||||||||||
| if stmt.TableExpr != nil { | ||||||||||||||||||||||||||||||||||
| db.Statement.TableExpr = stmt.TableExpr | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| // If multiple scopes set different table names, only the last non-empty value is retained. | |
| // Later scopes take precedence and overwrite earlier Table assignments. |
Copilot
AI
Oct 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both Selects and Omits are being overwritten rather than merged. If multiple scopes specify different selects or omits, only the last one will apply. This could lead to unexpected behavior where earlier scope configurations are lost. Consider either accumulating these values or documenting that later scopes override earlier ones.
| db.Statement.Selects = stmt.Selects | |
| } | |
| if stmt.Omits != nil { | |
| db.Statement.Omits = stmt.Omits | |
| if db.Statement.Selects == nil { | |
| db.Statement.Selects = []string{} | |
| } | |
| db.Statement.Selects = append(db.Statement.Selects, stmt.Selects...) | |
| } | |
| if stmt.Omits != nil { | |
| if db.Statement.Omits == nil { | |
| db.Statement.Omits = []string{} | |
| } | |
| db.Statement.Omits = append(db.Statement.Omits, stmt.Omits...) |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it work if we make a function
func (db *DB) mergeClause(tx *DB)and then call it in the loop on line 397 to cut down on iterations?db.mergeClause(scope(cleanDB))Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is to avoid the impact of multiple
AddClauseon the db instance, so a clean stmt needs to be cached (Clausesare not affected byAddClause)At the same time we need to keep the order of conditions, such as
.Where(...).Scope(...)